From 08e7f9df73e6e43eabb9a79f8ea724555adce04f Mon Sep 17 00:00:00 2001 From: Francesco Agnoletto Date: Thu, 18 Jun 2020 17:09:48 +0200 Subject: [PATCH 1/8] Add types --- packages/gatsby/package.json | 1 + packages/gatsby/src/redux/types.ts | 6 +- ...der-helpers.js => babel-loader-helpers.ts} | 68 ++++++++++++++----- 3 files changed, 55 insertions(+), 20 deletions(-) rename packages/gatsby/src/utils/{babel-loader-helpers.js => babel-loader-helpers.ts} (66%) diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index b97aeae94b78d..a688578bd4921 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -156,6 +156,7 @@ "devDependencies": { "@babel/cli": "^7.10.1", "@babel/runtime": "^7.10.2", + "@types/babel-core": "^6.25.6", "@types/hapi__joi": "^16.0.12", "@types/reach__router": "^1.3.5", "@types/semver": "^7.1.0", diff --git a/packages/gatsby/src/redux/types.ts b/packages/gatsby/src/redux/types.ts index 65944d9b8fedb..8f518389263a9 100644 --- a/packages/gatsby/src/redux/types.ts +++ b/packages/gatsby/src/redux/types.ts @@ -120,17 +120,17 @@ export interface IPlugin { options: Record } -interface IBabelStage { +export interface IBabelStage { plugins: IPlugin[] presets: IPlugin[] - options: { + options?: { cacheDirectory: boolean sourceType: string sourceMaps?: string } } -type BabelStageKeys = +export type BabelStageKeys = | "develop" | "develop-html" | "build-html" diff --git a/packages/gatsby/src/utils/babel-loader-helpers.js b/packages/gatsby/src/utils/babel-loader-helpers.ts similarity index 66% rename from packages/gatsby/src/utils/babel-loader-helpers.js rename to packages/gatsby/src/utils/babel-loader-helpers.ts index 5e4a45516d7ce..f94dadd05ae8e 100644 --- a/packages/gatsby/src/utils/babel-loader-helpers.js +++ b/packages/gatsby/src/utils/babel-loader-helpers.ts @@ -1,7 +1,20 @@ -const path = require(`path`) -const _ = require(`lodash`) +import path from "path" +import _ from "lodash" +import Babel, { + ConfigItem, + PluginItem, + CreateConfigItemOptions, +} from "@babel/core" + +import { IBabelStage, BabelStageKeys } from "../redux/types" + +interface ILoadCachedConfigReturnType { + stages: { + test: IBabelStage + } +} -const loadCachedConfig = () => { +const loadCachedConfig = (): ILoadCachedConfigReturnType => { let pluginBabelConfig = { stages: { test: { plugins: [], presets: [] }, @@ -16,13 +29,23 @@ const loadCachedConfig = () => { return pluginBabelConfig } -const getCustomOptions = stage => { +export const getCustomOptions = (stage: string): IBabelStage["options"] => { const pluginBabelConfig = loadCachedConfig() return pluginBabelConfig.stages[stage].options } -const prepareOptions = (babel, options = {}, resolve = require.resolve) => { - let pluginBabelConfig = loadCachedConfig() +type prepareOptionsType = ( + babel: typeof Babel, + options?: { stage?: BabelStageKeys }, + resolve?: RequireResolve +) => Array + +export const prepareOptions: prepareOptionsType = ( + babel, + options = {}, + resolve = require.resolve +) => { + const pluginBabelConfig = loadCachedConfig() const { stage } = options @@ -32,7 +55,7 @@ const prepareOptions = (babel, options = {}, resolve = require.resolve) => { type: `plugin`, }), ] - const requiredPresets = [] + const requiredPresets: PluginItem[] = [] // Stage specific plugins to add if (stage === `build-html` || stage === `develop-html`) { @@ -53,7 +76,7 @@ const prepareOptions = (babel, options = {}, resolve = require.resolve) => { } // Fallback preset - const fallbackPresets = [] + const fallbackPresets: ConfigItem[] = [] fallbackPresets.push( babel.createConfigItem( @@ -70,8 +93,8 @@ const prepareOptions = (babel, options = {}, resolve = require.resolve) => { ) // Go through babel state and create config items for presets/plugins from. - const reduxPlugins = [] - const reduxPresets = [] + const reduxPlugins: PluginItem[] = [] + const reduxPresets: PluginItem[] = [] pluginBabelConfig.stages[stage].plugins.forEach(plugin => { reduxPlugins.push( babel.createConfigItem([resolve(plugin.name), plugin.options], { @@ -98,7 +121,24 @@ const prepareOptions = (babel, options = {}, resolve = require.resolve) => { ] } -const mergeConfigItemOptions = ({ items, itemToMerge, type, babel }) => { +type mergeConfigItemOptionsType = ({ + items, + itemToMerge, + type, + babel, +}: { + items: ConfigItem[] + itemToMerge: ConfigItem + type: CreateConfigItemOptions["type"] + babel: typeof Babel +}) => ConfigItem[] + +export const mergeConfigItemOptions: mergeConfigItemOptionsType = ({ + items, + itemToMerge, + type, + babel, +}) => { const index = _.findIndex( items, i => i.file.resolved === itemToMerge.file.resolved @@ -121,9 +161,3 @@ const mergeConfigItemOptions = ({ items, itemToMerge, type, babel }) => { return items } - -exports.getCustomOptions = getCustomOptions - -// Export helper functions for testing -exports.prepareOptions = prepareOptions -exports.mergeConfigItemOptions = mergeConfigItemOptions From 94960133c59770ae89c20efb04ff3b5f3d3d8a45 Mon Sep 17 00:00:00 2001 From: Francesco Agnoletto Date: Thu, 18 Jun 2020 17:09:59 +0200 Subject: [PATCH 2/8] Fix imports --- packages/gatsby/src/utils/babel-loader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/gatsby/src/utils/babel-loader.js b/packages/gatsby/src/utils/babel-loader.js index 3f5ad3c05e18c..47c969f982b23 100644 --- a/packages/gatsby/src/utils/babel-loader.js +++ b/packages/gatsby/src/utils/babel-loader.js @@ -1,10 +1,10 @@ const babelLoader = require(`babel-loader`) -const { +import { prepareOptions, getCustomOptions, mergeConfigItemOptions, -} = require(`./babel-loader-helpers`) +} from "./babel-loader-helpers" /** * Gatsby's custom loader for webpack & babel From 8370a90af2f16a4940850916a1e987954f4429ce Mon Sep 17 00:00:00 2001 From: Francesco Agnoletto Date: Thu, 18 Jun 2020 17:11:22 +0200 Subject: [PATCH 3/8] Add non-null assertion --- packages/gatsby/src/utils/babel-loader-helpers.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/gatsby/src/utils/babel-loader-helpers.ts b/packages/gatsby/src/utils/babel-loader-helpers.ts index f94dadd05ae8e..2dc7d983dba01 100644 --- a/packages/gatsby/src/utils/babel-loader-helpers.ts +++ b/packages/gatsby/src/utils/babel-loader-helpers.ts @@ -95,7 +95,7 @@ export const prepareOptions: prepareOptionsType = ( // Go through babel state and create config items for presets/plugins from. const reduxPlugins: PluginItem[] = [] const reduxPresets: PluginItem[] = [] - pluginBabelConfig.stages[stage].plugins.forEach(plugin => { + pluginBabelConfig.stages[stage!].plugins.forEach(plugin => { reduxPlugins.push( babel.createConfigItem([resolve(plugin.name), plugin.options], { name: plugin.name, @@ -103,7 +103,7 @@ export const prepareOptions: prepareOptionsType = ( }) ) }) - pluginBabelConfig.stages[stage].presets.forEach(preset => { + pluginBabelConfig.stages[stage!].presets.forEach(preset => { reduxPresets.push( babel.createConfigItem([resolve(preset.name), preset.options], { name: preset.name, @@ -141,14 +141,14 @@ export const mergeConfigItemOptions: mergeConfigItemOptionsType = ({ }) => { const index = _.findIndex( items, - i => i.file.resolved === itemToMerge.file.resolved + i => i.file!.resolved === itemToMerge.file!.resolved ) // If this exist, merge the options, otherwise, add it to the array if (index !== -1) { items[index] = babel.createConfigItem( [ - itemToMerge.file.resolved, + itemToMerge.file!.resolved, _.merge({}, items[index].options, itemToMerge.options), ], { From fa7886f1cee8ca26f32ef569b76f2ef57bb76082 Mon Sep 17 00:00:00 2001 From: Francesco Agnoletto Date: Thu, 18 Jun 2020 22:22:36 +0200 Subject: [PATCH 4/8] Update types --- packages/gatsby/src/utils/babel-loader-helpers.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/gatsby/src/utils/babel-loader-helpers.ts b/packages/gatsby/src/utils/babel-loader-helpers.ts index 2dc7d983dba01..6469e1ce48071 100644 --- a/packages/gatsby/src/utils/babel-loader-helpers.ts +++ b/packages/gatsby/src/utils/babel-loader-helpers.ts @@ -7,6 +7,7 @@ import Babel, { } from "@babel/core" import { IBabelStage, BabelStageKeys } from "../redux/types" +import { Stage } from "../commands/types" interface ILoadCachedConfigReturnType { stages: { @@ -29,7 +30,7 @@ const loadCachedConfig = (): ILoadCachedConfigReturnType => { return pluginBabelConfig } -export const getCustomOptions = (stage: string): IBabelStage["options"] => { +export const getCustomOptions = (stage: Stage): IBabelStage["options"] => { const pluginBabelConfig = loadCachedConfig() return pluginBabelConfig.stages[stage].options } @@ -141,14 +142,14 @@ export const mergeConfigItemOptions: mergeConfigItemOptionsType = ({ }) => { const index = _.findIndex( items, - i => i.file!.resolved === itemToMerge.file!.resolved + i => i.file?.resolved === itemToMerge.file?.resolved ) // If this exist, merge the options, otherwise, add it to the array if (index !== -1) { items[index] = babel.createConfigItem( [ - itemToMerge.file!.resolved, + itemToMerge.file?.resolved, _.merge({}, items[index].options, itemToMerge.options), ], { From e4d126b49bbb410197e106ab92ec7a2468b03f11 Mon Sep 17 00:00:00 2001 From: Francesco Agnoletto Date: Thu, 18 Jun 2020 22:28:19 +0200 Subject: [PATCH 5/8] Fix test file types --- .../gatsby/src/redux/__tests__/babelrc.ts | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/packages/gatsby/src/redux/__tests__/babelrc.ts b/packages/gatsby/src/redux/__tests__/babelrc.ts index 69413460f7fa2..8874e775ed5e5 100644 --- a/packages/gatsby/src/redux/__tests__/babelrc.ts +++ b/packages/gatsby/src/redux/__tests__/babelrc.ts @@ -76,9 +76,9 @@ describe(`Babelrc actions/reducer`, () => { it(`sets default presets/plugins if there's no userland babelrc`, () => { const fakeResolver = (moduleName): string => `/path/to/module/${moduleName}` - const babel = { createConfigItem: jest.fn() } + const babel = { createConfigItem: jest.fn() } as any - prepareOptions(babel, { stage: `test` }, fakeResolver) + prepareOptions(babel, { stage: `test` as any }, fakeResolver as any) expect(babel.createConfigItem.mock.calls).toMatchSnapshot() }) @@ -89,7 +89,7 @@ describe(`Babelrc actions/reducer`, () => { { name: `test` } ) let state = babelrcReducer(undefined, action) - expect(state.stages.develop.options.sourceMaps).toBe(`inline`) + expect(state.stages.develop.options!.sourceMaps).toBe(`inline`) const updateAction = actions.setBabelOptions( { options: { sourceMaps: true } }, @@ -97,7 +97,7 @@ describe(`Babelrc actions/reducer`, () => { ) state = babelrcReducer(state, updateAction) - expect(state.stages.develop.options.sourceMaps).toBe(true) + expect(state.stages.develop.options!.sourceMaps).toBe(true) }) it(`allows setting options on a particular stage`, () => { @@ -106,16 +106,28 @@ describe(`Babelrc actions/reducer`, () => { { name: `test` } ) const state = babelrcReducer(undefined, action) - expect(state.stages.develop.options.sourceMaps).toBe(`inline`) - expect(state.stages[`develop-html`].options.sourceMaps).toBe(undefined) + expect(state.stages.develop.options!.sourceMaps).toBe(`inline`) + expect(state.stages[`develop-html`].options!.sourceMaps).toBe(undefined) }) it(`allows merging config items`, () => { - const babel = { createConfigItem: jest.fn() } + const babel = { createConfigItem: jest.fn() } as any // This merges in new change. mergeConfigItemOptions({ - items: [{ options: { wat: 1 }, file: { resolved: `hi` } }], - itemToMerge: { options: { wat: 2 }, file: { resolved: `hi` } }, + items: [ + { + value: (): null => null, + dirname: `hi`, + options: { wat: 1 }, + file: { resolved: `hi`, request: `hello` }, + }, + ], + itemToMerge: { + value: (): null => null, + dirname: `hi`, + options: { wat: 2 }, + file: { resolved: `hi`, request: `hello` }, + }, type: `plugin`, babel, }) @@ -123,8 +135,20 @@ describe(`Babelrc actions/reducer`, () => { expect( mergeConfigItemOptions({ - items: [{ options: { wat: 1 }, file: { resolved: `hi` } }], - itemToMerge: { options: { wat: 2 }, file: { resolved: `hi2` } }, + items: [ + { + value: (): null => null, + dirname: `hi`, + options: { wat: 1 }, + file: { resolved: `hi`, request: `hello` }, + }, + ], + itemToMerge: { + value: (): null => null, + dirname: `hi2`, + options: { wat: 2 }, + file: { resolved: `hi2`, request: `hello2` }, + }, type: `plugin`, babel, }) From 7264a459b4414430cac18e5967f4a0f9ef5e1e7f Mon Sep 17 00:00:00 2001 From: Francesco Agnoletto Date: Thu, 18 Jun 2020 22:28:53 +0200 Subject: [PATCH 6/8] Use proper Stage enum --- packages/gatsby/src/redux/types.ts | 16 +++++----------- .../gatsby/src/utils/babel-loader-helpers.ts | 4 ++-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/gatsby/src/redux/types.ts b/packages/gatsby/src/redux/types.ts index 8f518389263a9..5d8d789b8622a 100644 --- a/packages/gatsby/src/redux/types.ts +++ b/packages/gatsby/src/redux/types.ts @@ -1,4 +1,4 @@ -import { IProgram } from "../commands/types" +import { IProgram, Stage } from "../commands/types" import { GraphQLFieldExtensionDefinition } from "../schema/extensions" import { DocumentNode, GraphQLSchema } from "graphql" import { SchemaComposer } from "graphql-compose" @@ -130,12 +130,6 @@ export interface IBabelStage { } } -export type BabelStageKeys = - | "develop" - | "develop-html" - | "build-html" - | "build-javascript" - export interface IStateProgram extends IProgram { extensions: string[] } @@ -217,7 +211,7 @@ export interface IGatsbyState { redirects: IRedirect[] babelrc: { stages: { - [key in BabelStageKeys]: IBabelStage + [key in Stage]: IBabelStage } } schemaCustomization: { @@ -319,7 +313,7 @@ export type ActionsUnion = interface ISetBabelPluginAction { type: `SET_BABEL_PLUGIN` payload: { - stage: BabelStageKeys + stage: Stage name: IPlugin["name"] options: IPlugin["options"] } @@ -328,7 +322,7 @@ interface ISetBabelPluginAction { interface ISetBabelPresetAction { type: `SET_BABEL_PRESET` payload: { - stage: BabelStageKeys + stage: Stage name: IPlugin["name"] options: IPlugin["options"] } @@ -337,7 +331,7 @@ interface ISetBabelPresetAction { interface ISetBabelOptionsAction { type: `SET_BABEL_OPTIONS` payload: { - stage: BabelStageKeys + stage: Stage name: IPlugin["name"] options: IPlugin["options"] } diff --git a/packages/gatsby/src/utils/babel-loader-helpers.ts b/packages/gatsby/src/utils/babel-loader-helpers.ts index 6469e1ce48071..064edc9489ac7 100644 --- a/packages/gatsby/src/utils/babel-loader-helpers.ts +++ b/packages/gatsby/src/utils/babel-loader-helpers.ts @@ -6,7 +6,7 @@ import Babel, { CreateConfigItemOptions, } from "@babel/core" -import { IBabelStage, BabelStageKeys } from "../redux/types" +import { IBabelStage } from "../redux/types" import { Stage } from "../commands/types" interface ILoadCachedConfigReturnType { @@ -37,7 +37,7 @@ export const getCustomOptions = (stage: Stage): IBabelStage["options"] => { type prepareOptionsType = ( babel: typeof Babel, - options?: { stage?: BabelStageKeys }, + options?: { stage?: Stage }, resolve?: RequireResolve ) => Array From bfc2b6a1997e572b59cd84384b74488f02605911 Mon Sep 17 00:00:00 2001 From: Francesco Agnoletto Date: Thu, 18 Jun 2020 22:32:13 +0200 Subject: [PATCH 7/8] Update snaps --- .../src/redux/__tests__/__snapshots__/babelrc.ts.snap | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/gatsby/src/redux/__tests__/__snapshots__/babelrc.ts.snap b/packages/gatsby/src/redux/__tests__/__snapshots__/babelrc.ts.snap index 5d666619c69cf..bdf06c2c3ba07 100644 --- a/packages/gatsby/src/redux/__tests__/__snapshots__/babelrc.ts.snap +++ b/packages/gatsby/src/redux/__tests__/__snapshots__/babelrc.ts.snap @@ -137,20 +137,26 @@ Array [ exports[`Babelrc actions/reducer allows merging config items 2`] = ` Array [ Object { + "dirname": "hi", "file": Object { + "request": "hello", "resolved": "hi", }, "options": Object { "wat": 1, }, + "value": [Function], }, Object { + "dirname": "hi2", "file": Object { + "request": "hello2", "resolved": "hi2", }, "options": Object { "wat": 2, }, + "value": [Function], }, ] `; From 36a13d7fd644c2e24eb0aa2b494b3b7602d37622 Mon Sep 17 00:00:00 2001 From: Francesco Agnoletto Date: Fri, 19 Jun 2020 18:50:23 +0200 Subject: [PATCH 8/8] Address feedback --- .../gatsby/src/utils/babel-loader-helpers.ts | 60 ++++++++----------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/packages/gatsby/src/utils/babel-loader-helpers.ts b/packages/gatsby/src/utils/babel-loader-helpers.ts index 064edc9489ac7..3ae1446bb424f 100644 --- a/packages/gatsby/src/utils/babel-loader-helpers.ts +++ b/packages/gatsby/src/utils/babel-loader-helpers.ts @@ -35,17 +35,11 @@ export const getCustomOptions = (stage: Stage): IBabelStage["options"] => { return pluginBabelConfig.stages[stage].options } -type prepareOptionsType = ( +export const prepareOptions = ( babel: typeof Babel, - options?: { stage?: Stage }, - resolve?: RequireResolve -) => Array - -export const prepareOptions: prepareOptionsType = ( - babel, - options = {}, - resolve = require.resolve -) => { + options: { stage?: Stage } = {}, + resolve: RequireResolve = require.resolve +): Array => { const pluginBabelConfig = loadCachedConfig() const { stage } = options @@ -96,22 +90,25 @@ export const prepareOptions: prepareOptionsType = ( // Go through babel state and create config items for presets/plugins from. const reduxPlugins: PluginItem[] = [] const reduxPresets: PluginItem[] = [] - pluginBabelConfig.stages[stage!].plugins.forEach(plugin => { - reduxPlugins.push( - babel.createConfigItem([resolve(plugin.name), plugin.options], { - name: plugin.name, - type: `plugin`, - }) - ) - }) - pluginBabelConfig.stages[stage!].presets.forEach(preset => { - reduxPresets.push( - babel.createConfigItem([resolve(preset.name), preset.options], { - name: preset.name, - type: `preset`, - }) - ) - }) + + if (stage) { + pluginBabelConfig.stages[stage].plugins.forEach(plugin => { + reduxPlugins.push( + babel.createConfigItem([resolve(plugin.name), plugin.options], { + name: plugin.name, + type: `plugin`, + }) + ) + }) + pluginBabelConfig.stages[stage].presets.forEach(preset => { + reduxPresets.push( + babel.createConfigItem([resolve(preset.name), preset.options], { + name: preset.name, + type: `preset`, + }) + ) + }) + } return [ reduxPresets, @@ -122,7 +119,7 @@ export const prepareOptions: prepareOptionsType = ( ] } -type mergeConfigItemOptionsType = ({ +export const mergeConfigItemOptions = ({ items, itemToMerge, type, @@ -132,14 +129,7 @@ type mergeConfigItemOptionsType = ({ itemToMerge: ConfigItem type: CreateConfigItemOptions["type"] babel: typeof Babel -}) => ConfigItem[] - -export const mergeConfigItemOptions: mergeConfigItemOptionsType = ({ - items, - itemToMerge, - type, - babel, -}) => { +}): ConfigItem[] => { const index = _.findIndex( items, i => i.file?.resolved === itemToMerge.file?.resolved