Skip to content

Commit

Permalink
fix(*): enable separate config for node_modules transpilation (#15270)
Browse files Browse the repository at this point in the history
  • Loading branch information
wardpeet committed Jul 1, 2019
1 parent e5a2f47 commit 7e39a12
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 23 deletions.
1 change: 1 addition & 0 deletions packages/babel-preset-gatsby/package.json
Expand Up @@ -8,6 +8,7 @@
"@babel/plugin-transform-runtime": "^7.0.0",
"@babel/preset-env": "^7.4.1",
"@babel/preset-react": "^7.0.0",
"@babel/runtime": "^7.4.5",
"babel-plugin-macros": "^2.4.2"
},
"peerDependencies": {
Expand Down
15 changes: 14 additions & 1 deletion packages/babel-preset-gatsby/src/__tests__/index.js
Expand Up @@ -8,6 +8,7 @@ it(`Specifies proper presets and plugins for test stage`, () => {
[
expect.stringContaining(path.join(`@babel`, `preset-env`)),
{
exclude: [`transform-typeof-symbol`],
corejs: 2,
loose: true,
modules: `commonjs`,
Expand Down Expand Up @@ -40,8 +41,13 @@ it(`Specifies proper presets and plugins for test stage`, () => {
[
expect.stringContaining(path.join(`@babel`, `plugin-transform-runtime`)),
{
absoluteRuntimePath: expect.stringContaining(
path.join(`@babel`, `runtime`)
),
corejs: false,
helpers: true,
regenerator: true,
useESModules: false,
},
],
])
Expand All @@ -63,6 +69,7 @@ it(`Specifies proper presets and plugins for build-html stage`, () => {
[
expect.stringContaining(path.join(`@babel`, `preset-env`)),
{
exclude: [`transform-typeof-symbol`],
corejs: 2,
loose: true,
modules: false,
Expand Down Expand Up @@ -95,8 +102,13 @@ it(`Specifies proper presets and plugins for build-html stage`, () => {
[
expect.stringContaining(path.join(`@babel`, `plugin-transform-runtime`)),
{
helpers: true,
absoluteRuntimePath: expect.stringContaining(
path.join(`@babel`, `runtime`)
),
helpers: false,
regenerator: true,
corejs: false,
useESModules: true,
},
],
])
Expand All @@ -111,6 +123,7 @@ it(`Allows to configure browser targets`, () => {
expect(presets[0]).toEqual([
expect.stringContaining(path.join(`@babel`, `preset-env`)),
{
exclude: [`transform-typeof-symbol`],
corejs: 2,
loose: true,
modules: false,
Expand Down
55 changes: 55 additions & 0 deletions packages/babel-preset-gatsby/src/dependencies.js
@@ -0,0 +1,55 @@
// This file is heavily based on create-react-app's implementation
// @see https://github.com/facebook/create-react-app/blob/master/packages/babel-preset-react-app/dependencies.js

const path = require(`path`)
const resolve = m => require.resolve(m)

module.exports = function(api, options = {}) {
const absoluteRuntimePath = path.dirname(
resolve(`@babel/runtime/package.json`)
)

return {
// Babel assumes ES Modules, which isn't safe until CommonJS
// dies. This changes the behavior to assume CommonJS unless
// an `import` or `export` is present in the file.
// https://github.com/webpack/webpack/issues/4039#issuecomment-419284940
sourceType: `unambiguous`,
presets: [
[
// Latest stable ECMAScript features
`@babel/preset-env`,
{
// Allow importing core-js in entrypoint and use browserlist to select polyfills
useBuiltIns: `usage`,
corejs: 2,
modules: false,
// Exclude transforms that make all code slower (https://github.com/facebook/create-react-app/pull/5278)
exclude: [`transform-typeof-symbol`],
},
],
],
plugins: [
// Polyfills the runtime needed for async/await, generators, and friends
// https://babeljs.io/docs/en/babel-plugin-transform-runtime
[
resolve(`@babel/plugin-transform-runtime`),
{
corejs: false,
helpers: true,
regenerator: true,
// https://babeljs.io/docs/en/babel-plugin-transform-runtime#useesmodules
// We should turn this on once the lowest version of Node LTS
// supports ES Modules.
useESModules: true,
// Undocumented option that lets us encapsulate our runtime, ensuring
// the correct version is used
// https://github.com/babel/babel/blob/090c364a90fe73d36a30707fc612ce037bdbbb24/packages/babel-plugin-transform-runtime/src/index.js#L35-L42
absoluteRuntime: absoluteRuntimePath,
},
],
// Adds syntax support for import()
resolve(`@babel/plugin-syntax-dynamic-import`),
],
}
}
10 changes: 9 additions & 1 deletion packages/babel-preset-gatsby/src/index.js
Expand Up @@ -29,6 +29,9 @@ module.exports = function preset(_, options = {}) {

const pluginBabelConfig = loadCachedConfig()
const stage = process.env.GATSBY_BUILD_STAGE || `test`
const absoluteRuntimePath = path.dirname(
require.resolve(`@babel/runtime/package.json`)
)

if (!targets) {
if (stage === `build-html` || stage === `test`) {
Expand All @@ -50,6 +53,8 @@ module.exports = function preset(_, options = {}) {
modules: stage === `test` ? `commonjs` : false,
useBuiltIns: `usage`,
targets,
// Exclude transforms that make all code slower (https://github.com/facebook/create-react-app/pull/5278)
exclude: [`transform-typeof-symbol`],
},
],
[
Expand All @@ -73,8 +78,11 @@ module.exports = function preset(_, options = {}) {
[
resolve(`@babel/plugin-transform-runtime`),
{
helpers: true,
corejs: false,
helpers: stage === `develop` || stage === `test`,
regenerator: true,
useESModules: stage !== `test`,
absoluteRuntimePath,
},
],
],
Expand Down
Expand Up @@ -2,7 +2,7 @@

exports[`webpack utils js returns default values without any options 1`] = `
Object {
"exclude": /core-js\\|event-source-polyfill\\|webpack-hot-middleware\\\\/client/,
"exclude": /\\(node_modules\\|bower_components\\)/,
"test": /\\\\\\.\\(js\\|mjs\\|jsx\\)\\$/,
"type": "javascript/auto",
"use": Array [
Expand All @@ -14,15 +14,28 @@ Object {
}
`;

exports[`webpack utils js returns the correct exclude paths 1`] = `
exports[`webpack utils js returns default values without any options 2`] = `
Object {
"exclude": /core-js\\|event-source-polyfill\\|webpack-hot-middleware\\\\/client\\|node_modules/,
"test": /\\\\\\.\\(js\\|mjs\\|jsx\\)\\$/,
"exclude": /@babel\\(\\?:\\\\/\\|\\\\\\\\\\{1,2\\}\\)runtime\\|core-js/,
"test": /\\\\\\.\\(js\\|mjs\\)\\$/,
"type": "javascript/auto",
"use": Array [
Object {
"loader": "<PROJECT_ROOT>/packages/gatsby/src/utils/babel-loader.js",
"options": Object {},
"options": Object {
"babelrc": false,
"compact": false,
"configFile": false,
"presets": Array [
Array [
"<PROJECT_ROOT>/packages/babel-preset-gatsby/dependencies.js",
Object {
"stage": "develop",
},
],
],
"sourceMaps": false,
},
},
],
}
Expand Down
10 changes: 6 additions & 4 deletions packages/gatsby/src/utils/__tests__/webpack-utils.js
Expand Up @@ -22,10 +22,12 @@ describe(`webpack utils`, () => {
expect(rule).toMatchSnapshot()
})

it(`returns the correct exclude paths`, () => {
const rule = config.rules.js({
exclude: [`node_modules`],
})
it(`adds dependency rule`, () => {
expect(config.rules.dependencies).toEqual(expect.any(Function))
})

it(`returns default values without any options`, () => {
const rule = config.rules.dependencies()

expect(rule).toMatchSnapshot()
})
Expand Down
38 changes: 32 additions & 6 deletions packages/gatsby/src/utils/webpack-utils.js
Expand Up @@ -293,14 +293,10 @@ module.exports = async ({
* JavaScript loader via babel, excludes node_modules
*/
{
let js = ({ exclude = [], ...options } = {}) => {
const excludeRegex = [
`core-js|event-source-polyfill|webpack-hot-middleware/client`,
].concat(exclude)

let js = (options = {}) => {
return {
test: /\.(js|mjs|jsx)$/,
exclude: new RegExp(excludeRegex.join(`|`)),
exclude: vendorRegex,
type: `javascript/auto`,
use: [loaders.js(options)],
}
Expand All @@ -309,6 +305,36 @@ module.exports = async ({
rules.js = js
}

/**
* Node_modules JavaScript loader via babel (exclude core-js & babel-runtime to speedup babel transpilation)
*/
{
let dependencies = (options = {}) => {
const jsOptions = {
babelrc: false,
configFile: false,
compact: false,
presets: [
[require.resolve(`babel-preset-gatsby/dependencies`), { stage }],
],
// If an error happens in a package, it's possible to be
// because it was compiled. Thus, we don't want the browser
// debugger to show the original code. Instead, the code
// being evaluated would be much more helpful.
sourceMaps: false,
}

return {
test: /\.(js|mjs)$/,
exclude: /@babel(?:\/|\\{1,2})runtime|core-js/,
type: `javascript/auto`,
use: [loaders.js(jsOptions)],
}
}

rules.dependencies = dependencies
}

{
let eslint = schema => {
return {
Expand Down
13 changes: 7 additions & 6 deletions packages/gatsby/src/utils/webpack.config.js
Expand Up @@ -248,12 +248,6 @@ module.exports = async (program, directory, suppliedStage) => {
function getModule() {
const jsOptions = {}

// Speedup 🏎️💨 the build! We only include transpilation of node_modules on production builds
// TODO create gatsby plugin to enable this behaviour on develop (only when people are requesting this feature)
if (stage === `develop`) {
jsOptions.exclude = [`node_modules`]
}

// Common config for every env.
// prettier-ignore
let configRules = [
Expand All @@ -264,6 +258,13 @@ module.exports = async (program, directory, suppliedStage) => {
rules.media(),
rules.miscAssets(),
]

// Speedup 🏎️💨 the build! We only include transpilation of node_modules on javascript production builds
// TODO create gatsby plugin to enable this behaviour on develop (only when people are requesting this feature)
if (stage === `build-javascript`) {
configRules.push(rules.dependencies())
}

if (store.getState().themes.themes) {
configRules = configRules.concat(
store.getState().themes.themes.map(theme => {
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Expand Up @@ -1937,6 +1937,7 @@
"@babel/runtime@^7.4.5":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
dependencies:
regenerator-runtime "^0.13.2"

Expand Down

0 comments on commit 7e39a12

Please sign in to comment.