diff --git a/packages/babel-preset-gatsby/src/__tests__/__snapshots__/index.js.snap b/packages/babel-preset-gatsby/src/__tests__/__snapshots__/index.js.snap new file mode 100644 index 0000000000000..2da44f352415c --- /dev/null +++ b/packages/babel-preset-gatsby/src/__tests__/__snapshots__/index.js.snap @@ -0,0 +1,229 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`babel-preset-gatsby should specify proper presets and plugins when stage is build-html 1`] = ` +Object { + "plugins": Array [ + Array [ + "/node_modules/@babel/plugin-proposal-class-properties/lib/index.js", + Object { + "loose": true, + }, + ], + "/node_modules/babel-plugin-macros/dist/index.js", + "/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js", + Array [ + "/node_modules/@babel/plugin-transform-runtime/lib/index.js", + Object { + "absoluteRuntimePath": "/packages/babel-preset-gatsby/node_modules/@babel/runtime", + "corejs": false, + "helpers": false, + "regenerator": true, + "useESModules": true, + }, + ], + Array [ + "/node_modules/@babel/plugin-transform-spread/lib/index.js", + Object { + "loose": false, + }, + ], + "/node_modules/babel-plugin-dynamic-import-node/lib/index.js", + ], + "presets": Array [ + Array [ + "/node_modules/@babel/preset-env/lib/index.js", + Object { + "corejs": 2, + "exclude": Array [ + "transform-typeof-symbol", + ], + "loose": true, + "modules": false, + "targets": Object { + "node": "current", + }, + "useBuiltIns": "usage", + }, + ], + Array [ + "/node_modules/@babel/preset-react/lib/index.js", + Object { + "development": false, + "pragma": "React.createElement", + "useBuiltIns": true, + }, + ], + ], +} +`; + +exports[`babel-preset-gatsby should specify proper presets and plugins when stage is build-javascript 1`] = ` +Object { + "plugins": Array [ + Array [ + "/node_modules/@babel/plugin-proposal-class-properties/lib/index.js", + Object { + "loose": true, + }, + ], + "/node_modules/babel-plugin-macros/dist/index.js", + "/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js", + Array [ + "/node_modules/@babel/plugin-transform-runtime/lib/index.js", + Object { + "absoluteRuntimePath": "/packages/babel-preset-gatsby/node_modules/@babel/runtime", + "corejs": false, + "helpers": false, + "regenerator": true, + "useESModules": true, + }, + ], + Array [ + "/node_modules/@babel/plugin-transform-spread/lib/index.js", + Object { + "loose": false, + }, + ], + "/node_modules/babel-plugin-dynamic-import-node/lib/index.js", + Array [ + "/node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js", + Object { + "removeImport": true, + }, + ], + ], + "presets": Array [ + Array [ + "/node_modules/@babel/preset-env/lib/index.js", + Object { + "corejs": 2, + "exclude": Array [ + "transform-typeof-symbol", + ], + "loose": true, + "modules": false, + "targets": undefined, + "useBuiltIns": "usage", + }, + ], + Array [ + "/node_modules/@babel/preset-react/lib/index.js", + Object { + "development": false, + "pragma": "React.createElement", + "useBuiltIns": true, + }, + ], + ], +} +`; + +exports[`babel-preset-gatsby should specify proper presets and plugins when stage is build-stage 1`] = ` +Object { + "plugins": Array [ + Array [ + "/node_modules/@babel/plugin-proposal-class-properties/lib/index.js", + Object { + "loose": true, + }, + ], + "/node_modules/babel-plugin-macros/dist/index.js", + "/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js", + Array [ + "/node_modules/@babel/plugin-transform-runtime/lib/index.js", + Object { + "absoluteRuntimePath": "/packages/babel-preset-gatsby/node_modules/@babel/runtime", + "corejs": false, + "helpers": false, + "regenerator": true, + "useESModules": true, + }, + ], + Array [ + "/node_modules/@babel/plugin-transform-spread/lib/index.js", + Object { + "loose": false, + }, + ], + "/node_modules/babel-plugin-dynamic-import-node/lib/index.js", + ], + "presets": Array [ + Array [ + "/node_modules/@babel/preset-env/lib/index.js", + Object { + "corejs": 2, + "exclude": Array [ + "transform-typeof-symbol", + ], + "loose": true, + "modules": false, + "targets": undefined, + "useBuiltIns": "usage", + }, + ], + Array [ + "/node_modules/@babel/preset-react/lib/index.js", + Object { + "development": false, + "pragma": "React.createElement", + "useBuiltIns": true, + }, + ], + ], +} +`; + +exports[`babel-preset-gatsby should specify proper presets and plugins when stage is develop 1`] = ` +Object { + "plugins": Array [ + Array [ + "/node_modules/@babel/plugin-proposal-class-properties/lib/index.js", + Object { + "loose": true, + }, + ], + "/node_modules/babel-plugin-macros/dist/index.js", + "/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js", + Array [ + "/node_modules/@babel/plugin-transform-runtime/lib/index.js", + Object { + "absoluteRuntimePath": "/packages/babel-preset-gatsby/node_modules/@babel/runtime", + "corejs": false, + "helpers": true, + "regenerator": true, + "useESModules": true, + }, + ], + Array [ + "/node_modules/@babel/plugin-transform-spread/lib/index.js", + Object { + "loose": false, + }, + ], + "/node_modules/babel-plugin-dynamic-import-node/lib/index.js", + ], + "presets": Array [ + Array [ + "/node_modules/@babel/preset-env/lib/index.js", + Object { + "corejs": 2, + "exclude": Array [ + "transform-typeof-symbol", + ], + "loose": true, + "modules": false, + "targets": undefined, + "useBuiltIns": "usage", + }, + ], + Array [ + "/node_modules/@babel/preset-react/lib/index.js", + Object { + "development": true, + "pragma": "React.createElement", + "useBuiltIns": true, + }, + ], + ], +} +`; diff --git a/packages/babel-preset-gatsby/src/__tests__/dependencies.js b/packages/babel-preset-gatsby/src/__tests__/dependencies.js new file mode 100644 index 0000000000000..5998906740ee5 --- /dev/null +++ b/packages/babel-preset-gatsby/src/__tests__/dependencies.js @@ -0,0 +1,7 @@ +const preset = require(`../dependencies`) + +describe(`dependencies`, () => { + it(`should specify proper presets and plugins`, () => { + expect(preset()).toMatchSnapshot() + }) +}) diff --git a/packages/babel-preset-gatsby/src/__tests__/index.js b/packages/babel-preset-gatsby/src/__tests__/index.js index 6612a07120559..09355fabb94f4 100644 --- a/packages/babel-preset-gatsby/src/__tests__/index.js +++ b/packages/babel-preset-gatsby/src/__tests__/index.js @@ -1,79 +1,22 @@ const preset = require(`../`) const path = require(`path`) -it(`Specifies proper presets and plugins for test stage`, () => { - const { presets, plugins } = preset() - - expect(presets).toEqual([ - [ - expect.stringContaining(path.join(`@babel`, `preset-env`)), - { - exclude: [`transform-typeof-symbol`], - corejs: 2, - loose: true, - modules: `commonjs`, - useBuiltIns: `usage`, - targets: { - node: `current`, - }, - }, - ], - [ - expect.stringContaining(path.join(`@babel`, `preset-react`)), - { - development: false, - pragma: `React.createElement`, - useBuiltIns: true, - }, - ], - ]) - expect(plugins).toEqual([ - [ - expect.stringContaining( - path.join(`@babel`, `plugin-proposal-class-properties`) - ), - { loose: true }, - ], - expect.stringContaining(`babel-plugin-macros`), - expect.stringContaining( - path.join(`@babel`, `plugin-syntax-dynamic-import`) - ), - [ - expect.stringContaining(path.join(`@babel`, `plugin-transform-runtime`)), - { - absoluteRuntimePath: expect.stringContaining( - path.join(`@babel`, `runtime`) - ), - corejs: false, - helpers: true, - regenerator: true, - useESModules: false, - }, - ], - [ - expect.stringContaining(path.join(`@babel`, `plugin-transform-spread`)), - { - loose: false, - }, - ], - expect.stringContaining(`babel-plugin-dynamic-import-node`), - ]) -}) - -it(`Specifies proper presets and plugins for build-html stage`, () => { - const currentGatsbyBuildStage = process.env.GATSBY_BUILD_STAGE - let presets, plugins - try { - process.env.GATSBY_BUILD_STAGE = `build-html` - const config = preset() - presets = config.presets - plugins = config.plugins - } finally { - process.env.GATSBY_BUILD_STAGE = currentGatsbyBuildStage - } +describe(`babel-preset-gatsby`, () => { + it.each([`build-stage`, `develop`, `build-javascript`, `build-html`])( + `should specify proper presets and plugins when stage is %s`, + stage => { + expect(preset(null, { stage })).toMatchSnapshot() + } + ) + + it(`Allows to configure browser targets`, () => { + const targets = `last 1 version` + const { presets } = preset(null, { + stage: `build-javascript`, + targets, + }) - expect(presets).toEqual([ - [ + expect(presets[0]).toEqual([ expect.stringContaining(path.join(`@babel`, `preset-env`)), { exclude: [`transform-typeof-symbol`], @@ -81,89 +24,8 @@ it(`Specifies proper presets and plugins for build-html stage`, () => { loose: true, modules: false, useBuiltIns: `usage`, - targets: { - node: `current`, - }, - }, - ], - [ - expect.stringContaining(path.join(`@babel`, `preset-react`)), - { - development: false, - pragma: `React.createElement`, - useBuiltIns: true, - }, - ], - ]) - expect(plugins).toEqual([ - [ - expect.stringContaining( - path.join(`@babel`, `plugin-proposal-class-properties`) - ), - { loose: true }, - ], - expect.stringContaining(`babel-plugin-macros`), - expect.stringContaining( - path.join(`@babel`, `plugin-syntax-dynamic-import`) - ), - [ - expect.stringContaining(path.join(`@babel`, `plugin-transform-runtime`)), - { - absoluteRuntimePath: expect.stringContaining( - path.join(`@babel`, `runtime`) - ), - helpers: false, - regenerator: true, - corejs: false, - useESModules: true, - }, - ], - [ - expect.stringContaining(path.join(`@babel`, `plugin-transform-spread`)), - { - loose: false, + targets, }, - ], - expect.stringContaining(`babel-plugin-dynamic-import-node`), - ]) -}) - -it(`Allows to configure browser targets`, () => { - const targets = `last 1 version` - const { presets } = preset(null, { - targets, - }) - - expect(presets[0]).toEqual([ - expect.stringContaining(path.join(`@babel`, `preset-env`)), - { - exclude: [`transform-typeof-symbol`], - corejs: 2, - loose: true, - modules: false, - useBuiltIns: `usage`, - targets, - }, - ]) -}) - -describe(`in production mode`, () => { - it(`adds babel-plugin-transform-react-remove-prop-types`, () => { - process.env.GATSBY_BUILD_STAGE = `build-javascript` - - const { plugins } = preset() - - expect(plugins).toEqual( - expect.arrayContaining([ - [ - expect.stringContaining( - path.join(`babel-plugin-transform-react-remove-prop-types`) - ), - { - removeImport: true, - }, - ], - ]) - ) + ]) }) }) diff --git a/packages/babel-preset-gatsby/src/index.js b/packages/babel-preset-gatsby/src/index.js index a6cddf6d016a0..686b922088165 100644 --- a/packages/babel-preset-gatsby/src/index.js +++ b/packages/babel-preset-gatsby/src/index.js @@ -29,8 +29,9 @@ const loadCachedConfig = () => { module.exports = function preset(_, options = {}) { let { targets = null } = options + // TODO(v3): Remove process.env.GATSBY_BUILD_STAGE, needs to be passed as an option + const stage = options.stage || process.env.GATSBY_BUILD_STAGE || `test` const pluginBabelConfig = loadCachedConfig() - const stage = process.env.GATSBY_BUILD_STAGE || `test` const absoluteRuntimePath = path.dirname( require.resolve(`@babel/runtime/package.json`) ) diff --git a/packages/gatsby/src/redux/__tests__/__snapshots__/babelrc.js.snap b/packages/gatsby/src/redux/__tests__/__snapshots__/babelrc.js.snap index b5e94554957f9..44104845c5858 100644 --- a/packages/gatsby/src/redux/__tests__/__snapshots__/babelrc.js.snap +++ b/packages/gatsby/src/redux/__tests__/__snapshots__/babelrc.js.snap @@ -159,7 +159,7 @@ exports[`Babelrc actions/reducer sets default presets/plugins if there's no user Array [ Array [ Array [ - "/path/to/module/babel-plugin-remove-graphql-queries", + "/packages/babel-plugin-remove-graphql-queries/index.js", ], Object { "type": "plugin", @@ -167,7 +167,10 @@ Array [ ], Array [ Array [ - "/path/to/module/babel-preset-gatsby", + "/packages/babel-preset-gatsby/index.js", + Object { + "stage": "test", + }, ], Object { "type": "preset", diff --git a/packages/gatsby/src/redux/__tests__/babelrc.js b/packages/gatsby/src/redux/__tests__/babelrc.js index f9761a2513a0a..da19f8ba6f5cd 100644 --- a/packages/gatsby/src/redux/__tests__/babelrc.js +++ b/packages/gatsby/src/redux/__tests__/babelrc.js @@ -78,7 +78,7 @@ describe(`Babelrc actions/reducer`, () => { const fakeResolver = moduleName => `/path/to/module/${moduleName}` const babel = { createConfigItem: jest.fn() } - prepareOptions(babel, fakeResolver) + prepareOptions(babel, { stage: `test` }, fakeResolver) expect(babel.createConfigItem.mock.calls).toMatchSnapshot() }) diff --git a/packages/gatsby/src/utils/__tests__/__snapshots__/webpack-utils.js.snap b/packages/gatsby/src/utils/__tests__/__snapshots__/webpack-utils.js.snap index ea89eecf03346..765484e1e2b74 100644 --- a/packages/gatsby/src/utils/__tests__/__snapshots__/webpack-utils.js.snap +++ b/packages/gatsby/src/utils/__tests__/__snapshots__/webpack-utils.js.snap @@ -7,18 +7,13 @@ Object { "type": "javascript/auto", "use": Array [ Object { - "loader": "/packages/gatsby/src/utils/babel-loader.js", + "loader": "/node_modules/babel-loader/lib/index.js", "options": Object { "babelrc": false, - "compact": false, + "cacheIdentifier": "gatsby-dependencies@1.0.0", "configFile": false, "presets": Array [ - Array [ - "/packages/babel-preset-gatsby/dependencies.js", - Object { - "stage": "develop", - }, - ], + "/packages/babel-preset-gatsby/dependencies.js", ], "sourceMaps": false, }, @@ -35,7 +30,11 @@ Object { "use": Array [ Object { "loader": "/packages/gatsby/src/utils/babel-loader.js", - "options": Object {}, + "options": Object { + "compact": true, + "configFile": false, + "stage": "develop", + }, }, ], } diff --git a/packages/gatsby/src/utils/__tests__/webpack-utils.js b/packages/gatsby/src/utils/__tests__/webpack-utils.js index 9fa0fc1d76091..0d059fa96cc89 100644 --- a/packages/gatsby/src/utils/__tests__/webpack-utils.js +++ b/packages/gatsby/src/utils/__tests__/webpack-utils.js @@ -1,5 +1,11 @@ const utils = require(`../webpack-utils`) +jest.mock(`babel-preset-gatsby/package.json`, () => { + return { + version: `1.0.0`, + } +}) + let config beforeAll(async () => { config = await utils({ diff --git a/packages/gatsby/src/utils/babel-loader-helpers.js b/packages/gatsby/src/utils/babel-loader-helpers.js index 8d7b9ea837494..143d63cf6b04c 100644 --- a/packages/gatsby/src/utils/babel-loader-helpers.js +++ b/packages/gatsby/src/utils/babel-loader-helpers.js @@ -16,16 +16,15 @@ const loadCachedConfig = () => { return pluginBabelConfig } -const getCustomOptions = () => { +const getCustomOptions = stage => { const pluginBabelConfig = loadCachedConfig() - const stage = process.env.GATSBY_BUILD_STAGE || `test` return pluginBabelConfig.stages[stage].options } -const prepareOptions = (babel, resolve = require.resolve) => { +const prepareOptions = (babel, options = {}, resolve = require.resolve) => { let pluginBabelConfig = loadCachedConfig() - const stage = process.env.GATSBY_BUILD_STAGE || `test` + const { stage } = options // Required plugins/presets const requiredPlugins = [ @@ -56,16 +55,26 @@ const prepareOptions = (babel, resolve = require.resolve) => { const fallbackPresets = [] fallbackPresets.push( - babel.createConfigItem([resolve(`babel-preset-gatsby`)], { - type: `preset`, - }) + babel.createConfigItem( + [ + resolve(`babel-preset-gatsby`), + { + stage, + }, + ], + { + type: `preset`, + } + ) ) + // Go through babel state and create config items for presets/plugins from. const reduxPlugins = [] const reduxPresets = [] pluginBabelConfig.stages[stage].plugins.forEach(plugin => { reduxPlugins.push( babel.createConfigItem([resolve(plugin.name), plugin.options], { + name: plugin.name, type: `plugin`, }) ) @@ -73,6 +82,7 @@ const prepareOptions = (babel, resolve = require.resolve) => { pluginBabelConfig.stages[stage].presets.forEach(preset => { reduxPresets.push( babel.createConfigItem([resolve(preset.name), preset.options], { + name: preset.name, type: `preset`, }) ) diff --git a/packages/gatsby/src/utils/babel-loader.js b/packages/gatsby/src/utils/babel-loader.js index b3a646363cd0a..3f5ad3c05e18c 100644 --- a/packages/gatsby/src/utils/babel-loader.js +++ b/packages/gatsby/src/utils/babel-loader.js @@ -24,19 +24,22 @@ const { module.exports = babelLoader.custom(babel => { const toReturn = { // Passed the loader options. - customOptions(options) { + customOptions({ stage = `test`, ...options }) { return { + custom: { + stage, + }, loader: { cacheDirectory: true, sourceType: `unambiguous`, - ...getCustomOptions(), + ...getCustomOptions(stage), ...options, }, } }, // Passed Babel's 'PartialConfig' object. - config(partialConfig) { + config(partialConfig, { customOptions }) { let { options } = partialConfig const [ reduxPresets, @@ -44,7 +47,7 @@ module.exports = babelLoader.custom(babel => { requiredPresets, requiredPlugins, fallbackPresets, - ] = prepareOptions(babel) + ] = prepareOptions(babel, customOptions) // If there is no filesystem babel config present, add our fallback // presets/plugins. diff --git a/packages/gatsby/src/utils/webpack-utils.js b/packages/gatsby/src/utils/webpack-utils.js index a0a1ae8299acb..8fffbca7dc3b5 100644 --- a/packages/gatsby/src/utils/webpack-utils.js +++ b/packages/gatsby/src/utils/webpack-utils.js @@ -62,6 +62,7 @@ export type LoaderUtils = { file: LoaderResolver<*>, url: LoaderResolver<*>, js: LoaderResolver<*>, + dependencies: LoaderResovler<*>, miniCssExtract: LoaderResolver<*>, imports: LoaderResolver<*>, @@ -255,11 +256,21 @@ module.exports = async ({ js: options => { return { - options, + options: { + stage, + ...options, + }, loader: require.resolve(`./babel-loader`), } }, + dependencies: options => { + return { + options, + loader: require.resolve(`babel-loader`), + } + }, + eslint: (schema = ``) => { const options = eslintConfig(schema) @@ -312,7 +323,13 @@ module.exports = async ({ ) }, type: `javascript/auto`, - use: [loaders.js(options)], + use: [ + loaders.js({ + ...options, + configFile: false, + compact: true, + }), + ], } } @@ -326,20 +343,21 @@ module.exports = async ({ */ { let dependencies = ( - { modulesThatUseGatsby, ...options } = { modulesThatUseGatsby: [] } + { modulesThatUseGatsby } = { modulesThatUseGatsby: [] } ) => { const jsOptions = { babelrc: false, configFile: false, compact: false, - presets: [ - [require.resolve(`babel-preset-gatsby/dependencies`), { stage }], - ], + presets: [require.resolve(`babel-preset-gatsby/dependencies`)], // 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, + cacheIdentifier: `${stage}---gatsby-dependencies@${ + require(`babel-preset-gatsby/package.json`).version + }`, } return { @@ -367,7 +385,7 @@ module.exports = async ({ return true }, type: `javascript/auto`, - use: [loaders.js(jsOptions)], + use: [loaders.dependencies(jsOptions)], } }