Assuming no major misunderstandings from my side: It was not clear me from the documentation that create-react-app installs fetch (whatwg-fetch), and that this is then available to me in my own JavaScript code. I only found this out when I looked at create-react-app (CRA)'s package.json file and tried it out.
I assume the presence of fetch and its use in user code is intended, but I cannot assume this is true for everything inside CRA's package.json file.
It seems to me there are three kinds of dependencies inside create-react-app:
It is hard to tell right now which dependency is which. It would be great to have this documented somewhere. I would propose something, but I lack the requisite knowledge.
Hi @jhorneman , let's keep track here https://github.com/facebookincubator/create-react-app/pull/531
Thanks. Sorry, I only looked through the docs issues, not the pull requests. I'll do that next time!
It's not meant to be used as a dependency, it's a polyfill. So you should not try to import it.
It just makes sure you have a global fetch()
and global Promise
whether or not browser implements them.
Wrong:
import fetch from 'whatwg-fetch'
fetch()
Right:
fetch()
I agree we should document available polyfills.
People commonly mistakingly assume Create React App polyfills ES6 runtime methods like Array.from
. We should document this.
What is the best practice to adding polyfills to CRA apps?
For example: I want to polyfill Array.includes and I'm wondering where and how to add it and be consistent with the CRA worldview
If you're okay with using CDNs, consider using https://polyfill.io/. Don't forget to add Promise, fetch and Object.assign to excludes
because they're already bundled with CRA.
If you'd prefer to bundle them with your app, you can install core-js
and import corresponding polyfills from src/index.js
before other imports. I don't recommend importing complete core-js
because it is pretty heavy.
Ahh
Ahh thanks Dan, at the time instead of src/index.js
I had added it to the end of config/polyfills.js
:
if (!Array.includes) {
require('core-js/fn/array/includes');
}
@gaearon Should babel-preset-env take care of polyfilling only needed built-ins?
ping @hzoo
The way it works now it requires you to have import "babel-polyfill";
somewhere in your code.
only needed built-ins?
1 is not including polyfills based on the browsers, 2 is not including polyfills that aren't used in the codebase itself (would have to include node_modules/ 3rd party bundled code too if they expect the user to provide them). Seems to be a difficult thing to do so an open issue for it at https://github.com/babel/babel-preset-env/issues/84 (most likely needs 2 passes?)
@hzoo I'd say 1 pass is enough if you use aickin's approach and modify his plugin to not output imports if target set of browsers already supports them.
The issue brought up at the end of #914 where this doesn't work well for people who use react-native-web and want to import some JS-only React-Native dependencies.
This project already support this use case by aliasing react-native
to react-native-web
, why not go all the way and support dependencies?
@RangerMauve
The build times are already pretty slow. We won't be making them slower by compiling everything in node_modules
. It is also not always safe (i.e. compiling a library with Babel can break it in some edge cases).
By the way polyfills are now documented here:
https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#supported-language-features-and-polyfills
So we can close this.
Most helpful comment
It's not meant to be used as a dependency, it's a polyfill. So you should not try to import it.
It just makes sure you have a global
fetch()
and globalPromise
whether or not browser implements them.Wrong:
Right:
I agree we should document available polyfills.