We have previously considered bundling React into a flat file without requires and a module map.
For example, #4230 is a (somewhat outdated) implementation of this.
Rollup is another tool that, if I鈥檓 not mistaken, bundles modules in the same way.
Do we really want to do this? What problems does this solve for us? If we want to try, what is the plan, and how do we evaluate whether the switch is worth it?
It seems like one trick would be to accommodate existing projects that includes React internals. How badly would this affect them, and is there a smooth upgrade path?
Relying on React internals was never supported in the first place. There are edge cases where this is still necessary (renderers) but presumably we would come up with public APIs or unstable exported modules for them.
We should do this and taking it a step further, we will want to consider using our bundled file in npm (with a single entry point that does the dev check, requiring & rexporting either the min or dev version). Downside of that is you don't get the shared deps for everything that comes from fbjs (and anything else we might depend on in the future). But as long as those deps are stateless then we're ok. The other piece to figure out is the bridges between packages like react-dom, react-native, etc and making sure the right bits (be they public APIs or unstable ones) are exposed.
For whatever my opinion is worth, I really like this. If this is seen through, it would be cool for rough numbers to be published on the React blog as a reference point for other projects.
I'm not sure how really relevant it is, but it may be worth considering that webpack 2 will come with "tree shaking" which allows it to discard unused modules from the bundle. Due to the current design of React it will probably not make a measurable difference anyway, but compiling to a single file will flat-out prevent that. There are also other logistical hurdles to cross for it to be feasible, but may be worth keeping in-mind at least.
@gaearon cjs-to-es6 can be of great help :). :+1: for using rollup. I threw a few minutes at it and I got src/isomorphic/React.js and all of its files as es6 modules here. Here's the a very simple rollup script to get people going. You run it with rollup -c rollup.config.js src/isomorphic/React.js.
By the way, I'm linking this issue to #6336 as it's also about modules.
Sorry if this is covered somewhere else but I couldn't find it, how does one access the haste map for React modules? It would be very handy to automatically replace imports for paths :).
Thanks!
On haste vs relative paths, I pushed some more code that allows for providesModule to keep on being used through an alias in rollup. I included the map and the alias in the commit so that it's easier for people to look at.
Generate the module map with node alias-provides-modules/index.js './src/**/*.js' > module-map.json from react's root. The rollup command doesn't change, e.g. build ReactDOM rollup -c rollup.config.js src/renderers/dom/ReactDOM.js.
There seem to be many dependencies that aren't part of the codebase itself, e.g., ExecutionEnvironment, invariant, keyMirror, etc., I imagine that haste might be providing this for you internally, am I right? /cc @gaearon @zpao
https://github.com/rollup/rollup/wiki/ES6-modules
This would be awesome!
There seem to be many dependencies that aren't part of the codebase itself
Yea, we pull those in from fbjs which has a generated module map & that gets used when rewriting requires.
@zpao so I reckon that fbjs' module map could be leveraged too?
Probably. I only took a quick look at what you're doing and it seems like it should be very similar/identical. FYI: we're a ways from committing to something like what you're working on (if ever), but it's a cool exploration and we'll definitely cycle back to looking at it.
Going to keep track of next units of work here.
https://github.com/facebook/react/pull/9147
Done in #9327!
Most helpful comment
I'm not sure how really relevant it is, but it may be worth considering that webpack 2 will come with "tree shaking" which allows it to discard unused modules from the bundle. Due to the current design of React it will probably not make a measurable difference anyway, but compiling to a single file will flat-out prevent that. There are also other logistical hurdles to cross for it to be feasible, but may be worth keeping in-mind at least.