Giter Site home page Giter Site logo

babel-plugin-react-transform's Introduction

This Project Is Deprecated

React Hot Loader 3 is on the horizon, and you can try it today (boilerplate branch, upgrade example). It fixes some long-standing issues with both React Hot Loader and React Transform, and is intended as a replacement for both. The docs are not there yet, but they will be added before the final release. For now, this commit is a good reference.

babel-plugin-react-transform

react-transform channel on discord

🚀 Now with Babel 6 support (thank you @thejameskyle!)

This plugin wraps React components with arbitrary transforms. In other words, it allows you to instrument React components in any way—limited only by your imagination.

🚧🚧🚧🚧🚧

This is highly experimental tech. If you’re enthusiastic about hot reloading, by all means, give it a try, but don’t bet your project on it. Either of the technologies it relies upon may change drastically or get deprecated any day. You’ve been warned 😉 .

This technology exists to prototype next-generation React developer experience. Please don’t use it blindly if you don’t know the underlying technologies well. Otherwise you are likely to get disillusioned with JavaScript tooling.

No effort went into making this user-friendly yet. The goal is to eventually kill this technology in favor of less hacky technologies baked into React. These projects are not long term.

Table of Contents

Ecosystem

For a reference implementation, see react-transform-boilerplate.
For a starter kit to help write your own transforms, see react-transform-noop.

Transforms

Feeling inspired? Learn how to write transforms and send a PR!

Demo Project

Check out react-transform-boilerplate for a demo showing a combination of transforms.

Installation

This plugin is designed to be used with the Babel 6 ecosystem. These instructions assume you have a working project set up. If you do not have Babel set up in your project, learn how to integrate it with your toolkit before installing this plugin.

Using NPM

Install plugin and save in devDependencies:

npm install --save-dev babel-plugin-react-transform

Install some transforms:

npm install --save-dev react-transform-hmr
npm install --save-dev react-transform-catch-errors
Configuration

Add react-transform to the list of plugins in your babel configuration (usually .babelrc):

{
  "presets": ["react", "es2015"],
  "env": {
    // this plugin will be included only in development mode, e.g.
    // if NODE_ENV (or BABEL_ENV) environment variable is not set
    // or is equal to "development"
    "development": {
      "plugins": [
        // must be an array with options object as second item
        ["react-transform", {
          // must be an array of objects
          "transforms": [{
            // can be an NPM module name or a local path
            "transform": "react-transform-hmr",
            // see transform docs for "imports" and "locals" dependencies
            "imports": ["react"],
            "locals": ["module"]
          }, {
            // you can have many transforms, not just one
            "transform": "react-transform-catch-errors",
            "imports": ["react", "redbox-react"]
          }, {
            // can be an NPM module name or a local path
            "transform": "./src/my-custom-transform"
          }]
          // by default we only look for `React.createClass` (and ES6 classes)
          // but you can tell the plugin to look for different component factories:
          // factoryMethods: ["React.createClass", "createClass"]
        }]
      ]
    }
  }
}

As you can see, each transform, apart from the transform field where you write it name, also has imports and locals fields. You should consult the docs of each individual transform to learn which imports and locals it might need, and how it uses them. You probably already guessed that this is just a way to inject local variables (like module) or dependencies (like react) into the transforms that need them.

Note that when using React.createClass() and allowing babel to extract the displayName property you must ensure that babel-plugin-react-display-name is included before react-transform. See this github issue for more details.

You may optionally specify an array of strings called factoryMethods if you want the plugin to look for components created with a factory method other than React.createClass. Note that you don’t have to do anything special to look for ES6 components—factoryMethods is only relevant if you use factory methods akin to React.createClass.

Writing Transforms

It’s not hard to write a custom transform! First, make sure you call your NPM package react-transform-* so we have uniform naming across the transforms. The only thing you should export from your transform module is a function.

export default function myTransform() {
  // ¯\_(ツ)_/¯
}

This function should return another function:

export default function myTransform() {
  return function wrap(ReactClass) {
    // ¯\_(ツ)_/¯
    return ReactClass;
  }
}

As you can see, you’ll receive ReactClass as a parameter. It’s up to you to do something with it: monkeypatch its methods, create another component with the same prototype and a few different methods, wrap it into a higher-order component, etc. Be creative!

export default function logAllUpdates() {
  return function wrap(ReactClass) {
    const displayName = // ¯\_(ツ)_/¯
    const originalComponentDidUpdate = ReactClass.prototype.componentDidUpdate;

    ReactClass.prototype.componentDidUpdate = function componentDidUpdate() {
      console.info(`${displayName} updated:`, this.props, this.state);

      if (originalComponentDidUpdate) {
        originalComponentDidUpdate.apply(this, arguments);
      }
    }

    return ReactClass;
  }
}

Oh, how do I get displayName? Actually, we give your transformation function a single argument called options. Yes, options:

export default function logAllUpdates(options) {

It contains some useful data. For example, your options could look like this:

{
  // the file being processed
  filename: '/Users/dan/p/my-projects/src/App.js',
  // remember that "imports" .babelrc option?
  imports: [React],
  // remember that "locals" .babelrc option?
  locals: [module],
  // all components declared in the current file
  components: {
    $_MyComponent: {
      // with their displayName when available
      displayName: 'MyComponent'
    },
    $_SomeOtherComponent: {
      displayName: 'SomeOtherComponent',
      // and telling whether they are defined inside a function
      isInFunction: true
    }
  }
}

Of course, you might not want to use all options, but isn’t it nice to know that you have access to them in the top scope—which means before the component definitions actually run? (Hint: a hot reloading plugin might use this to decide whether a module is worthy of reloading, even if it contains an error and no React components have yet been wrapped because of it.)

So, to retrieve the displayName (or isInFunction, when available), use the options parameter and the second uniqueId parameter given to the inner function after ReactClass:

export default function logAllUpdates(options) {
  return function wrap(ReactClass, uniqueId) {
    const displayName = options.components[uniqueId].displayName || '<Unknown>';

This is it!

Sure, it’s a slightly contrived example, as you can grab ReactClass.displayName just fine, but it illustrates a point: you have information about all of the components inside a file before that file executes, which is very handy for some transformations.

Here is the complete code for this example transformation function:

export default function logAllUpdates(options) {
  return function wrap(ReactClass, uniqueId) {
    const displayName = options.components[uniqueId].displayName || '<Unknown>';
    const originalComponentDidUpdate = ReactClass.prototype.componentDidUpdate;

    ReactClass.prototype.componentDidUpdate = function componentDidUpdate() {
      console.info(`${displayName} updated:`, this.props, this.state);

      if (originalComponentDidUpdate) {
        originalComponentDidUpdate.apply(this, arguments);
      }
    }

    return ReactClass;
  }
}

Now go ahead and write your own! Don’t forget to tag it with react-transform keyword on npm.

Patrons

The work on React Transform, React Hot Loader, Redux, and related projects was funded by the community. Meet some of the outstanding companies that made it possible:

See the full list of React Transform patrons.

License

MIT

babel-plugin-react-transform's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

babel-plugin-react-transform's Issues

Support pure components

We should extend the transform to find and wrap pure components.
I think a good enough heuristic for us is to catch functions that contain JSX.

We should also support them in react-proxy: gaearon/react-proxy#12

Does react-transform support updating the target file dynamically as well?

I have tried the react-transform-boilerplate, it is really awesome. Is there any way I could see the changes the target folder as well when I make a change.
Currently, when I make any change it bundles it and directly updates in the server. Instead, I want to see the changes in the file (static/bundle.js) directly using (Finder and text editor).

This case, I can commit or take a reference of the bundle.js for the further use.

Thanks in advance.

Display name cannot be resolved in all cases

I have the following component:

define(['react',
        'snappy',
        'drool/viewport/templates/viewport',
        'navigation',
        'viewfactory'
    ],
    function(React, Snappy, Viewport, Navigation, viewfactory) {

        return React.createClass(viewfactory.create({

            displayName: 'App',

            propTypes: {
                activeMenu: React.PropTypes.array,
                subNav: React.PropTypes.array
            },

            mixins: [Snappy.Routing.Navigation],

            render: function () {
                var navigation = <Navigation path={this.getPath()}
                                             centerItem={this.props.activeMenu ? this.props.activeMenu[0] : undefined}
                                             subNav={this.props.subNav ? this.props.subNav[0] : undefined} />;

                return (
                    <Viewport navigation={navigation}>
                        {this.props.children}
                    </Viewport>
                );

            }
        }));

    });

and when transforming I receive the following error:

ERROR in ../frontend/src/js/views/app.jsx
Module build failed: TypeError: e:/Code/PronetSquared/frontend/src/js/views/app.jsx: Cannot read property 'find' of undefined
    at find (e:\Code\PronetSquared\frontend\node_modules\array-find\find.js:5:17)
    at getDisplayName (e:\Code\PronetSquared\frontend\node_modules\babel-plugin-react-transform\lib\index.js:33:41)
    at Object.CallExpression (e:\Code\PronetSquared\frontend\node_modules\babel-plugin-react-transform\lib\index.js:110:22)
    at NodePath._call (e:\Code\PronetSquared\frontend\node_modules\babel-traverse\lib\path\context.js:74:18)
    at NodePath.call (e:\Code\PronetSquared\frontend\node_modules\babel-traverse\lib\path\context.js:46:17)
    at NodePath.visit (e:\Code\PronetSquared\frontend\node_modules\babel-traverse\lib\path\context.js:104:12)
    at TraversalContext.visitQueue (e:\Code\PronetSquared\frontend\node_modules\babel-traverse\lib\context.js:153:16)
    at TraversalContext.visitSingle (e:\Code\PronetSquared\frontend\node_modules\babel-traverse\lib\context.js:113:19)
    at TraversalContext.visit (e:\Code\PronetSquared\frontend\node_modules\babel-traverse\lib\context.js:197:19)
    at Function.traverse.node (e:\Code\PronetSquared\frontend\node_modules\babel-traverse\lib\index.js:139:17)
 @ ../frontend/src/js/router.jsx 51:0-98:2

This results in an error in the getDisplayName method on the first line (when looking for the actual property)

  function getDisplayName(node) {
    var property = (0, _arrayFind2.default)(node.arguments[0].properties, function (node) {
        return node.key.name === 'displayName';
    });
    return property && property.value.value;
  }

Is this related to the viewfactory wrapper we have in place?

`displayName` is not populated during transformation of `React.createClass`

Before react-transform

babel.transform('var Component = React.createClass({fun: "yay"});');

generates

"use strict";

var Component = React.createClass({
  displayName: "Component",
  fun: "yay" });

(which includes the populated displayName).

After react-transform

babel.transform('var Component = React.createClass({fun: "yay"});', {
    plugins: ['react-transform'],
    extra: {
        'react-transform': []
    }
});

generates

"use strict";

var _components = {
  _$Unknown: {}
};

function _wrapComponent(uniqueId) {
  return function (ReactClass) {
    return ReactClass;
  };
}

var Component = _wrapComponent("_$Unknown")(React.createClass({ fun: "yay" }));

(which does not have a displayName).

Using this latter code, dev tools can't get a name for Component.

Is this expected? Am I missing something? Thanks!

Versions

iframes and custom webpack loaders

For the past few days I've been struggling to integrate babel-plugin-react-transform with a project that lives in an iframe. I have forked react-transform-boilerplate and made the minimum number of changes necessary to reproduce the problem I am experiencing.

Two things about this project that might be causing the problem

  1. This project must live inside an iframe,
  2. Because of the iframe we need to use a custom webpack loader entry-loader

The problem: Now when I make a change to a React component I see the following in dev-tools and no hot-loading happens.

[HMR] connected
client.js?3ac5:106 [HMR] bundle rebuilding
client.js?3ac5:108 [HMR] bundle rebuilt in 304ms

static class property displayName not taken into account for displayName

While upgrading to react-transform I noticed in case displayName is defined as a class property the name is not taken into account e.g.

class CustomDisplayNameComponent {
  static displayName = 'Custom Name';
  render() {}
}

Here out in the wild: https://github.com/nikgraf/belle/blob/75aa7dad0a2ba03ad755a97efe3193bdcf76b3a3/src/components/Card.jsx#L27
For Belle we will migrate the display names, but others might run into the same issue.

I investigated and learned that findDisplayName takes the name in case it's a class node and has an ID or leverages the arguments from createClass. I couldn't figure out how to get the properties from a class node. Any hint? I'm happy to submit a PR.

Support higher order components

Right now we wrap every component, even if it is generated dynamically.

While this is fine by itself, we should add a parameter to the transformation function API to notify it whether the component is declared in top-level scope, or not. For example, hot reloading transformation wouldn't considered displayName a unique identifier if we're inside a function, and opt out.

Make React component search configurable

As requested in #3 and #6, let's make component search more flexible and configurable.
I imagine us changing the react-transform config to be an object, with transforms being an array.

.babelrc might look like this:

{
  "stage": 0,
  "plugins": [
    "react-transform"
  ],
  "extra": {
    "react-transform": {
      "transforms": [{
        "transform": "react-transform-webpack-hmr",
        "imports": ["react"],
        "locals": ["module"]
      }, {
        "transform": "react-transform-catch-errors",
        "imports": ["react", "redbox-react"]
      }, {
        "transform": "./src/my-custom-transform"
      }]
    }
  }
}

(Note I renamed target to transform, I think it makes more sense but feel free to disagree.)

This gives us space to add more configuration options. I'd like to add factoryMethods to address #3 and baseClasses to address #6. If you omit them, we will use the defaults:

"react-transform": {
  "baseClasses": ["React.Component", "Component"], // defaults
  "factoryMethods": ["React.createClass", "createClass"], // defaults
  "transforms": [...]
}

However you're free to specify different ones:

"baseClasses": [] // inspect every class with render() instead
"baseClasses": ['React.Component', 'MyCustomBaseComponent'] // inspect specific base classes
"factoryMethods": ["myComponentFactory", "React.createClass"] // inspect specific factory methods

etc.

I currently don't have time to do this, but I'm happy to accept a pull request.

[babel 6] SyntaxError: Unexpected token: async () => {

Hello

I am testing the new babel 6 support with "babel-plugin-react-transform": "^2.0.0-beta1" but get a syntax error, see below.

Is this a babel 6 issue or related to this plugin?

> babel-node --eval "require('./scripts/externalsUpdate')().catch(err => console.error(err.stack))"

/usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/file/index.js:547
      throw err;
      ^

SyntaxError: /Users/bernd/WebstormProjects/react-webpack/scripts/externalsUpdate.js: Unexpected token (20:49)
  18 | 
  19 | // Save JSON of full schema introspection for Babel Relay Plugin to use
> 20 | export default task('update externals', async () => {
     |                                                  ^
  21 | 
  22 |   // react
  23 |   console.log('copying react v' + react.version);
    at Parser.pp.raise (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/parser/location.js:22:13)
    at Parser.pp.unexpected (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/parser/util.js:91:8)
    at Parser.pp.parseAsyncArrowFromCallExpression (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/parser/expression.js:357:47)
    at Parser.<anonymous> (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/plugins/flow.js:972:20)
    at Parser.parseAsyncArrowFromCallExpression (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/plugins/flow.js:972:20)
    at Parser.pp.parseSubscripts (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/parser/expression.js:308:21)
    at Parser.pp.parseExprSubscripts (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/parser/expression.js:275:15)
    at Parser.pp.parseMaybeUnary (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/parser/expression.js:245:19)
    at Parser.pp.parseExprOps (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/parser/expression.js:176:19)
    at Parser.pp.parseMaybeConditional (/usr/local/lib/node_modules/babel-cli/node_modules/babylon/lib/parser/expression.js:158:19)

This is my .babelrc

{
  "presets": ["react", "es2015"],
  "env": {
    "development": {
      "plugins": [
        [
          "babel-relay-plugin-loader",
          "react-transform", {
            "transforms": [{
              "transform": "react-transform-hmr",
              "imports": ["react"],
              "locals": ["module"]
            }, {
              "transform": "react-transform-catch-errors",
              "imports": ["react", "redbox-react"]
            }]
        }]
      ]
    },
    "production": {
      "plugins": [
        [
          "babel-relay-plugin-loader"
        ]
      ]
    }
  }
}

And these are my dependencies - all up to the latest within their semver rule:

"dependencies": {
  "bootstrap": "^3.0.0",
  "history": "^1.0.0",
  "lodash": "^3.0.0",
  "mysql": "^2.0.0",
  "react": "^0.14.0",
  "react-bootstrap": "^0.28.0",
  "react-dom": "^0.14.0",
  "react-relay": "^0.6.0",
  "react-router": "^1.0.0",
  "react-router-relay": "^0.8.0",
  "sequelize": "^3.0.0"
},
"devDependencies": {
  "autoprefixer": "^6.0.0",
  "babel-core": "^6.0.0",
  "babel-eslint": "^5.0.0-beta4",
  "babel-loader": "^6.0.0",
  "babel-plugin-react-transform": "^2.0.0-beta1",
  "babel-preset-es2015": "^6.0.0",
  "babel-preset-react": "^6.0.0",
  "babel-relay-plugin": "^0.6.0",
  "babel-relay-plugin-loader": "^0.6.0",
  "browser-sync": "^2.0.0",
  "browser-sync-webpack-plugin": "^1.0.0",
  "clean-webpack-plugin": "^0.1.0",
  "copy-webpack-plugin": "^0.3.0",
  "cors": "^2.0.0",
  "css-loader": "^0.23.0",
  "express": "^4.0.0",
  "express-graphql": "^0.4.0",
  "extract-text-webpack-plugin": "^0.9.0",
  "faker": "^3.0.0",
  "file-loader": "^0.8.0",
  "graphiql": "^0.4.0",
  "graphql": "^0.4.0",
  "graphql-relay": "^0.3.0",
  "history": "^1.0.0",
  "html-webpack-plugin": "^1.0.0",
  "isparta-instrumenter-loader": "^1.0.0",
  "jasmine-core": "^2.0.0",
  "karma": "^0.13.0",
  "karma-chrome-launcher": "^0.2.0",
  "karma-coverage": "^0.5.0",
  "karma-jasmine": "^0.3.0",
  "karma-phantomjs-launcher": "^0.2.0",
  "karma-sourcemap-loader": "^0.3.0",
  "karma-spec-reporter": "^0.0.23",
  "karma-webpack": "^1.0.0",
  "less": "^2.0.0",
  "less-loader": "^2.0.0",
  "node-libs-browser": "^0.5.0",
  "null-loader": "^0.1.0",
  "phantomjs": "^1.0.0",
  "postcss-loader": "^0.8.0",
  "q": "^1.0.0",
  "raw-loader": "^0.5.0",
  "react-transform-catch-errors": "^1.0.0",
  "react-transform-hmr": "^1.0.0",
  "redbox-react": "^1.0.0",
  "relay-local-schema": "^0.3.0",
  "style-loader": "^0.13.0",
  "webpack": "^1.0.0",
  "webpack-dev-server": "^1.0.0"
}

TypeError: Plugin is not a function

Any idea how to resolve or what's causing this?

ERROR in ./js/index.js
Module build failed: TypeError: Plugin is not a function
    at exports.default (/Users/phaistonian/www/Test/node_modules/babel-plugin-react-transform/lib/index.js:258:10)

Unknown option: base.extra with Babel 6

error with babel-loader
how to use babel-plugin-react-transform ??

ERROR in ./src/templates/azul/app.js
Module build failed: ReferenceError: [BABEL] /Users/carlos/www/mall4g-templates/src/templates/azul/app.js: Unknown option: base.extra
    at Logger.error (/Users/carlos/www/mall4g-templates/node_modules/babel-core/lib/transformation/file/logger.js:41:11)
    at OptionManager.mergeOptions (/Users/carlos/www/mall4g-templates/node_modules/babel-core/lib/transformation/file/options/option-manager.js:262:18)
    at OptionManager.init (/Users/carlos/www/mall4g-templates/node_modules/babel-core/lib/transformation/file/options/option-manager.js:416:10)
    at File.initOptions (/Users/carlos/www/mall4g-templates/node_modules/babel-core/lib/transformation/file/index.js:190:75)
    at new File (/Users/carlos/www/mall4g-templates/node_modules/babel-core/lib/transformation/file/index.js:121:22)
    at Pipeline.transform (/Users/carlos/www/mall4g-templates/node_modules/babel-core/lib/transformation/pipeline.js:42:16)
    at transpile (/Users/carlos/www/mall4g-templates/node_modules/babel-loader/index.js:14:22)
    at Object.module.exports (/Users/carlos/www/mall4g-templates/node_modules/babel-loader/index.js:87:14)

Does not seem to work consistently w/ source maps enabled in webpack

Using devtool: 'eval-source-map' or devtool: 'cheap-module-eval-source-map' causes either babel-plugin-react-transform or react-transform-hmr to not work consistently. I don't have a small repro yet, but on my project if I use devtool: 'eval' then all components are hot reloadable. If I use any source-map enabled devtool, it only appears to make the first component it sees hot reloadable.

I'll keep digging and add more information as I find it.

array-find issue

Since [email protected], they will not include polyfills, but other shims like collections will be used in process scope ( babel-polyfill will overwrite them before )

montagejs/collections#139

It will broken matchesPatterns, because of

!!-1 // return true

Just notice it, if someone use webpack with other packages, the global shim will make babel-plugin-react-transform broken

Transform interferes with Istanbul code coverage

When a class has isComponentishClass pass on it, it is transformed, and that transform has a branch in it:

var Some_React_Class = (function (_React$Component) {
  _inherits(Some_React_Class, _React$Component);

  function Some_React_Class() {
    _classCallCheck(this, _Some_React_Class);

    _get(Object.getPrototypeOf(_Some_React_Class.prototype), "constructor", this).apply(this, arguments);
  }

  _createClass(Some_React_Class, [{
    key: "render",
    value: function render() {
      return _react2["default"].createElement(
        "div"
      );
    }
  }]);

  var _Some_React_Class = Some_React_Class;

//This is the branch:
  Some_React_Class = _wrapComponent("_$Some_React_Class")(Some_React_Class) || Some_React_Class;
  return Some_React_Class;
})(_react2["default"].Component);

exports["default"] = (0, _reactRedux.connect)(select)(Some_React_Class);

I've done a diff between a class which has a render function and one that doesn't - the difference seems to be the || Some_React_Class 5 lines from the end there.

I'm not sure how to trigger the other side of that OR, or to ignore it, so this stops me from getting 100% test coverage and makes me sad.

static willTransitionTo is lost

i'm not sure if this is the fault of babel-plugin-react-transform. After integrating react-transform-boilerplate into our setup, static willTransitionTo is gone on components. i guess it gets lost in the process of wrapping the component with a HOC?

Add configuration for which transforms to run in production

Right now, transforms have to include special code to opt out of production effect. Even if they are no-ops, the code to call them is still generated, and any imports are still imported.

I think we should change this behavior:

  • All transforms should be turned off by default in production
  • Transform configuration may have an opt-in production: true which enables it in production
  • If there are no transforms enabled in production, we don't generate the component records and related code, as there is nothing to consume it

Use without .babelrc

I'm creating a set of reusable react components, and having a .babelrc file is problematic, so I would like to avoid having one if possible. I cannot figure out how to translate the option objects for transforms into a cli-friendly format. Can this be used without a .babelrc, and if so, how?

Release version number / react-transform-boilerplate update

@thejameskyle @gaearon what are you guys thinking for release version—1.2.0 or 2.0.0?

we should probably get gaearon/react-transform-boilerplate#64 merged with this release, since it's mentioned throughout this repo and is the reference implementation using babel 6—docs are updated and everything should be good to go.

james, if you have a sec can you review and/or (maybe dan) can merge later? i just have to rebase with new version of babel-plugin-react-transform, so let me know what i should use 😄

Supporting ES module imports

@gaearon thanks for offering to help before. From the previous issues I think the interop issue @timbur is having is that the component module is of the form { default: component } for ES modules when they are added to the imports by the transformer instead of the direct component.

Babel has an exception where a module with a single default export gets treated as the entire module, but I don't think we can't assume this exception for real ES module environments.

A check before handling the component of something like component instanceof React.component ? component || component.default || component may be a way to support ES module react components here. I know the instanceof doesn't quite cover it though so let me know if you have any ideas here?

Let me know your thoughts and if that is clear.

[React Transform HMR] Patching _$Unknown when using ES6 classes with default export

When using export default class extends React.Component syntax, [React Transform HMR] Patching _$Unknown in being displayed in the console instead of the component name.

2015-10-20 at 00 43

vs

2015-10-20 at 00 43

The second one is defined like export default class ImageUploadDropzone extends React.Component

Also I see a lot of _default when getting propTypes warnings. Not sure if this is related to the other issue.

2015-10-20 at 00 43

I'm using React 0.14 and [email protected]

Support Functional Components

Moving from #34.

As of [email protected], plain functions can be used as components. In the future this will bring performance optimizations in React.

function Component(props) {
  return <div/>;
}

Many people are already using these, there's even a Babel plugin (that I wrote) to transform pure component classes to pure component functions.

It would be great if babel-plugin-react-transform supported these. However, there is a pretty big concern.

Since these are just plain functions, with JSX in them there is nothing that designates that it is a react component. i.e. in order to tell that a class is a react component, we can test that it extends React.Component, or that it has a matching interface.

We can attempt to match them by treating "any function that has JSX in it will be treated as a component" i.e.:

function Component() {
  return <div/>;
}

However, this would also match the inner function in here:

class Component extends React.Component {
  render() {
    const children = this.props.items.map(function(props) {
      return <li>{props.name}</li>;
    });
    return <ul>{children}</ul>;
  }
}

So we can tighten things and say "only top level components", but then we run into wanting to support factories:

function componentFactory() {
  return function Component(props) {
    return <div/>;
  };
}

I could keep going for a while, you can put functions all over the place in JavaScript and no matter what we define as the rule here there will be exceptions. It's a matter of deciding what the heuristics should be that balances:

  1. Rarity - How often people will actually run into exceptions in real world code
  2. Obviousness - How easy it is to understand the reasoning behind an exception

It might be possible to get around the obviousness problem by throwing compile errors when running into ambiguous scenarios.

React Router RoutingContext null

I'm getting an empty node when using this in regards to React Router. The Initial react render is happening, but the RoutingContext component is empty. Any ideas?

DisplayName is not generated when running in through webpack-karma

I am able to get the tranform-react-display-name plugin running when running webpack in my normal environment with this configuration.

module: {
    loaders: [
      { test: /(\.jsx|\.js)$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          env: {
            development: {
              plugins: [
                ["transform-react-display-name"],
              ],
            },
          },
        },
      },
    ]
  }

However, with a nearly identical configuration in my karma.conf with webpack-karma, it does not transform the displayName. I need this functionality to unit test some of my components.

module: {
        loaders: [
          {
            test: /(\.jsx|\.js)$/,
            exclude: /node_modules/,
            loader: 'babel',
            query: {
              env: {
                development: {
                  plugins: [
                    ["transform-react-display-name"],
                    ["babel-plugin-rewire"]
                  ]
                }
              }
            },
          },
        ],
      },

I was able to trace it down to this call in the isCreateClass function.

if (!isCreateClassCallExpression(node.callee)) return false;

[Relay] Support for Relay GraphQL needed.

Hello

It would be great if the hot-middleware could update a component when its Relay GraphQL Query changes. At the moment it is not aware of it and forces the developer to manually do a full page reload which destroys his current application state.

In this example

import React from 'react';
import Relay from 'react-relay';

/**
 * The Home component.
 */
class Home extends React.Component {
  // Expected properties.
  static propTypes = {
    viewer: React.PropTypes.object.isRequired
  };
  // Initialize the component.
  constructor(props) {
    super(props);
  }
  // Render the component.
  render() {
    // Return the component UI.
    return (
      <div>
        <h1>Widget list</h1>
        <ul>
          {this.props.viewer.widgets.edges.map(edge =>
              <li key={edge.node.id}>{edge.node.name} (ID: {edge.node.id})</li>
          )}
        </ul>
      </div>
    );
  }
}

/**
 * The home data container.
 */
export default Relay.createContainer(Home, {
  fragments: {
    viewer: () => Relay.QL`
      fragment on User {
        widgets(first: 5) {
          edges {
            node {
              id,
              name,
            },
          },
        },
      }
    `
  }
});

We should be able to make a change to the Query and the hot-middleware should update the component.

Hope it will be easy for you to add this feature - it would improve React development hugely.

Thank you

release 2.0.0

I use babel-plugin-react-transform everyday and had no issue since beta1 was released. So just curious when 2.0.0 will be released. I believe master is stable enough. Or is there are any blockers?

support component factory methods

Many of our legacy components are created with componentFactory({...}) instead of React.createClass. Ideally it'd support any factory function name.

Entire application is reloading with message "Navigated to..."

When I make any change to a React component in my project, I see the following in Chrome's dev-tools console and then my entire application reloads.

How do I stop the entire application from reloading? I'm guessing it has something to do with the final statement "Navigated to http://localhost:9000/frame.html" but I have no idea why this is happening.

[WDS] App updated. Recompiling...
[WDS] App updated. Reloading...
Navigated to http://localhost:9000/frame.html

Edit: I forgot to mention that my application lives inside an iframe and in order to get React dev-tools to work I had to do something like the following: https://gist.github.com/jaredly/593c9b22c619aaf0e0cf. Perhaps this information is relevant?

Look for render method on prototype?

I am writing my code in livescript and chaining the output into babel-loader (evil, I know)

I am essentially transpiling es5 javascript code for the sole benefit of using this plugin.

Anyhow, livescript has its own syntactic sugar for classes:

export class Hello extends React.Component
  (@props) -> super ...
  render: ->
    div null,
      h1 null, 'Hello World!'

That compiles (pre-babel) into:

var Hello, out$ = typeof exports != 'undefined' && exports || this;
out$.Hello = Hello = (function(superclass){
  var prototype = extend$((import$(Hello, superclass).displayName = 'Hello', Hello), superclass).prototype, constructor = Hello;
  function Hello(props){
    this.props = props;
    Hello.superclass.apply(this, arguments);
  }
  prototype.render = function(){
    return div(null, h1(null, 'Hello World!'));
  };
  return Hello;
}(React.Component));
function extend$(sub, sup){
  function fun(){} fun.prototype = (sub.superclass = sup).prototype;
  (sub.prototype = new fun).constructor = sub;
  if (typeof sup.extended == 'function') sup.extended(sub);
  return sub;
}
function import$(obj, src){
  var own = {}.hasOwnProperty;
  for (var key in src) if (own.call(src, key)) obj[key] = src[key];
  return obj;
}

Now, all of the Above runs just fine, however react-tranform does not recognize the resulting node tree.

So, my question is, would it be possible to modify the filter in react-transform to identify the above example of livescript generated code?

And, yes if I use this syntax, everything works great:

export Hello = React.create-class {
  display-name: \Hello
  render: ->
    div null,
      h1 null, 'Hello World!'
}

But I really want my cake, and to eat it too. 🍰

Any suggestions would be appreciated.

Loses displayName when using React.createClass

In the following code

var App = React.createClass({
  render: function() {
    return <div />;
  }
});

Babel (via https://github.com/babel/babel/tree/development/packages/babel-plugin-react-display-name) adds the displayName property based on the variable name.

However, this react-transform plugin doesn't seem to find these display names. Perhaps this is something to do with the ordering of the plugins?

I notice you have a test-case which confirms this behaviour - https://github.com/gaearon/babel-plugin-react-transform/blob/master/test/fixtures/classic/expected.js#L146 - was this intentional or just something that isn't yet supported?

Module build failed: TypeError: template is not a function

Hi,

I had started a simple project using webpack and I'm getting the error below:

ERROR in ./app/index.jsx
Module build failed: TypeError: template is not a function
    at exports.default (/Users/jancassio/Works/labs/webpack/kanban-app/node_modules/babel-plugin-react-transform/lib/index.js:60:33)
    at Function.memoisePluginContainer (/Users/jancassio/Works/labs/webpack/kanban-app/node_modules/babel-core/lib/transformation/file/plugin-manager.js:77:23)
    at PluginManager.add (/Users/jancassio/Works/labs/webpack/kanban-app/node_modules/babel-core/lib/transformation/file/plugin-manager.js:209:30)
    at File.buildTransformers (/Users/jancassio/Works/labs/webpack/kanban-app/node_modules/babel-core/lib/transformation/file/index.js:237:21)
    at new File (/Users/jancassio/Works/labs/webpack/kanban-app/node_modules/babel-core/lib/transformation/file/index.js:139:10)
    at Pipeline.transform (/Users/jancassio/Works/labs/webpack/kanban-app/node_modules/babel-core/lib/transformation/pipeline.js:164:16)
    at transpile (/Users/jancassio/Works/labs/webpack/kanban-app/node_modules/babel-loader/index.js:12:22)
    at Object.module.exports (/Users/jancassio/Works/labs/webpack/kanban-app/node_modules/babel-loader/index.js:71:12)
 @ multi main

I don't have any clue about how to fix this issue, I tried to remove entire node_modules and install all modules again but still the same.

If necessary, I can share some source.
Any ideas about how to fix are welcome.

Thanks.

Babel 6

Babel 6 was just released and has a new plugin API. Assuming this plugin will need to be updated to support it (otherwise can just close this issue).

import.some is not a function exception

I did an update this morning and now get the following exception.

    ERROR in ./docs/containers/App.js
    Module build failed: TypeError: /Users/loy/Projects/omakase/ui-kit/docs/containers/App.js: imports.some is not a function
        at defineInitTransformCall (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-plugin-react-transform/lib/index.js:237:17)
        at /Users/loy/Projects/omakase/ui-kit/node_modules/babel-plugin-react-transform/lib/index.js:328:20
        at Array.map (native)
        at NodePath.exit (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-plugin-react-transform/lib/index.js:327:50)
        at NodePath.call (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/traversal/path/context.js:56:28)
        at NodePath.visit (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/traversal/path/context.js:108:12)
        at TraversalContext.visitSingle (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/traversal/context.js:132:12)
        at TraversalContext.visit (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/traversal/context.js:148:19)
        at Function.traverse.node (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/traversal/index.js:76:17)
        at Object.traverse [as default] (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/traversal/index.js:55:14)
        at PluginPass.transform (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/transformation/plugin-pass.js:51:27)
        at File.transform (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/transformation/file/index.js:621:12)
        at /Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/transformation/pipeline.js:168:19
        at File.wrap (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/transformation/file/index.js:639:16)
        at Pipeline.transform (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-core/lib/transformation/pipeline.js:165:17)
        at transpile (/Users/loy/Projects/omakase/ui-kit/node_modules/babel-loader/index.js:12:22)
     @ ./docs/index.js 25:21-48

Check all exports for being React components

Currently exports are not being checked. This is, in a way, a regression from React Hot Loader which used to check every export for componentish-ness. It's hitting us really bad in some cases:

  • reduxjs/redux#782
  • reduxjs/react-redux#115
    #18 could potentially fix this, but I have no idea how to even get started on it without a dependency graph, so in the meantime, we should implement exactly what React Hot Loader did: check every export for being a component.

Using babel plugin to dynamically require a resource

Since this is done at the compilation time, I expect the following to work:

import path from 'path';

export default (options) => {
    let dirname,
        info,
        target;

    dirname = path.dirname(options.filename);
    target = path.resolve(dirname, 'index.json');

    info = require(target);

    return (ReactClass) => {
        return ReactClass;
    };
};

But that produces an error in webpack:

WARNING in ../react-transform-css-modules/dist/index.js
Critical dependencies:
23:11-26 the request of a dependency is an expression
 @ ../react-transform-css-modules/dist/index.js 23:11-26

WARNING in Loader /Users/gajus/Documents/dev/gajus/react-transform-css-modules/node_modules/babel/index.js didn't return a function
 @ ../react-transform-css-modules/dist ^\.\/.*$

and an error in the browser:

Uncaught Error: Cannot find module '/Users/gajus/Documents/dev/gajus/babel-react-css-modules-test/src/index.json'.

Is there a way to do it?

Explore wrapping HOCs at the call site

While this sounds pretty crazy, we might want to (via opt-in API?) signal that a particular function in a particular module produces a component, so that the results of this function are identified as components at the call site.

On the other hand maybe this is a terrible idea.

jspm with plugin-babel and react preset: "cannot read property 'transform' of undefined"

I'm getting the above error in the Chrome console at system.js 4 @system.src.js:4837
I've got the jsx preset installed in jspm_packages along with the babel-plugin.
My config.js has the "transpiler" set as "plugin-babel".
My config.js has "presets": [ "babel-preset-react" ] and "blacklist": [] under "babelOptions."

In my "main.js" file I have:

import React from 'react';
import ReactDom from 'react-dom'; (both are installed in jspm_packages)
import showNavbars from '/path' (imports a function)
showNavbars();

On my index.html I have:

<script src="jspm_packages/system.js"></script> <script src="config.js"></script> <script> System.import('/assets/js/main.js'); </script>

I'm not even sure if this is a react-transform issue or not. I'm getting the error from system.js, so I logged it under jspm and babel-plugin as well.

Isomorphic react support

I'm trying to use it in my isomorphic react project. But I got a error when I require a jsx file.

locals[0] does not appear to be a `module` object with Hot Module replacement API enabled. You should disable react-transform-hmr in production by using `env` section in Babel configuration. See the example in README: https://github.com/gaearon/react-transform-hmr

Error: locals[0] does not appear to be a `module` object with Hot Module replacement API enabled. You should disable react-transform-hmr in production by using `env` section in Babel configuration. See the example in README: https://github.com/gaearon/react-transform-hmr
    at proxyReactComponents (/Users/xujie/Documents/Github/FTravel/node_modules/react-transform-hmr/lib/index.js:51:11)
    at Object.<anonymous> (/Users/xujie/Documents/Github/FTravel/public/js/components/Root.jsx:47:59)
    at Module._compile (module.js:425:26)
    at loader (/Users/xujie/Documents/Github/FTravel/node_modules/babel-register/lib/node.js:130:5)
    at Object.require.extensions.(anonymous function) [as .jsx] (/Users/xujie/Documents/Github/FTravel/node_modules/babel-register/lib/node.js:140:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at Object.<anonymous> (app.js:5:20)

Seems like, babel cant figure out whether the file is required in the server side or not. So it apply the react-transform-hmr on every jsx file.

Any workarounds to solve my problem?

Issue with mangling imports

I have a problem with imports when using react-transform and am not quite sure if this is created by react-transform or babel itself or even something I am doing wrong in my config.

In my source file, I am importing a file like this:

import widgetGroups from '../widgetGroups';

Without react-transform, babel translates it to:

var _widgetGroups2 = __webpack_require__(1153);
var _widgetGroups3 = _interopRequireDefault(_widgetGroups2);

Whereas with react-transform, I get:

var _widgetGroups = __webpack_require__(1153);
var _widgetGroups2 = _interopRequireDefault(_widgetGroups2['default']);

This obviously cannot work and throws an error.

Resolving imports paths with enabled preloaders

If I have a preloader in webpack.config, such as:

preLoaders: {
    { test: /\.jsx?$/, loader: 'eslint', exclude: /node_modules/ }
}

then the loader's filename is included in filepath (/Users/.../eslint-loader/index.js!/Users/.../Component.jsx). I guess we should split filepath with "!" and use the last part of it.

Improve the logic for determining if class is a React component

I have been looking at the code and isCompomentishClass function caught my eye as very loose:

/**
* Does this class have a render function?
*/
function isComponentishClass(cls) {
    return cls.body.body.filter(isRenderMethod).length > 0;
} 

The only logic that is used to determine whether class declaration represents a React component is if it defines render method.

Off top of my head, I do not have suggestions how to improve this beyond:

  • Check if class extends Component.
  • Check if class extends React.Component.

I still think thats pretty loose.

I am opening this issue to create a medium for discussion. Maybe someone will have better ideas.

arguments[0] is Function

https://github.com/gaearon/babel-plugin-react-transform/blob/master/src/index.js#L36

Module build failed: TypeError: /Users/xxx/bable-react/react-transform-boilerplate/src/App.js: Cannot read property 'find' of undefined
    at find (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/array-find/find.js:5:17)
    at getDisplayName (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-plugin-react-transform/lib/index.js:33:44)
    at Object.CallExpression (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-plugin-react-transform/lib/index.js:110:27)
    at NodePath._call (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-traverse/lib/path/context.js:74:18)
    at NodePath.call (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-traverse/lib/path/context.js:46:17)
    at NodePath.visit (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-traverse/lib/path/context.js:104:12)
    at TraversalContext.visitQueue (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-traverse/lib/context.js:153:16)
    at TraversalContext.visitSingle (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-traverse/lib/context.js:113:19)
    at TraversalContext.visit (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-traverse/lib/context.js:197:19)
    at Function.traverse.node (/Users/daixiaqing/git/src/bable-react/react-transform-boilerplate/node_modules/babel-traverse/lib/index.js:139:17)

update:
React.createClass(fn())

Fails when running mocha

Hey guys, i get the following error when trying to run mocha:

/Users/nicolas/Sites/webpack-tuto/node_modules/babel-plugin-react-transform/lib/index.js:258
  return new Plugin('babel-plugin-react-transform', {
         ^
TypeError: undefined is not a function
    at exports.default (/Users/nicolas/Sites/webpack-tuto/node_modules/babel-plugin-react-transform/lib/index.js:258:10)
    at Function.memoisePluginContainer (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/transformation/file/plugin-manager.js:46:23)
    at PluginManager.add (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/transformation/file/plugin-manager.js:130:30)
    at File.buildTransformers (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/transformation/file/index.js:281:21)
    at new File (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/transformation/file/index.js:148:10)
    at TransformerPipeline.transform (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/transformation/transformer-pipeline.js:87:16)
    at Object.transformFileSync (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/api/node.js:108:42)
    at compile (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/api/register/node.js:101:20)
    at normalLoader (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/api/register/node.js:150:14)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/nicolas/Sites/webpack-tuto/node_modules/mocha-babel/node_modules/babel/node_modules/babel-core/lib/babel/api/register/node.js:163:7)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at /usr/local/lib/node_modules/mocha/lib/mocha.js:216:27
    at Array.forEach (native)
    at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:213:14)
    at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:453:10)
    at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:393:18)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

Seems to fail, does anybody have mocha running with this?

displayName

Alright, this has been a common issue so I'm folding every other issue into this one single one.

Basically since in Babel 6 plugin visitors get merged, this plugin will always run before babel-plugin-transform-react-display-name, meaning that displayName will never get added because we've already changed the AST.

The fix here has to be inside of the displayName plugin so that it is forced to run before any other transforms.

I'm locking this issue because I don't want any unnecessary noise, I've already identified the problem.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.