When loading React from the CDN, we now need to include two separate files:
<script src="https://fb.me/react-0.14.2.js"></script>
<script src="https://fb.me/react-dom-0.14.2.js"></script>
Why? Given the primary use of React via CDN is for browsers, shouldn't we bundle them together? When would you ever load react-0.14.2.js via the CDN without loading react-dom-0.14.2.js?
Because we wanted to keep the usage as similar to node as possible. react.js is the react package on npm. react-dom.js is the react-dom package.
There are a non-trivial number of people doing global replacement in their builds with webpack. This replaces var whatever = require('react') with var whatever = React, so it's actually a good idea to keep the objects aligned.
This also works towards the eventual goal of being able to swap out renderers. We may not be there quite yet but if somebody wanted to build an alternate renderer, they would just drop the react-dom.js and use my-custom-dom-renderer.js.
There are a non-trivial number of people doing global replacement in their builds with webpack. This replaces var whatever = require('react') with var whatever = React, so it's actually a good idea to keep the objects aligned.
Sure, but providing two globals (React and ReactDOM) doesn't mean they need to be in two totally separate JavaScript files :)
Since loading both is the most common case right now, wouldn't it be beneficial to provide one .js file with both (say react-full.js or something like that)?
As @Daniel15 mentioned, we could export two globals. This issue keeps coming up (eg. https://github.com/facebook/react/issues/6128), and for a good reason: In the common case, a user will want react.js IFF they're using react-dom.js so it makes sense for the default to be that they are packaged together. There are notable counterexamples (like react-art), but most of those people are using commonjs anyway (which will deduplicate). It's easy to make the argument that they should be bundled by default. At the very least, we could provide an optional bundled build for the CDNs.
@jimfb +1
The optional build seems to be the best option. Should keep everyone happy, without any downsides. Eventually the natural course of things in terms browser requests should be pulling in of the combined bundle, ensuring sensible browser caches.
in completeness, with http2 you would arguably want react-core and react-dom to be separate requests still. To be optimal in all scenarios we’d be asking the React team to maintain a minimum of the following distributions:
At the very least, we could provide an optional bundled build for the CDNs.
This sounds better than providing just a single build to me.
You’d need not one but two new builds though: ReactWithDOM.js, ReactWithAddonsAndDOM.js.
I’m confused how UMD would work for such builds. I think a library can have two “independent” exports (window.React and window.ReactDOM) only in the global environment. This wouldn’t work exactly like this in CommonJS which UMD builds currently support.
Today you can
import React from 'react/dist/react'
import ReactDOM from 'react-dom/dist/react-dom'
using our UMD builds.
For the hypothetical ReactWithDOM, if it is UMD, it would either look like
import ReactWithDOM from 'react/dist/react-with-dom'
with merged public API (potential name clashes), or
import { React, ReactDOM } from 'react/dist/react-with-dom'
(inconsistent with how we import them in vanilla builds).
Not saying importing CommonJS from UMD build is a common use case but I’m worried about the potential confusion here. Or maybe I just don’t understand how UMD builds work :sweat_smile: .
We won't do just a single build and replace what we have now. If we do this, it will be another bundled build. It will probably not be UMD and just set 2 globals.
Imagine that there was another renderer on the page such as react-art.js, then you would need them both to use the same react (because there is still shared global state). There still needs to be separate distributions of each one then. react, react-art, react-dom as well as react-with-dom. Maybe you can combine react-with-dom with react-art, but what if you only want react-art? Then you have to add react.
Seems complicated.
Just a wild suggestion, even though it may not apply explicitly to react.
Has facebook considered their CDNs to take in optional request like what Google does (eg. Google Fonts)?
How about Facebook's CDN take a request with multiple keys?
Say //fb.me/?d=react-0.14.7.min.js+react-dom-0.14.7.min.js which ends up providing both in one request? And all Facebook needs to do is cache these requests with the dependency arithmetic in their side.
This should solve all the problems above quite succinctly. And would render this entire discussion irrelevant, and all the dependencies no matter the sizes, and usage patterns can be kept clean and separate.
Also, adding on to the above, usage patterns can then be isolated and provided for cleaner requests:
Eg: Instead of d=, usage of 'b=' (b for bundle) could be to pull in a set of pre-defined dependencies. So an example of a typical browser request of react with dom could either be:
//fb.me/?d=react-0.14.7.min.js+react-dom-0.14.7.min.js
or
//fb.me/?b=react-with-dom.0.14.7
Would even enable unknown potential future use cases, in a clean way.
PS: Something has to be done about the dashes if true dependency arithmetic is used, or they could just be ignored as well, only considering additions. Of course the details of the spec of the requests would have to be decided on then for consistency. This is just the idea.
To take that even further: this could actually make React a lot smaller since with an optional flag, since its opens up the possibility of only sending in custom builds which open up browser specific requirements, removing all compatibility layers. So, based on the User-Agent, the react dependency served directly from the CDN can be only specific to that particular browser. Less code, smaller network packages, lesser latency, more smiling faces.
React has to starting modularizing even more for that, allowing custom builds removing compatibility layers, but this could be a very interesting area to explore.
Closing as we won't be changing this.
Most helpful comment
Sure, but providing two globals (
ReactandReactDOM) doesn't mean they need to be in two totally separate JavaScript files :)Since loading both is the most common case right now, wouldn't it be beneficial to provide one .js file with both (say react-full.js or something like that)?