Skip to content

Commit

Permalink
chore(gatsby): convert babel-loader-helpers to typescript (#36237)
Browse files Browse the repository at this point in the history
* Add types

* Fix imports

* Add non-null assertion

* Update types

* Fix test file types

* Use proper Stage enum

* Update snaps

* Address feedback

* Fix exports

* Make test change to kick off builds

Having trouble merging master in, so just making a quick change to try to trigger builds. 😄

* Revert change, tests look good

Co-authored-by: Josh Johnson <jcjohnson77@gmail.com>
Co-authored-by: Lennart <lekoarts@gmail.com>
  • Loading branch information
3 people authored Aug 3, 2022
1 parent 867d1d1 commit ee2b0aa
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 72 deletions.
1 change: 1 addition & 0 deletions packages/gatsby/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"@babel/cli": "^7.15.4",
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/register": "^7.15.3",
"@types/babel-core": "^6.25.7",
"@types/eslint": "^8.2.1",
"@types/express": "^4.17.13",
"@types/express-http-proxy": "^1.6.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,20 +153,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],
},
]
`;
Expand Down
46 changes: 35 additions & 11 deletions packages/gatsby/src/redux/__tests__/babelrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,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()
})
Expand All @@ -104,15 +104,15 @@ 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 } },
{ name: `test` }
)
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`, () => {
Expand All @@ -121,25 +121,49 @@ 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,
})
expect(babel.createConfigItem.mock.calls).toMatchSnapshot()

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,
})
Expand Down
20 changes: 7 additions & 13 deletions packages/gatsby/src/redux/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { TrailingSlash } from "gatsby-page-utils"
import { IProgram } from "../commands/types"
import { IProgram, Stage } from "../commands/types"
import { GraphQLFieldExtensionDefinition } from "../schema/extensions"
import {
DocumentNode,
Expand Down Expand Up @@ -190,25 +190,19 @@ export interface IGatsbyCompleteJobV2 {

export interface IPlugin {
name: string
options: Record<string, any>
options: Record<string, unknown>
}

export interface IBabelStage {
plugins: Array<IPlugin>
presets: Array<IPlugin>
options: {
options?: {
cacheDirectory: boolean
sourceType: string
sourceMaps?: string
}
}

type BabelStageKeys =
| "develop"
| "develop-html"
| "build-html"
| "build-javascript"

export interface IStateProgram extends IProgram {
extensions: Array<string>
browserslist: Array<string>
Expand Down Expand Up @@ -322,7 +316,7 @@ export interface IGatsbyState {
redirects: Array<IRedirect>
babelrc: {
stages: {
[key in BabelStageKeys]: IBabelStage
[key in Stage]: IBabelStage
}
}
schemaCustomization: {
Expand Down Expand Up @@ -468,7 +462,7 @@ export interface IApiFinishedAction {
interface ISetBabelPluginAction {
type: `SET_BABEL_PLUGIN`
payload: {
stage: BabelStageKeys
stage: Stage
name: IPlugin["name"]
options: IPlugin["options"]
}
Expand All @@ -477,7 +471,7 @@ interface ISetBabelPluginAction {
interface ISetBabelPresetAction {
type: `SET_BABEL_PRESET`
payload: {
stage: BabelStageKeys
stage: Stage
name: IPlugin["name"]
options: IPlugin["options"]
}
Expand All @@ -486,7 +480,7 @@ interface ISetBabelPresetAction {
interface ISetBabelOptionsAction {
type: `SET_BABEL_OPTIONS`
payload: {
stage: BabelStageKeys
stage: Stage
name: IPlugin["name"]
options: IPlugin["options"]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
const path = require(`path`)
const _ = require(`lodash`)
import path from "path"
import _ from "lodash"
import Babel, {
ConfigItem,
PluginItem,
CreateConfigItemOptions,
} from "@babel/core"

import { IBabelStage } from "../redux/types"
import { Stage } from "../commands/types"

interface ILoadCachedConfigReturnType {
stages: {
test: IBabelStage
}
}

const loadCachedConfig = () => {
const loadCachedConfig = (): ILoadCachedConfigReturnType => {
let pluginBabelConfig = {
stages: {
test: { plugins: [], presets: [] },
Expand All @@ -16,7 +30,7 @@ const loadCachedConfig = () => {
return pluginBabelConfig
}

const getCustomOptions = stage => {
export const getCustomOptions = (stage: Stage): IBabelStage["options"] => {
const pluginBabelConfig = loadCachedConfig()
return pluginBabelConfig.stages[stage].options
}
Expand All @@ -30,11 +44,15 @@ const getCustomOptions = stage => {
*/
const configItemsMemoCache = new Map()

const prepareOptions = (
babel,
customOptions = {},
resolve = require.resolve
) => {
interface ICustomOptions extends Record<string, unknown> {
stage: Stage
}

export const prepareOptions = (
babel: typeof Babel,
customOptions: ICustomOptions,
resolve: RequireResolve = require.resolve
): Array<Array<PluginItem>> => {
const {
stage,
reactRuntime,
Expand Down Expand Up @@ -94,7 +112,7 @@ const prepareOptions = (
)
}

const requiredPresets = []
const requiredPresets: Array<PluginItem> = []

// Stage specific plugins to add
if (
Expand All @@ -117,7 +135,7 @@ const prepareOptions = (
}

// Fallback preset
const fallbackPresets = []
const fallbackPresets: Array<ConfigItem> = []

fallbackPresets.push(
babel.createConfigItem(
Expand All @@ -136,24 +154,27 @@ const prepareOptions = (
)

// 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`,
})
)
})
pluginBabelConfig.stages[stage].presets.forEach(preset => {
reduxPresets.push(
babel.createConfigItem([resolve(preset.name), preset.options], {
name: preset.name,
type: `preset`,
})
)
})
const reduxPlugins: Array<PluginItem> = []
const reduxPresets: Array<PluginItem> = []

if (stage) {
pluginBabelConfig.stages[stage].plugins.forEach(plugin => {
reduxPlugins.push(
babel.createConfigItem([resolve(plugin.name), plugin.options], {
dirname: plugin.name,
type: `plugin`,
})
)
})
pluginBabelConfig.stages[stage].presets.forEach(preset => {
reduxPresets.push(
babel.createConfigItem([resolve(preset.name), preset.options], {
dirname: preset.name,
type: `preset`,
})
)
})
}

const toReturn = [
reduxPresets,
Expand All @@ -168,16 +189,18 @@ const prepareOptions = (
return toReturn
}

const addRequiredPresetOptions = (
babel,
presets,
options = {},
resolve = require.resolve
) => {
export const addRequiredPresetOptions = (
babel: typeof Babel,
presets: Array<ConfigItem>,
options: { stage?: Stage } = {},
resolve: RequireResolve = require.resolve
): Array<PluginItem> => {
// Always pass `stage` option to babel-preset-gatsby
// (even if defined in custom babelrc)
const gatsbyPresetResolved = resolve(`babel-preset-gatsby`)
const index = presets.findIndex(p => p.file.resolved === gatsbyPresetResolved)
const index = presets.findIndex(
p => p.file!.resolved === gatsbyPresetResolved
)

if (index !== -1) {
presets[index] = babel.createConfigItem(
Expand All @@ -191,17 +214,27 @@ const addRequiredPresetOptions = (
return presets
}

const mergeConfigItemOptions = ({ items, itemToMerge, type, babel }) => {
export const mergeConfigItemOptions = ({
items,
itemToMerge,
type,
babel,
}: {
items: Array<ConfigItem>
itemToMerge: ConfigItem
type: CreateConfigItemOptions["type"]
babel: typeof Babel
}): Array<ConfigItem> => {
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),
],
{
Expand All @@ -214,10 +247,3 @@ const mergeConfigItemOptions = ({ items, itemToMerge, type, babel }) => {

return items
}

exports.getCustomOptions = getCustomOptions

// Export helper functions for testing
exports.prepareOptions = prepareOptions
exports.mergeConfigItemOptions = mergeConfigItemOptions
exports.addRequiredPresetOptions = addRequiredPresetOptions
5 changes: 3 additions & 2 deletions packages/gatsby/src/utils/babel-loader.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const babelLoader = require(`babel-loader`)

const {
import {
prepareOptions,
getCustomOptions,
mergeConfigItemOptions,
addRequiredPresetOptions,
} = require(`./babel-loader-helpers`)
} from "./babel-loader-helpers"

const { getBrowsersList } = require(`./browserslist`)

/**
Expand Down
Loading

0 comments on commit ee2b0aa

Please sign in to comment.