diff --git a/docs/docs/browser-support.md b/docs/docs/browser-support.md index 76035882921f6..3186b0f582a2c 100644 --- a/docs/docs/browser-support.md +++ b/docs/docs/browser-support.md @@ -49,8 +49,6 @@ By default, Gatsby emulates the following config: If you only support newer browsers, make sure to specify this in your `package.json`. This will often enable you to ship smaller JavaScript files. -## Note about IE < 11 +## Note about IE support -React depends on collection types `Map` and `Set`. While these are not used by Gatsby, Gatsby uses React and you will need to polyfill these if you support older browsers and devices including IE < 11. - -Read more about this in [https://reactjs.org/docs/javascript-environment-requirements.html](https://reactjs.org/docs/javascript-environment-requirements.html) +Gatsby will polyfil minimum requirements for IE support according to the `browserslist` config. diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 3ea453d0cfad5..4963fbbacfa1a 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -106,6 +106,7 @@ "postcss-loader": "^2.1.3", "prop-types": "^15.6.1", "raw-loader": "^0.5.1", + "react-app-polyfill": "^0.2.2", "react-dev-utils": "^4.2.1", "react-error-overlay": "^3.0.0", "react-hot-loader": "^4.6.2", diff --git a/packages/gatsby/src/utils/__tests__/webpack.config.js b/packages/gatsby/src/utils/__tests__/webpack.config.js index 4b7b18b4d16ad..bbe7f97627a4b 100644 --- a/packages/gatsby/src/utils/__tests__/webpack.config.js +++ b/packages/gatsby/src/utils/__tests__/webpack.config.js @@ -17,6 +17,7 @@ const { DefinePlugin } = require(`webpack`) const { readFileSync } = require(`fs-extra`) const webpackConfig = require(`../webpack.config`) const { store } = require(`../../redux`) +const { joinPath } = require(`../path`) beforeEach(() => { DefinePlugin.mockClear() @@ -31,13 +32,18 @@ beforeEach(() => { }) }) -const getConfig = (args = {}) => +const getConfig = ( + program, + directory = process.cwd(), + suppliedStage = `build-html` +) => webpackConfig( { extensions: [`.js`], + ...program, }, - process.cwd(), - `build-html` + directory, + suppliedStage ) describe(`basic functionality`, () => { @@ -113,3 +119,48 @@ describe(`environment variables`, () => { }) }) }) + +describe(`polyfill for ie support`, () => { + const directory = `gatsby-app` + const appEntry = joinPath(directory, `.cache/production-app`) + + it(`should not add ie polyfill if ie is not supported`, async () => { + const config = await getConfig( + { browserslist: `defaults, not ie >= 9` }, + directory, + `build-javascript` + ) + + expect(config.entry.app).toEqual([appEntry]) + }) + + it(`should add ie9 polyfill if ie >= 9 is supported`, async () => { + const config = await getConfig( + { browserslist: `defaults, ie >= 9` }, + directory, + `build-javascript` + ) + + expect(config.entry.app).toEqual([`react-app-polyfill/ie9`, appEntry]) + }) + + it(`should add ie9 polyfill if ie >= 10 is supported`, async () => { + const config = await getConfig( + { browserslist: `defaults, ie >= 10` }, + directory, + `build-javascript` + ) + + expect(config.entry.app).toEqual([`react-app-polyfill/ie9`, appEntry]) + }) + + it(`should add ie11 polyfill if ie >= 11 is supported`, async () => { + const config = await getConfig( + { browserslist: `defaults, ie >= 11` }, + directory, + `build-javascript` + ) + + expect(config.entry.app).toEqual([`react-app-polyfill/ie11`, appEntry]) + }) +}) diff --git a/packages/gatsby/src/utils/webpack.config.js b/packages/gatsby/src/utils/webpack.config.js index cec6e1413d990..d568be73d11c2 100644 --- a/packages/gatsby/src/utils/webpack.config.js +++ b/packages/gatsby/src/utils/webpack.config.js @@ -5,6 +5,7 @@ const path = require(`path`) const dotenv = require(`dotenv`) const FriendlyErrorsWebpackPlugin = require(`@pieh/friendly-errors-webpack-plugin`) const PnpWebpackPlugin = require(`pnp-webpack-plugin`) +const browserslist = require(`browserslist`) const { store } = require(`../redux`) const { actions } = require(`../redux/actions`) const debug = require(`debug`)(`gatsby:webpack-config`) @@ -29,6 +30,18 @@ module.exports = async ( ) => { const directoryPath = withBasePath(directory) + // Polyfill for IE support + const supportedBrowsers = browserslist(program.browserslist) + let iePolyfill = false + if ( + supportedBrowsers.includes(`ie 9`) || + supportedBrowsers.includes(`ie 10`) + ) { + iePolyfill = `react-app-polyfill/ie9` + } else if (supportedBrowsers.includes(`ie 11`)) { + iePolyfill = `react-app-polyfill/ie11` + } + process.env.GATSBY_BUILD_STAGE = suppliedStage // We combine develop & develop-html stages for purposes of generating the @@ -151,12 +164,13 @@ module.exports = async ( case `develop`: return { commons: [ + iePolyfill, `event-source-polyfill`, `${require.resolve( `webpack-hot-middleware/client` )}?path=${getHmrPath()}`, directoryPath(`.cache/app`), - ], + ].filter(Boolean), } case `develop-html`: return { @@ -168,7 +182,9 @@ module.exports = async ( } case `build-javascript`: return { - app: directoryPath(`.cache/production-app`), + app: [iePolyfill, directoryPath(`.cache/production-app`)].filter( + Boolean + ), } default: throw new Error(`The state requested ${stage} doesn't exist.`) diff --git a/yarn.lock b/yarn.lock index f9d1d1596dfc6..f8d370421721a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3630,7 +3630,7 @@ arrify@^1.0.0, arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -asap@^2.0.0, asap@~2.0.3: +asap@^2.0.0, asap@~2.0.3, asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -6599,6 +6599,11 @@ core-js-pure@3.0.0: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.0.0.tgz#a5679adb4875427c8c0488afc93e6f5b7125859b" integrity sha512-yPiS3fQd842RZDgo/TAKGgS0f3p2nxssF1H65DIZvZv0Od5CygP8puHXn3IQiM/39VAvgCbdaMQpresrbGgt9g== +core-js@2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.4.tgz#b8897c062c4d769dd30a0ac5c73976c47f92ea0d" + integrity sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A== + core-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0.tgz#a8dbfa978d29bfc263bfb66c556d0ca924c28957" @@ -15276,7 +15281,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@4.1.1, object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -16914,6 +16919,13 @@ promise-retry@^1.1.1: err-code "^1.0.0" retry "^0.10.0" +promise@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.0.2.tgz#9dcd0672192c589477d56891271bdc27547ae9f0" + integrity sha512-EIyzM39FpVOMbqgzEHhxdrEhtOSDOtjMZQ0M6iVfCE+kWNgCkAyOdnuCWqfmflylftfadU6FkiMgHZA2kUzwRw== + dependencies: + asap "~2.0.6" + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -17131,6 +17143,13 @@ quote-stream@^1.0.1, quote-stream@~1.0.2: minimist "^1.1.3" through2 "^2.0.0" +raf@3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + randomatic@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" @@ -17203,6 +17222,17 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-app-polyfill@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-0.2.2.tgz#a903b61a8bfd9c5e5f16fc63bebe44d6922a44fb" + integrity sha512-mAYn96B/nB6kWG87Ry70F4D4rsycU43VYTj3ZCbKP+SLJXwC0x6YCbwcICh3uW8/C9s1VgP197yx+w7SCWeDdQ== + dependencies: + core-js "2.6.4" + object-assign "4.1.1" + promise "8.0.2" + raf "3.4.1" + whatwg-fetch "3.0.0" + react-dev-utils@^4.2.1: version "4.2.2" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-4.2.2.tgz#e8f2ffdbf27bfb13ee88ac18e20c83163aac0659" @@ -21597,7 +21627,7 @@ whatwg-fetch@2.0.4: resolved "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== -whatwg-fetch@>=0.10.0: +whatwg-fetch@3.0.0, whatwg-fetch@>=0.10.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==