diff --git a/packages/react-app-polyfill/README.md b/packages/react-app-polyfill/README.md
new file mode 100644
index 00000000000..b3572849eb2
--- /dev/null
+++ b/packages/react-app-polyfill/README.md
@@ -0,0 +1,40 @@
+# react-app-polyfill
+
+This package includes polyfills for various browsers.
+It includes minimum requirements and commonly used language features used by [Create React App](https://github.com/facebook/create-react-app) projects.
+Please refer to its documentation:
+
+- [Getting Started](https://github.com/facebook/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
+- [User Guide](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md) – How to develop apps bootstrapped with Create React App.
+
+### Features
+
+Each polyfill ensures the following language features are present:
+
+1. `Promise` (for `async` / `await` support)
+1. `window.fetch` (a Promise-based way to make web requests in the browser)
+1. `Object.assign` (a helper required for Object Spread, i.e. `{ ...a, ...b }`)
+1. `Symbol` (a built-in object used by `for...of` syntax and friends)
+1. `Array.from` (a built-in static method used by array spread, i.e. `[...arr]`)
+
+### Entry Points
+
+You can import the entry point for the minimal version you intend to support. For example, if you import the IE9 entry point, this will include IE10 and IE11 support.
+
+#### Internet Explorer 9
+
+```js
+// This must be the first line in src/index.js
+import 'react-app-polyfill/ie9';
+
+// ...
+```
+
+#### Internet Explorer 11
+
+```js
+// This must be the first line in src/index.js
+import 'react-app-polyfill/ie11';
+
+// ...
+```
diff --git a/packages/react-scripts/config/polyfills.js b/packages/react-app-polyfill/ie11.js
similarity index 74%
rename from packages/react-scripts/config/polyfills.js
rename to packages/react-app-polyfill/ie11.js
index 8d97fb4ac39..15a7a9a085b 100644
--- a/packages/react-scripts/config/polyfills.js
+++ b/packages/react-app-polyfill/ie11.js
@@ -1,11 +1,9 @@
-// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
-// @remove-on-eject-end
'use strict';
if (typeof Promise === 'undefined') {
@@ -23,8 +21,7 @@ require('whatwg-fetch');
// It will use the native implementation if it's present and isn't buggy.
Object.assign = require('object-assign');
-// In tests, polyfill requestAnimationFrame since jsdom doesn't provide it yet.
-// We don't polyfill it in the browser--this is user's responsibility.
-if (process.env.NODE_ENV === 'test') {
- require('raf').polyfill(global);
-}
+// Support for...of (a commonly used syntax feature that requires Symbols)
+require('core-js/es6/symbol');
+// Support iterable spread (...Set, ...Map)
+require('core-js/fn/array/from');
diff --git a/packages/react-app-polyfill/ie9.js b/packages/react-app-polyfill/ie9.js
new file mode 100644
index 00000000000..ef89d14fa40
--- /dev/null
+++ b/packages/react-app-polyfill/ie9.js
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+'use strict';
+
+if (typeof Promise === 'undefined') {
+ // Rejection tracking prevents a common issue where React gets into an
+ // inconsistent state due to an error, but it gets swallowed by a Promise,
+ // and the user has no idea what causes React's erratic future behavior.
+ require('promise/lib/rejection-tracking').enable();
+ window.Promise = require('promise/lib/es6-extensions.js');
+}
+
+// fetch() polyfill for making API calls.
+require('whatwg-fetch');
+
+// Object.assign() is commonly used with React.
+// It will use the native implementation if it's present and isn't buggy.
+Object.assign = require('object-assign');
+
+// Support for...of (a commonly used syntax feature that requires Symbols)
+require('core-js/es6/symbol');
+// Support iterable spread (...Set, ...Map)
+require('core-js/fn/array/from');
+
+// React 16+ relies on Map, Set, and requestAnimationFrame
+require('core-js/es6/map');
+require('core-js/es6/set');
+require('raf').polyfill(window);
diff --git a/packages/react-app-polyfill/jsdom.js b/packages/react-app-polyfill/jsdom.js
new file mode 100644
index 00000000000..5ad61e54923
--- /dev/null
+++ b/packages/react-app-polyfill/jsdom.js
@@ -0,0 +1,10 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+'use strict';
+
+// fetch() polyfill for making API calls.
+require('whatwg-fetch');
diff --git a/packages/react-app-polyfill/package.json b/packages/react-app-polyfill/package.json
new file mode 100644
index 00000000000..e4ad033a215
--- /dev/null
+++ b/packages/react-app-polyfill/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "react-app-polyfill",
+ "version": "0.0.0",
+ "description": "Polyfills for various browsers including commonly used language features",
+ "repository": "facebook/create-react-app",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/facebook/create-react-app/issues"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "files": [
+ "ie9.js",
+ "ie11.js",
+ "jsdom.js"
+ ],
+ "dependencies": {
+ "core-js": "2.5.7",
+ "object-assign": "4.1.1",
+ "promise": "8.0.2",
+ "raf": "3.4.0",
+ "whatwg-fetch": "3.0.0"
+ }
+}
diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js
index 13fe5cafc24..24f51c018b7 100644
--- a/packages/react-scripts/config/webpack.config.dev.js
+++ b/packages/react-scripts/config/webpack.config.dev.js
@@ -82,10 +82,7 @@ module.exports = {
devtool: 'cheap-module-source-map',
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
- // The first two entry points enable "hot" CSS and auto-refreshes for JS.
entry: [
- // We ship a few polyfills by default:
- require.resolve('./polyfills'),
// Include an alternative client for WebpackDevServer. A client's job is to
// connect to WebpackDevServer by a socket and get notified about changes.
// When you save a file, the client will either apply hot updates (in case
diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js
index af250048d14..76e767faddf 100644
--- a/packages/react-scripts/config/webpack.config.prod.js
+++ b/packages/react-scripts/config/webpack.config.prod.js
@@ -100,8 +100,8 @@ module.exports = {
// We generate sourcemaps in production. This is slow but gives good results.
// You can exclude the *.map files from the build during deployment.
devtool: shouldUseSourceMap ? 'source-map' : false,
- // In production, we only want to load the polyfills and the app code.
- entry: [require.resolve('./polyfills'), paths.appIndexJs],
+ // In production, we only want to load the app code.
+ entry: [paths.appIndexJs],
output: {
// The build folder.
path: paths.appBuild,
diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json
index 93627fd1db2..c632cecbb9c 100644
--- a/packages/react-scripts/package.json
+++ b/packages/react-scripts/package.json
@@ -50,14 +50,12 @@
"jest": "23.6.0",
"loader-utils": "1.1.0",
"mini-css-extract-plugin": "0.4.3",
- "object-assign": "4.1.1",
"optimize-css-assets-webpack-plugin": "5.0.1",
"postcss-flexbugs-fixes": "4.1.0",
"postcss-loader": "3.0.0",
"postcss-preset-env": "6.0.6",
"postcss-safe-parser": "4.0.1",
- "promise": "8.0.2",
- "raf": "3.4.0",
+ "react-app-polyfill": "^0.0.0",
"react-dev-utils": "^5.0.0",
"resolve": "1.8.1",
"sass-loader": "7.1.0",
@@ -68,8 +66,7 @@
"url-loader": "1.1.1",
"webpack": "4.19.1",
"webpack-dev-server": "3.1.9",
- "webpack-manifest-plugin": "2.0.4",
- "whatwg-fetch": "3.0.0"
+ "webpack-manifest-plugin": "2.0.4"
},
"devDependencies": {
"react": "^16.3.2",
diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js
index c077746a9e2..22e52dbdca4 100644
--- a/packages/react-scripts/scripts/utils/createJestConfig.js
+++ b/packages/react-scripts/scripts/utils/createJestConfig.js
@@ -22,7 +22,7 @@ module.exports = (resolve, rootDir, isEjecting) => {
// in Jest configs. We need help from somebody with Windows to determine this.
const config = {
collectCoverageFrom: ['src/**/*.{js,jsx}'],
- setupFiles: [resolve('config/polyfills.js')],
+ setupFiles: ['react-app-polyfill/jsdom'],
setupTestFrameworkScriptFile: setupTestsFile,
testMatch: [
'/src/**/__tests__/**/*.{js,jsx}',