Skip to content

Commit

Permalink
chore: upgrade core-js to version 3 (#25158)
Browse files Browse the repository at this point in the history
* chore: upgrade to core-js@3

* add tests to core-js resolver

* update babel-preset tests
  • Loading branch information
wardpeet committed Jul 1, 2020
1 parent 1d568f5 commit a5396ef
Show file tree
Hide file tree
Showing 16 changed files with 207 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Array [
Array [
"@babel/preset-env",
Object {
"corejs": 2,
"corejs": 3,
"debug": false,
"loose": true,
"modules": "commonjs",
Expand All @@ -90,7 +90,7 @@ Array [
Array [
"@babel/preset-env",
Object {
"corejs": 2,
"corejs": 3,
"debug": true,
"loose": true,
"modules": "commonjs",
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-preset-gatsby-package/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function preset(context, options = {}) {
}

const nodeConfig = {
corejs: 2,
corejs: 3,
useBuiltIns: `entry`,
targets: {
node: nodeVersion,
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-preset-gatsby-package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@babel/preset-flow": "^7.10.1",
"@babel/preset-react": "^7.10.1",
"babel-plugin-dynamic-import-node": "^2.3.3",
"core-js": "^2.6.11"
"core-js": "^3.6.5"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
Expand Down
3 changes: 2 additions & 1 deletion packages/babel-preset-gatsby/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"gatsby-core-utils": "^1.3.8"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
"@babel/core": "^7.0.0",
"core-js": "^3.0.0"
},
"license": "MIT",
"main": "index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Object {
Array [
"<PROJECT_ROOT>/node_modules/@babel/preset-env/lib/index.js",
Object {
"corejs": 2,
"corejs": 3,
"exclude": Array [
"transform-typeof-symbol",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Object {
Array [
"<PROJECT_ROOT>/node_modules/@babel/preset-env/lib/index.js",
Object {
"corejs": 2,
"corejs": 3,
"exclude": Array [
"transform-typeof-symbol",
],
Expand Down Expand Up @@ -120,7 +120,7 @@ Object {
Array [
"<PROJECT_ROOT>/node_modules/@babel/preset-env/lib/index.js",
Object {
"corejs": 2,
"corejs": 3,
"exclude": Array [
"transform-typeof-symbol",
],
Expand Down Expand Up @@ -187,7 +187,7 @@ Object {
Array [
"<PROJECT_ROOT>/node_modules/@babel/preset-env/lib/index.js",
Object {
"corejs": 2,
"corejs": 3,
"exclude": Array [
"transform-typeof-symbol",
],
Expand Down Expand Up @@ -254,7 +254,7 @@ Object {
Array [
"<PROJECT_ROOT>/node_modules/@babel/preset-env/lib/index.js",
Object {
"corejs": 2,
"corejs": 3,
"exclude": Array [
"transform-typeof-symbol",
],
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-preset-gatsby/src/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe(`babel-preset-gatsby`, () => {
expect.stringContaining(path.join(`@babel`, `preset-env`)),
{
exclude: [`transform-typeof-symbol`],
corejs: 2,
corejs: 3,
loose: true,
modules: false,
useBuiltIns: `usage`,
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-preset-gatsby/src/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default (_?: unknown, options: IPresetOptions = {}) => {
{
// Allow importing core-js in entrypoint and use browserlist to select polyfills
useBuiltIns: `usage`,
corejs: 2,
corejs: 3,
modules: false,
// Exclude transforms that make all code slower (https://github.com/facebook/create-react-app/pull/5278)
exclude: [`transform-typeof-symbol`],
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-preset-gatsby/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ module.exports = function preset(_, options = {}) {
[
resolve(`@babel/preset-env`),
{
corejs: 2,
corejs: 3,
loose: true,
modules: stage === `test` ? `commonjs` : false,
useBuiltIns: `usage`,
Expand Down
1 change: 0 additions & 1 deletion packages/gatsby-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
},
"dependencies": {
"@babel/code-frame": "^7.10.3",
"@babel/runtime": "^7.10.3",
"@hapi/joi": "^15.1.1",
"@types/common-tags": "^1.8.0",
"better-opn": "^1.0.0",
Expand Down
3 changes: 1 addition & 2 deletions packages/gatsby-cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env node

import "@babel/polyfill"
import os from "os"
import semver from "semver"
import util from "util"
Expand Down Expand Up @@ -46,7 +45,7 @@ if (semver.prerelease(version)) {
report.warn(
report.stripIndent(`
You are currently using a prerelease version of Node (${version}), which is not supported.
You can use this for testing, but we do not recommend it in production.
You can use this for testing, but we do not recommend it in production.
Before reporting any bugs, please test with a supported version of Node (>=${MIN_NODE_VERSION}).`)
)
}
Expand Down
5 changes: 2 additions & 3 deletions packages/gatsby/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
"@babel/code-frame": "^7.10.3",
"@babel/core": "^7.10.3",
"@babel/parser": "^7.10.3",
"@babel/polyfill": "^7.8.7",
"@babel/runtime": "^7.10.3",
"@babel/traverse": "^7.10.3",
"@hapi/joi": "^15.1.1",
"@mikaelkristiansson/domready": "^1.0.10",
Expand Down Expand Up @@ -46,7 +44,7 @@
"compression": "^1.7.4",
"convert-hrtime": "^3.0.0",
"copyfiles": "^2.3.0",
"core-js": "^2.6.11",
"core-js": "^3.6.5",
"cors": "^2.8.5",
"css-loader": "^1.0.1",
"date-fns": "^2.14.0",
Expand Down Expand Up @@ -167,6 +165,7 @@
"babel-preset-gatsby-package": "^0.4.6",
"cross-env": "^5.2.1",
"documentation": "^12.3.0",
"enhanced-resolve": "^4.2.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/gatsby/src/utils/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const fs = require(`fs-extra`)
const path = require(`path`)
const dotenv = require(`dotenv`)
const PnpWebpackPlugin = require(`pnp-webpack-plugin`)
const { CoreJSResolver } = require(`./webpack/corejs-resolver`)
const { store } = require(`../redux`)
const { actions } = require(`../redux/actions`)
const { getPublicPath } = require(`./get-public-path`)
Expand Down Expand Up @@ -388,7 +389,6 @@ module.exports = async (
"@babel/runtime": path.dirname(
require.resolve(`@babel/runtime/package.json`)
),
"core-js": path.dirname(require.resolve(`core-js/package.json`)),
// TODO: Remove entire block when we make fast-refresh the default
...(process.env.GATSBY_HOT_LOADER !== `fast-refresh`
? {
Expand All @@ -415,6 +415,7 @@ module.exports = async (
PnpWebpackPlugin.bind(directoryPath(`public`), module),
// Transparently resolve packages via PnP when needed; noop otherwise
PnpWebpackPlugin,
new CoreJSResolver(),
],
}

Expand Down
75 changes: 75 additions & 0 deletions packages/gatsby/src/utils/webpack/__tests__/corejs-resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { slash } from "gatsby-core-utils"
import { CoreJSResolver } from "../corejs-resolver"

function executeResolve(
resolver: CoreJSResolver,
request: { request: string },
doResolveMock: unknown
): Promise<string> {
return new Promise((resolve, reject) => {
const webpackResolver = {
doResolve: doResolveMock,
ensureHook: (hook: string): string => hook,
getHook: (): Record<string, unknown> => {
return {
tapAsync: (_name: string, fn: Function): void => {
fn(request, null, (err, result) =>
err ? reject(err) : resolve(result)
)
},
}
},
}

resolver.apply(webpackResolver)
})
}

describe(`CoreJSResolver`, () => {
it(`should convert core-js@2 file to core-js@3`, async () => {
const resolver = new CoreJSResolver()

const doResolve = jest.fn((_, request, __, ___, callback) =>
callback(null, slash(request.request))
)

expect(
await executeResolve(
resolver,
{ request: `core-js/modules/es6.array.split.js` },
doResolve
)
).toEqual(expect.stringContaining(`core-js/modules/es.array.split.js`))
})

it(`should convert es6.regexp.replace to its corejs@3 equivalent`, async () => {
const resolver = new CoreJSResolver()

const doResolve = jest.fn((_, request, __, ___, callback) =>
callback(null, slash(request.request))
)

expect(
await executeResolve(
resolver,
{ request: `core-js/modules/es6.regexp.replace.js` },
doResolve
)
).toEqual(expect.stringContaining(`core-js/modules/es.string.replace.js`))
})

it(`should ignore non corejs requests`, async () => {
const resolver = new CoreJSResolver()

const doResolve = jest.fn()

expect(
await executeResolve(
resolver,
{ request: `gatsby/not/core-js.js` },
doResolve
)
).toBeUndefined()
expect(doResolve).not.toHaveBeenCalled()
})
})
103 changes: 103 additions & 0 deletions packages/gatsby/src/utils/webpack/corejs-resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import Resolver from "enhanced-resolve/lib/Resolver"
import * as path from "path"

// Core-js uses es6, es7 & web prefixes, which we'll convert to core-js 3
const coreJs2FileRegex = /\/modules\/(es6|es7|web)\.|\/es6\/|\/es7\//

// Try to replace core-js2 files to core-js@3 to reduce file size
const replaceMap = [
[`/es6.`, `/es.`],
[`/es7.`, `/es.`],
[`/es6/`, `/es/`],
[`/es7/`, `/es/`],
[`/es7/`, `/es/`],
[`web.dom.iterable`, `web.dom-collections.iterator.js`],
[`typed.data-view`, `data-view`],
[`regexp.match`, `string.match`],
[`regexp.replace`, `string.replace`],
[`regexp.search`, `string.search`],
[`regexp.split`, `string.split`],
]

interface IRequest {
request?: string
path: string
}

/**
* Babel-preset is set to corejs@3 which will add automatic polyfills. If a project has core-js@2 installed in their root or a package got compiled with core-js@2
* we need to convert it to corejs@3 because core-js@2 isn't available or we might add multiple polyfills for the same problem.
*
* The resolver converts core-js@2 imports to core-js@3 imports to make our bundle as small as possible.
*/
export class CoreJSResolver {
_coreJSNodeModulesPath: string
_resolver?: Resolver
_target?: string

constructor() {
// Get the nodemodules directory where core-js of gatsby lives
// it might be inside gatsby/node_modules when multiple core-js versions are loaded
this._coreJSNodeModulesPath = path.dirname(
path.dirname(require.resolve(`core-js`))
)
}

resolve(
request: IRequest,
resolveContext: unknown,
callback: (err?: Error | null, result?: unknown) => void
): void {
const innerRequest = request.request || request.path

// we only care about core-js
if (!innerRequest || !innerRequest.startsWith(`core-js/`)) {
return void callback()
}

let coreJsRequest = innerRequest
let resolveMessage = `alias core-js@3 to gatsby's core-js package`

// preset-env adds packages from modules/ so we rewrite them to our gatsby package
if (coreJs2FileRegex.test(coreJsRequest)) {
replaceMap.forEach(([search, replace]) => {
coreJsRequest = coreJsRequest.replace(search, replace)
})

resolveMessage = `map core-js@2(${innerRequest}) to corejs@3(${coreJsRequest})`
}

return void this._resolver.doResolve(
this._target,
{
...request,
request: path.resolve(this._coreJSNodeModulesPath, coreJsRequest),
},
resolveMessage,
resolveContext,
(err, result) => {
if (err) {
return callback(err)
}

// if a rename fails we try to load the original file
// this could error when our mapping isn't complete. I've tested this on a couple of sites
// and couldn't find anything but you never know.
if (result === undefined) {
return callback()
}

return callback(null, result)
}
)
}

apply(resolver: Resolver): void {
this._target = resolver.ensureHook(`resolve`)
this._resolver = resolver

resolver
.getHook(`described-resolve`)
.tapAsync(`CoreJSResolver`, this.resolve.bind(this))
}
}
Loading

0 comments on commit a5396ef

Please sign in to comment.