Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: upgrade core-js to version 3 #25158

Merged
merged 3 commits into from
Jul 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Copy link
Contributor Author

@wardpeet wardpeet Jun 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need this anymore (node 10.13 is pretty good)

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.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is prettier

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"
wardpeet marked this conversation as resolved.
Show resolved Hide resolved
import * as path from "path"
blainekasten marked this conversation as resolved.
Show resolved Hide resolved

// 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