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}',