Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(babel-preset-gatsby-package): add conditional compilation plugin #32687

Merged
merged 8 commits into from
Aug 5, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = {
__PATH_PREFIX__: true,
__BASE_PATH__: true,
__ASSET_PREFIX__: true,
_CFLAGS_: true,
},
rules: {
"@babel/no-unused-expressions": [
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@
},
"scripts": {
"bootstrap": "npm-run-all -s check-versions \"lerna-prepare -- --{@}\" --",
"check-repo-fields": "babel-node scripts/check-repo-fields.js",
"check-versions": "babel-node scripts/check-versions.js",
"check-repo-fields": "node scripts/check-repo-fields.js",
"check-versions": "node scripts/check-versions.js",
Comment on lines +120 to +121
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not necessary anymore, else I had to change a few things in babelrc

"format": "npm run format:code && npm run format:other && npm run format:svg",
"format:code": "npm run lint:code -- --fix",
"format:other": "npm run prettier -- --write",
Expand Down
11 changes: 11 additions & 0 deletions packages/babel-preset-gatsby-package/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"plugins": [
["@babel/plugin-transform-modules-commonjs"]
],
"overrides": [
{
"test": ["**/*.ts", "**/*.tsx"],
"plugins": [["@babel/plugin-transform-typescript", { "isTSX": true }]],
}
]
}
1 change: 1 addition & 0 deletions packages/babel-preset-gatsby-package/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
yarn.lock
dist/
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,29 @@ Array [
]
`;

exports[`babel-preset-gatsby-package in browser mode specifies proper presets for esm 1`] = `
Array [
Array [
"@babel/preset-env",
Object {
"bugfixes": true,
"debug": false,
"loose": true,
"modules": false,
"shippedProposals": true,
"targets": Object {
"esmodules": true,
},
"useBuiltIns": false,
},
],
Array [
"@babel/preset-react",
],
"@babel/preset-flow",
]
`;

exports[`babel-preset-gatsby-package in browser mode specifies the proper plugins 1`] = `
Array [
"@babel/plugin-proposal-nullish-coalescing-operator",
Expand All @@ -64,6 +87,25 @@ Array [
]
`;

exports[`babel-preset-gatsby-package in node mode can enable compilerFlags 1`] = `
Array [
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-transform-runtime",
"@babel/plugin-syntax-dynamic-import",
"babel-plugin-dynamic-import-node",
Array [
"./babel-transform-compiler-flags",
Object {
"availableFlags": Array [
"MAJOR",
],
"flags": Object {},
},
],
]
`;

exports[`babel-preset-gatsby-package in node mode specifies proper presets 1`] = `
Array [
Array [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const runner = require(`@babel/helper-plugin-test-runner`).default

runner(__dirname)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

if (_CFLAGS_.MAJOR === '4') {
console.log('We only load this for Gatsby 4')
} else {
console.log('Old code path')
}

function isGatsby4() {
return _CFLAGS_.MAJOR === '4'
}


if (isGatsby4()) {
console.log('We only load this for Gatsby 4')
} else {
console.log('Old code path')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
if ("4" === '4') {
console.log('We only load this for Gatsby 4');
} else {
console.log('Old code path');
}

function isGatsby4() {
return "4" === '4';
}

if (isGatsby4()) {
console.log('We only load this for Gatsby 4');
} else {
console.log('Old code path');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

if (_CFLAGS_.UNKNOWN === 'true') {
console.log('We only load this when true')
} else {
console.log('Old code path')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"throws": "UNKNOWN is not part of the available compiler flags."
}
17 changes: 17 additions & 0 deletions packages/babel-preset-gatsby-package/__tests__/fixtures/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const path = require("path")

module.exports = {
sourceType: "module",
plugins: [
[path.resolve(__dirname, "../../src/babel-transform-compiler-flags.ts"),
{
availableFlags: ['MAJOR'],
flags: {
MAJOR: '4',
}
}
],
],
babelrc: false,
configFile: false,
}
32 changes: 24 additions & 8 deletions packages/babel-preset-gatsby-package/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
const preset = require(`../`)
const preset = require(`../src/index.js`)

jest.mock(`../resolver`, () => jest.fn(moduleName => moduleName))
jest.mock(`../src/resolver`, () => jest.fn(moduleName => moduleName))

beforeEach(() => {
delete process.env.BABEL_ENV
})

describe(`babel-preset-gatsby-package`, () => {
let babelEnv;

beforeEach(() => {
babelEnv = process.env.BABEL_ENV
delete process.env.BABEL_ENV;
})

afterEach(() => {
process.env.BABEL_ENV = babelEnv
})

describe(`in node mode`, () => {
it(`specifies the proper plugins`, () => {
const { plugins } = preset()
Expand All @@ -29,12 +37,15 @@ describe(`babel-preset-gatsby-package`, () => {
nodeVersion,
})

const [, opts] = presets.find(preset =>
[].concat(preset).includes(`@babel/preset-env`)
)
const [, opts] = presets.find(preset => [].concat(preset).includes(`@babel/preset-env`))

expect(opts.targets.node).toBe(nodeVersion)
})

it(`can enable compilerFlags`, () => {
const { plugins } = preset(null, { availableCompilerFlags: [`MAJOR`] })
expect(plugins).toMatchSnapshot()
})
})

describe(`in browser mode`, () => {
Expand All @@ -52,5 +63,10 @@ describe(`babel-preset-gatsby-package`, () => {
const { presets } = preset(null, { browser: true, debug: true })
expect(presets).toMatchSnapshot()
})

it(`specifies proper presets for esm`, () => {
const { presets } = preset(null, { browser: true, esm: true })
expect(presets).toMatchSnapshot()
})
})
})
14 changes: 13 additions & 1 deletion packages/babel-preset-gatsby-package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,24 @@
"babel-plugin-dynamic-import-node": "^2.3.3",
"core-js": "^3.10.0"
},
"devDependencies": {
"@types/babel__core": "^7.1.15",
"@babel/cli": "^7.14.8",
"@babel/core": "^7.14.8",
"@babel/helper-plugin-test-runner": "7.14.5",
"@babel/plugin-transform-modules-commonjs": "^7.14.5"
},
"peerDependencies": {
"@babel/core": "^7.11.6"
},
"license": "MIT",
"main": "index.js",
"main": "dist/index.js",
"engines": {
"node": ">=12.13.0"
},
"scripts": {
"build": "babel src --out-dir dist/ --ignore \"**/__tests__\" --ignore \"**/__mocks__\" --extensions \".ts,.js\"",
"prepare": "cross-env NODE_ENV=production npm run build",
"watch": "babel -w src --out-dir dist/ --ignore \"**/__tests__\" --extensions \".ts,.js\""
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { NodePath, PluginObj, types, PluginPass } from "@babel/core"

interface IPluginOptions {
flags: Record<string, string>
availableFlags: Array<string>
}

export default function compilerFlags(
{
types: t,
}: {
types: typeof types
},
opts: Partial<IPluginOptions>
): PluginObj {
if (!opts.flags) {
throw new Error(`flags option needs to be set`)
}
if (!opts.availableFlags) {
throw new Error(`availableFlags option needs to be set`)
}

return {
name: `babel-transform-compiler-flags`,
visitor: {
Identifier(
nodePath: NodePath<types.Identifier>,
state: PluginPass
): void {
const flags = (state.opts as IPluginOptions).flags
const availableFlags = (state.opts as IPluginOptions).availableFlags

if (
nodePath.node.name === `_CFLAGS_` &&
t.isMemberExpression(nodePath.parent)
) {
const cFlag = (nodePath.parent.property as types.Identifier).name

if (!availableFlags.includes(cFlag)) {
throw new Error(
`${cFlag} is not part of the available compiler flags.`
)
}

nodePath.parentPath.replaceWith(
t.stringLiteral(flags[cFlag] ? flags[cFlag] : ``)
)
}
},
},
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
const r = require(`./resolver`)

function preset(context, options = {}) {
const { browser = false, debug = false, nodeVersion = `12.13.0`, esm = false } = options
const { NODE_ENV, BABEL_ENV } = process.env
const {
browser = false,
debug = false,
nodeVersion = `12.13.0`,
esm = false,
availableCompilerFlags = [],
} = options
const { NODE_ENV, BABEL_ENV, COMPILER_OPTIONS } = process.env

const IS_TEST = (BABEL_ENV || NODE_ENV) === `test`

Expand All @@ -13,11 +19,11 @@ function preset(context, options = {}) {
if (browser) {
if (esm) {
browserConfig.targets = {
esmodules: true
esmodules: true,
}
} else {
browserConfig.targets = {
browsers: [`last 2 versions`, `not ie <= 11`, `not android 4.4.3`]
browsers: [`last 2 versions`, `not ie <= 11`, `not android 4.4.3`],
}
}
}
Expand All @@ -30,6 +36,20 @@ function preset(context, options = {}) {
},
}

let parsedCompilerOptions = {}
if (COMPILER_OPTIONS) {
// COMPILER_OPTIONS syntax is key=value,key2=value2
parsedCompilerOptions = COMPILER_OPTIONS.split(`,`).reduce((acc, curr) => {
const [key, value] = curr.split(`=`)

if (key) {
acc[key] = value
}

return acc
}, Object.create(null))
}

return {
presets: [
[
Expand All @@ -54,6 +74,13 @@ function preset(context, options = {}) {
r(`@babel/plugin-transform-runtime`),
r(`@babel/plugin-syntax-dynamic-import`),
IS_TEST && r(`babel-plugin-dynamic-import-node`),
availableCompilerFlags.length && [
r(`./babel-transform-compiler-flags`),
{
flags: parsedCompilerOptions,
availableFlags: availableCompilerFlags,
},
],
pieh marked this conversation as resolved.
Show resolved Hide resolved
].filter(Boolean),
overrides: [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const r = m => require.resolve(m)

module.exports = r;
module.exports = r
4 changes: 4 additions & 0 deletions packages/babel-preset-gatsby-package/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../tsconfig.json",
"strict": true
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"resolveJsonModule": true,
"esModuleInterop": true,
"jsx": "preserve",
"typeRoots": ["./types", "**/node_modules/@types", "node_modules/@types"],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary to find the global CFLAGS types in the monorepo

"paths": {
"@reach/router/*": ["./node_modules/@gatsbyjs/reach-router/*"]
}
Expand Down
3 changes: 3 additions & 0 deletions types/gatsby-monorepo/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare const _CFLAGS_: {
GATSBY_MAJOR: string
}
5 changes: 5 additions & 0 deletions types/gatsby-monorepo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "gatsby-monorepo",
"types": "./global.d.ts",
"private": true
}