diff --git a/packages/babel-preset-gatsby/src/__tests__/index.js b/packages/babel-preset-gatsby/src/__tests__/index.js index 407cf86d6e852..850c68d9c9502 100644 --- a/packages/babel-preset-gatsby/src/__tests__/index.js +++ b/packages/babel-preset-gatsby/src/__tests__/index.js @@ -101,8 +101,9 @@ it(`Specifies proper presets and plugins for build-html stage`, () => { }) it(`Allows to configure browser targets`, () => { + const targets = `last 1 version` const { presets } = preset(null, { - targets: { browsers: [`last 1 version`] }, + targets, }) expect(presets[0]).toEqual([ @@ -111,9 +112,7 @@ it(`Allows to configure browser targets`, () => { loose: true, modules: false, useBuiltIns: `usage`, - targets: { - browsers: [`last 1 version`], - }, + targets, }, ]) }) diff --git a/packages/babel-preset-gatsby/src/index.js b/packages/babel-preset-gatsby/src/index.js index 0877ad29401c5..3b69a0974c5ae 100644 --- a/packages/babel-preset-gatsby/src/index.js +++ b/packages/babel-preset-gatsby/src/index.js @@ -1,6 +1,6 @@ const path = require(`path`) -const r = m => require.resolve(m) +const resolve = m => require.resolve(m) const loadCachedConfig = () => { let pluginBabelConfig = {} @@ -13,7 +13,7 @@ const loadCachedConfig = () => { return pluginBabelConfig } -function preset(context, options = {}) { +module.exports = function preset(_, options = {}) { let { targets = null } = options const pluginBabelConfig = loadCachedConfig() @@ -25,16 +25,14 @@ function preset(context, options = {}) { node: `current`, } } else { - targets = { - browsers: pluginBabelConfig.browserslist, - } + targets = pluginBabelConfig.browserslist } } return { presets: [ [ - r(`@babel/preset-env`), + resolve(`@babel/preset-env`), { loose: true, modules: stage === `test` ? `commonjs` : false, @@ -43,7 +41,7 @@ function preset(context, options = {}) { }, ], [ - r(`@babel/preset-react`), + resolve(`@babel/preset-react`), { useBuiltIns: true, pragma: `React.createElement`, @@ -53,15 +51,15 @@ function preset(context, options = {}) { ], plugins: [ [ - r(`@babel/plugin-proposal-class-properties`), + resolve(`@babel/plugin-proposal-class-properties`), { loose: true, }, ], - r(`babel-plugin-macros`), - r(`@babel/plugin-syntax-dynamic-import`), + resolve(`babel-plugin-macros`), + resolve(`@babel/plugin-syntax-dynamic-import`), [ - r(`@babel/plugin-transform-runtime`), + resolve(`@babel/plugin-transform-runtime`), { helpers: true, regenerator: true, @@ -70,5 +68,3 @@ function preset(context, options = {}) { ], } } - -module.exports = preset diff --git a/packages/gatsby/src/bootstrap/index.js b/packages/gatsby/src/bootstrap/index.js index 08b5393150eb2..e60ce6796ec5f 100644 --- a/packages/gatsby/src/bootstrap/index.js +++ b/packages/gatsby/src/bootstrap/index.js @@ -12,6 +12,7 @@ const Promise = require(`bluebird`) const apiRunnerNode = require(`../utils/api-runner-node`) const mergeGatsbyConfig = require(`../utils/merge-gatsby-config`) +const getBrowserslist = require(`../utils/browserslist`) const { graphql } = require(`graphql`) const { store, emitter } = require(`../redux`) const loadPlugins = require(`./load-plugins`) @@ -56,10 +57,13 @@ module.exports = async (args: BootstrapArgs) => { // and invokes Gatsby API based on actions. require(`../redux/plugin-runner`) + const directory = slash(args.directory) + const program = { ...args, + browserslist: getBrowserslist(directory), // Fix program directory path for windows env. - directory: slash(args.directory), + directory, } store.dispatch({ diff --git a/packages/gatsby/src/commands/build.js b/packages/gatsby/src/commands/build.js index 3ed36006c0df9..6c69c009a85d4 100644 --- a/packages/gatsby/src/commands/build.js +++ b/packages/gatsby/src/commands/build.js @@ -17,7 +17,6 @@ function reportFailure(msg, err: Error) { type BuildArgs = { directory: string, sitePackageJson: object, - browserslist: string[], prefixPaths: boolean, noUglify: boolean, openTracingConfigFile: string, diff --git a/packages/gatsby/src/internal-plugins/load-babel-config/gatsby-node.js b/packages/gatsby/src/internal-plugins/load-babel-config/gatsby-node.js index 6a6af7af6d9e9..5f0cf62307ef6 100644 --- a/packages/gatsby/src/internal-plugins/load-babel-config/gatsby-node.js +++ b/packages/gatsby/src/internal-plugins/load-babel-config/gatsby-node.js @@ -21,8 +21,15 @@ exports.onPreBootstrap = async ({ store }) => { await apiRunnerNode(`onCreateBabelConfig`, { stage: `build-html`, }) - const babelrcState = store.getState().babelrc - babelrcState.browserslist = browserslist - const babelState = JSON.stringify(babelrcState.stages, null, 4) + + const babelState = JSON.stringify( + { + ...store.getState().babelrc, + browserslist, + }, + null, + 2 + ) + await fs.writeFile(directoryPath(`.cache/babelState.json`), babelState) } diff --git a/packages/gatsby/src/utils/__tests__/browserslist.js b/packages/gatsby/src/utils/__tests__/browserslist.js new file mode 100644 index 0000000000000..f0f794516bee5 --- /dev/null +++ b/packages/gatsby/src/utils/__tests__/browserslist.js @@ -0,0 +1,31 @@ +jest.mock(`browserslist/node`, () => { + return { + findConfig: jest.fn(), + } +}) +const path = require(`path`) +const getBrowsersList = require(`../browserslist`) +const { findConfig: mockedFindConfig } = require(`browserslist/node`) + +const BASE = path.resolve(`.`) + +describe(`browserslist`, () => { + it(`prefers returned browserslist results`, () => { + const defaults = [`IE 11`] + mockedFindConfig.mockReturnValueOnce({ + defaults, + }) + + const list = getBrowsersList(BASE) + + expect(list).toEqual(defaults) + }) + + it(`falls back to defaults`, () => { + mockedFindConfig.mockReturnValueOnce(undefined) + + const list = getBrowsersList(BASE) + + expect(list).toEqual([`>0.25%`, `not dead`]) + }) +}) diff --git a/packages/gatsby/src/utils/babel-loader-helpers.js b/packages/gatsby/src/utils/babel-loader-helpers.js index 4ce5b6b3c98c3..8d7b9ea837494 100644 --- a/packages/gatsby/src/utils/babel-loader-helpers.js +++ b/packages/gatsby/src/utils/babel-loader-helpers.js @@ -2,7 +2,11 @@ const path = require(`path`) const _ = require(`lodash`) const loadCachedConfig = () => { - let pluginBabelConfig = { test: { plugins: [], presets: [] } } + let pluginBabelConfig = { + stages: { + test: { plugins: [], presets: [] }, + }, + } if (process.env.NODE_ENV !== `test`) { pluginBabelConfig = require(path.join( process.cwd(), @@ -15,7 +19,7 @@ const loadCachedConfig = () => { const getCustomOptions = () => { const pluginBabelConfig = loadCachedConfig() const stage = process.env.GATSBY_BUILD_STAGE || `test` - return pluginBabelConfig[stage].options + return pluginBabelConfig.stages[stage].options } const prepareOptions = (babel, resolve = require.resolve) => { @@ -59,14 +63,14 @@ const prepareOptions = (babel, resolve = require.resolve) => { // Go through babel state and create config items for presets/plugins from. const reduxPlugins = [] const reduxPresets = [] - pluginBabelConfig[stage].plugins.forEach(plugin => { + pluginBabelConfig.stages[stage].plugins.forEach(plugin => { reduxPlugins.push( babel.createConfigItem([resolve(plugin.name), plugin.options], { type: `plugin`, }) ) }) - pluginBabelConfig[stage].presets.forEach(preset => { + pluginBabelConfig.stages[stage].presets.forEach(preset => { reduxPresets.push( babel.createConfigItem([resolve(preset.name), preset.options], { type: `preset`, diff --git a/packages/gatsby/src/utils/browserslist.js b/packages/gatsby/src/utils/browserslist.js new file mode 100644 index 0000000000000..590acc73d39aa --- /dev/null +++ b/packages/gatsby/src/utils/browserslist.js @@ -0,0 +1,31 @@ +const path = require(`path`) +const browserslist = require(`browserslist/node`) + +function installedGatsbyVersion(directory) { + try { + const { version } = require(path.join( + directory, + `node_modules`, + `gatsby`, + `package.json` + )) + return parseInt(version.split(`.`)[0], 10) + } catch (e) { + return undefined + } +} + +module.exports = function getBrowsersList(directory) { + const fallback = + installedGatsbyVersion(directory) === 1 + ? [`>1%`, `last 2 versions`, `IE >= 9`] + : [`>0.25%`, `not dead`] + + const config = browserslist.findConfig(directory) + + if (config && config.defaults) { + return config.defaults + } + + return fallback +}