Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading React + ReactDOM from cdn #2758

Closed
mschipperheyn opened this issue Jul 10, 2017 · 36 comments
Closed

Loading React + ReactDOM from cdn #2758

mschipperheyn opened this issue Jul 10, 2017 · 36 comments

Comments

@mschipperheyn
Copy link

Given that React and ReactDOM are so prevalent and therefore likely to exist in the browser cache, it seems to make sense to have an option to build the package with an option to to include React and ReactDOM statically in the HTML file.

It would make the initial load that much snappier.

Is this something that could be considered?

@gaearon
Copy link
Contributor

gaearon commented Jul 10, 2017

I agree. There are currently reasons why we can’t easily do this (addons reach into React internals). But with React 16 this will no longer be a problem and I think we can reconsider offering this.

@chj-damon
Copy link

@gaearon have you offered this in the newest version of create-react-app?

@swyxio
Copy link
Contributor

swyxio commented Jan 22, 2018

hi! just had the same idea too. also wanted to point out it maybe doesnt take much more effort than configuring babel: https://www.youtube.com/watch?v=2rhkgB8Cohc

edit: i meant webpack, leaving my mistake as dan responded to me below

@gaearon
Copy link
Contributor

gaearon commented Jan 22, 2018

Not sure what this has to do with Babel.

have you offered this in the newest version of create-react-app?

No but I’m open to suggestions for how it should work! I think maybe we can do this automatically if we detect CDN links in the HTML? What do you think?

@czebe
Copy link

czebe commented Jan 22, 2018

Just offer a way to customize webpack.
I believe these scripts should go into "externals".

@gaearon
Copy link
Contributor

gaearon commented Jan 22, 2018

Nah, we're not going to allow to customize webpack :-) There are dozens of issues about this if you're wondering why.

@yvesgurcan
Copy link

Hello! I would love to contribute to create-react-app and this seems an easy enough project for me. I would be happy to put into practice @gaearon 's suggestion. Which files should I look at?

@andriijas
Copy link
Contributor

I was thinking the way @Ayc0 used to implement vendors in #3145 could be reused for this and #3878 - Im currently working in a project where some resources are loaded via CDN statically in index.html and its far from optimal. Its pretty convenient to have one source of truth of your packages and dependencies - package.json - easier to know which versions you are using and to keep track of updates.

Anyway Im just getting started with #3878 lets see how it goes.

@Ayc0
Copy link

Ayc0 commented Jan 23, 2018

@andriijas I don't know if you can use the chunk plugin (or the new split chunk plugin) to replace a module by a cdn

the external field of webpack can do this I think
Maybe, we can add a field externals in the package.json that's gonna be read by webpack

@Ayc0
Copy link

Ayc0 commented Jan 23, 2018

@iansu
Copy link
Contributor

iansu commented Jan 23, 2018

That webpack plugin looks like a good option. Does someone want to try it out and submit a PR?

@swyxio
Copy link
Contributor

swyxio commented Jan 24, 2018

giving it a shot. i think this could be an easy win.

@iansu - any thoughts on would this be a prod-only feature or both dev and prod?

@swyxio
Copy link
Contributor

swyxio commented Jan 24, 2018

I have implemented this only for prod. as one might expect it shaves 30kb off the bundle size (aka react)

@chj-damon
Copy link

@sw-yx would you like to share your process that how you make it?

@andriijas
Copy link
Contributor

@Ayc0 nah i was thinking we could have one central place to configure vendors and third parties

@Ayc0
Copy link

Ayc0 commented Jan 25, 2018

@andriijas for those kind of things, I'd like to add a config in the package.json
But, as the package.json has a standard shape, I don't know if it's a good a idea to add custom things in it
Or we could do what everyone is doing: support a cra field in the package.json and a .crarc and a .crarc.js files that contains our config

what do you think about this @gaearon ?

@swyxio
Copy link
Contributor

swyxio commented Jan 25, 2018

How do you reconcile this vs. the overall philosophy of zero config? I feel like Dan is always fending off suggestions to add config to explicitly zero config things. It is -ok- to have an opinion to make the lives of a majority of users (esp those who cant figure out good defaults for themselves) better. Thats why CRA did well in the first place, no?

@Ayc0
Copy link

Ayc0 commented Jan 25, 2018

I think it depends on the feature: for instance the service workers
It has been added by default but it's gonna be removed because it wasn't useful for everyone

but other tools are being created (ex: react app rewired) to keep CRA with a bit of customisation

I thing CRA could be better if some options were given to the users, but in a restricted way

Here, the cdn are really related to the packages a user is using, and we cannot predict what there're gonna use

@davidjb
Copy link
Contributor

davidjb commented Jan 31, 2018

If CDN loading is implemented, it'd be helpful to customise which CDN is being used for which specific resource; pretty much what @Ayc0 is saying as I understand it. It looks as though https://github.com/mastilver/dynamic-cdn-webpack-plugin is using its own modules.json under the hood, so you have to use unpkg or whatever's there -- which isn't going to suit everyone.

@swyxio
Copy link
Contributor

swyxio commented Feb 5, 2018

well I'm not sure what else to do at this point so if someone wants to give clearer guidance on this I'm all ears :)

@iansu
Copy link
Contributor

iansu commented Feb 5, 2018

Unfortunately I don't think there is a clear answer here. We need to make using a CDN opt-in and we also need to allow users to choose what CDN they want to use. It doesn't look like we can do that with dynamic-cdn-webpack-plugin.

One option might be to look in index.html for CDN links and then don't bundle React and/or ReactDOM if they're present. That's definitely more complicated though and I don't think there's an existing plugin we could use to do that.

@swyxio
Copy link
Contributor

swyxio commented Feb 6, 2018

I mean thats not super hard to do in Node especially if we can make rules for what looks like a cdn link. it could work. do we want to do this?

@iansu
Copy link
Contributor

iansu commented Feb 7, 2018

If we can make it work reliably then I do think it's something we want.

@czebe
Copy link

czebe commented Feb 7, 2018

How would you handle situations when the CDN is not available? Fallback mechanism can be quite complex, impossible to define in HTML.

@swyxio
Copy link
Contributor

swyxio commented Feb 7, 2018

with this proposal, CDN is opt in. you are consciously choosing to use CDN. so we don't need to handle fallback mechanism for the user. (I am learning that a lot of people dislike CDNs on principle)

@mastilver
Copy link

https://github.com/mastilver/dynamic-cdn-webpack-plugin is using its own modules.json under the hood, so you have to use unpkg or whatever's there -- which isn't going to suit everyone.

@davidjb You can already use your own implementation using the resolver options, I'm planning to add more "official" resolver (cdnjs for example)

https://github.com/mastilver/dynamic-cdn-webpack-plugin#optionsresolver

@davidjb
Copy link
Contributor

davidjb commented Feb 9, 2018

@mastilver Good to know, thanks. In the context of CRA, there'd need to be customisation which mightn't align with no customising Webpack (eg @gaearon's [comment](#2758 (comment) above). Perhaps CRA having its own resolver implementation that looks up package.json or some other config location might be the answer.

@swyxio
Copy link
Contributor

swyxio commented Feb 9, 2018

I think both @czebe and @davidjb might be overlooking @iansu's suggestion: "One option might be to look in index.html for CDN links and then don't bundle React and/or ReactDOM if they're present."

edit: i am unsubscribing to this issue bc i am not so keen on it anymore. hopefully yarn plug n play comes soon.

@crebbo
Copy link

crebbo commented Oct 4, 2018

Is there any plans for this feature ^ to be incorporated into create-react-app? Ideally I'm look for a sound way to exclude specified modules and to include my own cdn links. From what I can see dynamic-cdn-webpack-plugin doesn't work with create-react-app, has anyone done this well yet?

@ryouaki
Copy link

ryouaki commented Oct 28, 2018

I am looking for the solution about this feature.

@ryouaki
Copy link

ryouaki commented Oct 28, 2018

Nah, we're not going to allow to customize webpack :-) There are dozens of issues about this if you're wondering why.

But this is why we need eject the script from cra...... ( T_T )

@Ayc0
Copy link

Ayc0 commented Oct 28, 2018

If you want to modify the package.json, I don't recommand you to eject.

Instead try react-app-rewired. I'm using it on a big codebase and it works like a charm.

I'm also using it in cra2

@Kiranprajapati2719
Copy link

What about adding a custom react script allowing use of dynamic-cdn-webpack-plugin? Any possibility?

@yushengyuan1993
Copy link

yushengyuan1993 commented May 21, 2019

there is a solution, it works for me:
apple:

/* index.html */
<div id="root"></div>
<script src="%PUBLIC_URL%/static/js/react.development.js"></script>
<script src="%PUBLIC_URL%/static/js/react-dom.development.js"></script>
<script src="%PUBLIC_URL%/static/js/react-router.min.js"></script>

banana:

/* ./src/config.js */
const React = window.React;
const ReactDOM = window.ReactDOM;
const ReactRouter = window.ReactRouter;

export { React, ReactDOM, ReactRouter };

cat:
you kan use React like this:

/* ./src/index.js */
import { React, ReactDOM } from './config.js';

ReactDOM.render(<App />, document.getElementById('root'));

// Or
/* ./src/components/tabbar.js */
import { React } from '../config.js';

class TabBar extends React.Component {
 // your code ...
}

dog:
i started learning react a few days ago, so i am still a newcomer to using react.

@jamesknelson
Copy link
Contributor

jamesknelson commented Nov 6, 2019

If anyone still wants to do this -- which I wouldn't recommend but sometimes you get odd requirements -- you can just add some shim packages.

First, you'll need to load React from the CDN of your choice, in index.html:

<script src="https://unpkg.com/react@16.11.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-is@16.11.0/umd/react-is.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.11.0/umd/react-dom.production.min.js"></script>

Then, add a shims/react directory with package.json and index.js files:

{
  "name": "react",
  "version": "16.11.0",
  "private": true,
  "main": "./index.js",
  "module": "./index.js"
}
module.exports = window.React

Next, repeat this for react-dom and react-is.

Finally, update your root package.json's dependencies to point to the new shims (you may also need to nuke yarn.lock and node_modules to get the shims picked up):

{
  "dependencies": {
    "react": "./shims/react",
    "react-dom": "./shims/react-dom",
    "react-is": "./shims/react-is",
  }
}

This is a fair bit of work, and I feel like it's probably not even a good idea in most cases, but it'll let you externalize any packages you need with stock CRA.

@andriijas
Copy link
Contributor

andriijas commented Nov 6, 2019

Thanks for the update @jamesknelson

The http cache in browsers isn't predictable anymore ( https://www.jefftk.com/p/shared-cache-is-going-away ). Browsers are moving a away from single http cache to partitioned cache (for security reasons).

In 2019 it's not safe to make an assumption that React is in the cache anymore. Also cheap to free hosting options for single page apps has advanced even further in the recent years.

A better way to increase performance in your apps is to work with code splitting.

Therefor its time to close this issue. Sorry for any inconvenience.

@lock lock bot locked and limited conversation to collaborators Nov 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests