Skip to content

Commit

Permalink
Test Babel 7 plugins compatibility with Babel 8 core (#16332)
Browse files Browse the repository at this point in the history
* Allow configuring monorepo root in helper-fixtures

* Do not `require()` old syntax plugins when loading with Babel 8

* Add `REQUIRED_VERSION` macro

* Add test utils for Babel 7 plugins with Babel 8 core

* Run on CI

* babel.config.js runs in node 6

* chmod

* external-helpers doesn't work with Babel 8

* Discard changes to packages/babel-helper-fixtures/src/index.ts

* Use `yarn constraints` to update package.json
  • Loading branch information
nicolo-ribaudo committed Mar 7, 2024
1 parent a609d8e commit 4dd88ea
Show file tree
Hide file tree
Showing 124 changed files with 310 additions and 627 deletions.
1 change: 1 addition & 0 deletions .github/workflows/e2e-tests-breaking-esm.yml
Expand Up @@ -53,6 +53,7 @@ jobs:
# todo: verify which of these tests can be re-enabled
project:
- babel
- babel7plugins-babel8core
- create-react-app
# - vue-cli
# - jest
Expand Down
67 changes: 67 additions & 0 deletions babel.config.js
Expand Up @@ -13,6 +13,8 @@ if (typeof it === "function") {
const pathUtils = require("path");
const fs = require("fs");
const { parseSync } = require("@babel/core");
const packageJson = require("./package.json");
const babel7_8compat = require("./test/babel-7-8-compat/data.json");

function normalize(src) {
return src.replace(/\//, pathUtils.sep);
Expand Down Expand Up @@ -251,6 +253,26 @@ module.exports = function (api) {

pluginPackageJsonMacro,

[
pluginRequiredVersionMacro,
{
allowAny: !process.env.IS_PUBLISH || env === "standalone",
overwrite(requiredVersion, filename) {
if (requiredVersion === 7) requiredVersion = "^7.0.0-0";
if (process.env.BABEL_8_BREAKING) {
return packageJson.version;
}
const match = filename.match(/packages[\\/](.+?)[\\/]/);
if (
match &&
babel7_8compat["babel7plugins-babel8core"].includes(match[1])
) {
return `${requiredVersion} || >8.0.0-alpha <8.0.0-beta`;
}
},
},
],

needsPolyfillsForOldNode && pluginPolyfillsOldNode,
].filter(Boolean),
},
Expand Down Expand Up @@ -665,6 +687,51 @@ function pluginPackageJsonMacro({ types: t }) {
};
}

function pluginRequiredVersionMacro({ types: t }, { allowAny, overwrite }) {
const fnName = "REQUIRED_VERSION";

return {
visitor: {
ReferencedIdentifier(path) {
if (path.isIdentifier({ name: fnName })) {
throw path.buildCodeFrameError(
`"${fnName}" is only supported in call expressions.`
);
}
},
CallExpression(path) {
if (!path.get("callee").isIdentifier({ name: fnName })) return;

if (path.node.arguments.length !== 1) {
throw path.buildCodeFrameError(
`"${fnName}" expects exactly one argument.`
);
}

const arg = path.get("arguments.0").evaluate().value;
if (!arg) {
throw path.buildCodeFrameError(
`"${fnName}" expects a literal argument.`
);
}

if (allowAny) {
path.replaceWith(t.stringLiteral("*"));
return;
}

const version = overwrite(arg, this.filename);
if (version != null) {
path.replaceWith(t.stringLiteral(version));
return;
}

path.replaceWith(path.node.arguments[0]);
},
},
};
}

// transform `import { x } from "@babel/types"` to `import * as _t from "@babel/types"; const { x } = _t;
function transformNamedBabelTypesImportToDestructuring({
types: {
Expand Down
5 changes: 1 addition & 4 deletions eslint/babel-eslint-parser/src/parse.cts
Expand Up @@ -15,10 +15,7 @@ let isRunningMinSupportedCoreVersion: boolean = null;

export = function parse(code: string, options: Options, client: Client) {
// Ensure we're using a version of `@babel/core` that includes `parse()` and `tokTypes`.
const minSupportedCoreVersion =
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: ">=7.2.0";
const minSupportedCoreVersion = REQUIRED_VERSION(">=7.2.0");

if (typeof isRunningMinSupportedCoreVersion !== "boolean") {
isRunningMinSupportedCoreVersion = semver.satisfies(
Expand Down
2 changes: 2 additions & 0 deletions lib/globals.d.ts
@@ -1,6 +1,8 @@
declare const USE_ESM: boolean;
declare const IS_STANDALONE: boolean;
declare const PACKAGE_JSON: { name: string; version: string };
declare function REQUIRED_VERSION(version: number): number | string;
declare function REQUIRED_VERSION(version: string): string;

declare namespace NodeJS {
export interface ProcessEnv {
Expand Down
Expand Up @@ -2147,18 +2147,18 @@ export default function (
inherits: PluginObject["inherits"],
): PluginObject {
if (process.env.BABEL_8_BREAKING) {
assertVersion(process.env.IS_PUBLISH ? PACKAGE_JSON.version : "^7.21.0");
assertVersion(REQUIRED_VERSION("^7.21.0"));
} else {
if (
version === "2023-11" ||
version === "2023-05" ||
version === "2023-01"
) {
assertVersion("^7.21.0");
assertVersion(REQUIRED_VERSION("^7.21.0"));
} else if (version === "2021-12") {
assertVersion("^7.16.0");
assertVersion(REQUIRED_VERSION("^7.16.0"));
} else {
assertVersion("^7.19.0");
assertVersion(REQUIRED_VERSION("^7.19.0"));
}
}

Expand Down
Expand Up @@ -2,11 +2,7 @@ import { declare } from "@babel/helper-plugin-utils";
import { shouldTransform } from "./util.ts";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.16.0",
);
api.assertVersion(REQUIRED_VERSION("^7.16.0"));

return {
name: "plugin-bugfix-safari-id-destructuring-collision-in-function-expression",
Expand Down
Expand Up @@ -5,11 +5,7 @@ import type { NodePath } from "@babel/traverse";
import type * as t from "@babel/types";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

const noDocumentAll = api.assumption("noDocumentAll") ?? false;
const pureGetters = api.assumption("pureGetters") ?? false;
Expand Down
Expand Up @@ -32,11 +32,7 @@ function buildFieldsReplacement(
}

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

const setPublicClassFields = api.assumption("setPublicClassFields");

Expand Down
6 changes: 1 addition & 5 deletions packages/babel-plugin-external-helpers/src/index.ts
Expand Up @@ -7,11 +7,7 @@ export interface Options {
}

export default declare((api, options: Options) => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

const { helperVersion = "7.0.0-beta.0", whitelist = false } = options;

Expand Down
Expand Up @@ -4,11 +4,7 @@ import hoistVariables from "@babel/helper-hoist-variables";
import type * as t from "@babel/types";

export default declare(({ types: t, assertVersion }) => {
assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.13.0",
);
assertVersion(REQUIRED_VERSION("^7.13.0"));

return {
name: "proposal-async-do-expressions",
Expand Down
12 changes: 2 additions & 10 deletions packages/babel-plugin-proposal-decorators/src/index.ts
Expand Up @@ -17,11 +17,7 @@ interface Options extends SyntaxOptions {
export type { Options };

export default declare((api, options: Options) => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

// Options are validated in @babel/plugin-syntax-decorators
if (!process.env.BABEL_8_BREAKING) {
Expand Down Expand Up @@ -49,11 +45,7 @@ export default declare((api, options: Options) => {
version === "2023-05" ||
version === "2023-11"
) {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.0.2",
);
api.assertVersion(REQUIRED_VERSION("^7.0.2"));
return createClassFeaturePlugin({
name: "proposal-decorators",

Expand Down
Expand Up @@ -14,11 +14,7 @@ import type { NodePath, Visitor } from "@babel/traverse";
import type * as t from "@babel/types";

export default declare(function ({ assertVersion, assumption, types: t }) {
assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.17.0",
);
assertVersion(REQUIRED_VERSION("^7.17.0"));
const {
assignmentExpression,
assignmentPattern,
Expand Down
6 changes: 1 addition & 5 deletions packages/babel-plugin-proposal-do-expressions/src/index.ts
Expand Up @@ -2,11 +2,7 @@ import { declare } from "@babel/helper-plugin-utils";
import syntaxDoExpressions from "@babel/plugin-syntax-do-expressions";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

return {
name: "proposal-do-expressions",
Expand Down
Expand Up @@ -7,11 +7,7 @@ export interface Options {
}

export default declare((api, options: Options) => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.19.0",
);
api.assertVersion(REQUIRED_VERSION("^7.19.0"));

const { runtime } = options;
if (runtime !== undefined && typeof runtime !== "boolean") {
Expand Down
Expand Up @@ -9,11 +9,7 @@ const enum USING_KIND {
}

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.22.0",
);
api.assertVersion(REQUIRED_VERSION("^7.22.0"));

const TOP_LEVEL_USING = new Map<t.Node, USING_KIND>();

Expand Down
Expand Up @@ -3,11 +3,7 @@ import syntaxExportDefaultFrom from "@babel/plugin-syntax-export-default-from";
import { types as t } from "@babel/core";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

return {
name: "proposal-export-default-from",
Expand Down
6 changes: 1 addition & 5 deletions packages/babel-plugin-proposal-function-bind/src/index.ts
Expand Up @@ -4,11 +4,7 @@ import { types as t } from "@babel/core";
import type { Scope } from "@babel/traverse";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

function getTempId(scope: Scope) {
let id = scope.path.getData("functionBind");
Expand Down
6 changes: 1 addition & 5 deletions packages/babel-plugin-proposal-function-sent/src/index.ts
Expand Up @@ -5,11 +5,7 @@ import { types as t } from "@babel/core";
import type { Visitor } from "@babel/traverse";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

const isFunctionSent = (node: t.MetaProperty) =>
t.isIdentifier(node.meta, { name: "function" }) &&
Expand Down
Expand Up @@ -4,11 +4,7 @@ import type * as t from "@babel/types";
import syntaxImportAttributes from "@babel/plugin-syntax-import-attributes";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

return {
name: "proposal-import-attributes-to-assertions",
Expand Down
6 changes: 1 addition & 5 deletions packages/babel-plugin-proposal-import-defer/src/index.ts
Expand Up @@ -6,11 +6,7 @@ import { defineCommonJSHook } from "@babel/plugin-transform-modules-commonjs";
import syntaxImportDefer from "@babel/plugin-syntax-import-defer";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.23.0",
);
api.assertVersion(REQUIRED_VERSION("^7.23.0"));
// We need the explicit type annotation otherwise when using t.assert* ts
// reports that 'Assertions require every name in the call target to be
// declared with an explicit type annotation'
Expand Down
Expand Up @@ -11,11 +11,7 @@ import {

export default declare(api => {
const { types: t, template } = api;
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.23.0",
);
api.assertVersion(REQUIRED_VERSION("^7.23.0"));

const targets = api.targets();

Expand Down
6 changes: 1 addition & 5 deletions packages/babel-plugin-proposal-json-modules/src/index.ts
Expand Up @@ -10,11 +10,7 @@ import {

export default declare(api => {
const { types: t, template } = api;
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.22.0",
);
api.assertVersion(REQUIRED_VERSION("^7.22.0"));

const targets = api.targets();

Expand Down
Expand Up @@ -6,11 +6,7 @@ import { skipTransparentExprWrappers } from "@babel/helper-skip-transparent-expr
import { transformOptionalChain } from "@babel/plugin-transform-optional-chaining";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: "^7.22.5",
);
api.assertVersion(REQUIRED_VERSION("^7.22.5"));

const assumptions = {
noDocumentAll: api.assumption("noDocumentAll") ?? false,
Expand Down
Expand Up @@ -4,11 +4,7 @@ import { types as t } from "@babel/core";
import type { Scope } from "@babel/traverse";

export default declare(api => {
api.assertVersion(
process.env.BABEL_8_BREAKING && process.env.IS_PUBLISH
? PACKAGE_JSON.version
: 7,
);
api.assertVersion(REQUIRED_VERSION(7));

/**
* a function to figure out if a call expression has
Expand Down

0 comments on commit 4dd88ea

Please sign in to comment.