Skip to content

Commit

Permalink
Improve @babel/runtime esm stability (#12883)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Feb 24, 2021
1 parent c9da965 commit 6a471de
Show file tree
Hide file tree
Showing 47 changed files with 2,713 additions and 337 deletions.
3 changes: 3 additions & 0 deletions .eslintignore
Expand Up @@ -26,3 +26,6 @@ packages/babel-parser/test/expressions
eslint/*/lib
eslint/*/node_modules
eslint/*/test/fixtures

test/runtime-integration/*/output.js
test/runtime-integration/*/output-absolute.js
2 changes: 2 additions & 0 deletions .flowconfig
Expand Up @@ -5,6 +5,8 @@
<PROJECT_ROOT>/codemods/.*/lib
<PROJECT_ROOT>/codemods/.*/test
<PROJECT_ROOT>/node_modules/module-deps/
<PROJECT_ROOT>/node_modules/webpack-cli/
<PROJECT_ROOT>/test/runtime-integration/

[include]
packages/*/src
Expand Down
81 changes: 81 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -269,3 +269,84 @@ jobs:
run: make test-flow
- name: Run TypeScript Tests
run: make test-typescript

runtime-interop:
name: Test @babel/runtime integrations
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Use Node.js latest
uses: actions/setup-node@v2-beta
with:
node-version: "*"
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
- uses: actions/cache@v2
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: yarn-${{ hashFiles('yarn.lock') }}
- name: Install
run: yarn install
- uses: actions/download-artifact@v2
with:
name: babel-artifact
- name: Generate runtime helpers
run: |
make build-plugin-transform-runtime-dist
- name: Generate absoluteRuntime tests
run: yarn test:runtime:generate-absolute-runtime
- name: Test bundlers
run: yarn test:runtime:bundlers
- name: Test Node.js
run: yarn test:runtime:node
- name: Use Node.js 10
uses: actions/setup-node@v2-beta
with:
node-version: 10
- name: Test Node.js 10
run: yarn test:runtime:node
- name: Use Node.js 12.0
uses: actions/setup-node@v2-beta
with:
node-version: "12.0" # quoted, otherwise it's just 13
- name: Test Node.js 12.0
run: yarn test:runtime:node
- name: Use Node.js 12.17
uses: actions/setup-node@v2-beta
with:
node-version: 12.17
- name: Test Node.js 12.17
run: yarn test:runtime:node
- name: Use Node.js 13.0
uses: actions/setup-node@v2-beta
with:
node-version: "13.0" # quoted, otherwise it's just 13
- name: Test Node.js 13.0
run: yarn test:runtime:node
# - name: Use Node.js 13.2
# uses: actions/setup-node@v2-beta
# with:
# node-version: 13.2
# - name: Test Node.js 13.2
# run: yarn test:runtime:node
# - name: Use Node.js 13.6
# uses: actions/setup-node@v2-beta
# with:
# node-version: 13.6
# - name: Test Node.js 13.6
# run: yarn test:runtime:node
- name: Use Node.js 13.7
uses: actions/setup-node@v2-beta
with:
node-version: 13.7
- name: Test Node.js 13.7
run: yarn test:runtime:node
- name: Use Node.js 14.2
uses: actions/setup-node@v2-beta
with:
node-version: 14.2
- name: Test Node.js 14.2
run: yarn test:runtime:node
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -79,3 +79,6 @@ packages/babel-standalone/babel.min.js

tsconfig.json
tsconfig.tsbuildinfo

/test/runtime-integration/*/output.js
/test/runtime-integration/*/absolute-output.js
8 changes: 6 additions & 2 deletions package.json
Expand Up @@ -12,7 +12,10 @@
"lint": "make lint",
"test": "make test",
"version": "yarn --immutable-cache && git add yarn.lock",
"test:esm": "node test/esm/index.js"
"test:esm": "node test/esm/index.js",
"test:runtime:generate-absolute-runtime": "node test/runtime-integration/generate-absolute-runtime.cjs",
"test:runtime:bundlers": "node test/runtime-integration/bundlers.cjs",
"test:runtime:node": "node test/runtime-integration/node.cjs"
},
"devDependencies": {
"@babel/cli": "^7.12.0",
Expand Down Expand Up @@ -73,7 +76,8 @@
"codemods/*",
"eslint/*",
"packages/*",
"test/esm"
"test/esm",
"test/runtime-integration/*"
],
"resolutions": {
"browserslist": "npm:4.14.5",
Expand Down
16 changes: 16 additions & 0 deletions packages/babel-plugin-transform-runtime/scripts/build-dist.js
Expand Up @@ -248,6 +248,7 @@ function buildHelper(
[transformRuntime, { corejs, version: runtimeVersion }],
buildRuntimeRewritePlugin(runtimeName, helperName),
esm ? null : addDefaultCJSExport,
esm ? useRelativeImports : null,
].filter(Boolean),
overrides: [
{
Expand Down Expand Up @@ -318,3 +319,18 @@ function addDefaultCJSExport({ template }) {
},
};
}

function useRelativeImports() {
const RE = /^@babel\/runtime(?:-corejs[23])?\/helpers\/(?<name>.+)$/;

return {
visitor: {
ImportDeclaration(path) {
path.node.source.value = path.node.source.value.replace(
RE,
"../$<name>/_index.mjs"
);
},
},
};
}
7 changes: 0 additions & 7 deletions packages/babel-plugin-transform-runtime/src/index.js
Expand Up @@ -88,13 +88,6 @@ export default declare((api, options, dirname) => {
// TODO(Babel 8): Remove this check, it's always true
const DUAL_MODE_RUNTIME = "7.13.0";
const supportsCJSDefault = hasMinVersion(DUAL_MODE_RUNTIME, runtimeVersion);
if (supportsCJSDefault && useESModules && !absoluteRuntime) {
console.warn(
`[@babel/plugin-transform-runtime] The 'useESModules' option is not necessary when using` +
` a @babel/runtime version >= ${DUAL_MODE_RUNTIME} and not using the 'absoluteRuntime'` +
` option, because it automatically detects the necessary module format.`,
);
}

function has(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
Expand Down

This file was deleted.

4 changes: 2 additions & 2 deletions packages/babel-runtime-corejs2/helpers/temporalRef/_index.mjs
@@ -1,5 +1,5 @@
import undef from "@babel/runtime-corejs2/helpers/temporalUndefined";
import err from "@babel/runtime-corejs2/helpers/tdz";
import undef from "../temporalUndefined/_index.mjs";
import err from "../tdz/_index.mjs";
export default function _temporalRef(val, name) {
return val === undef ? err(name) : val;
}
8 changes: 4 additions & 4 deletions packages/babel-runtime-corejs2/helpers/toArray/_index.mjs
@@ -1,7 +1,7 @@
import arrayWithHoles from "@babel/runtime-corejs2/helpers/arrayWithHoles";
import iterableToArray from "@babel/runtime-corejs2/helpers/iterableToArray";
import unsupportedIterableToArray from "@babel/runtime-corejs2/helpers/unsupportedIterableToArray";
import nonIterableRest from "@babel/runtime-corejs2/helpers/nonIterableRest";
import arrayWithHoles from "../arrayWithHoles/_index.mjs";
import iterableToArray from "../iterableToArray/_index.mjs";
import unsupportedIterableToArray from "../unsupportedIterableToArray/_index.mjs";
import nonIterableRest from "../nonIterableRest/_index.mjs";
export default function _toArray(arr) {
return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest();
}
4 changes: 2 additions & 2 deletions packages/babel-runtime/helpers/temporalRef/_index.mjs
@@ -1,5 +1,5 @@
import undef from "@babel/runtime/helpers/temporalUndefined";
import err from "@babel/runtime/helpers/tdz";
import undef from "../temporalUndefined/_index.mjs";
import err from "../tdz/_index.mjs";
export default function _temporalRef(val, name) {
return val === undef ? err(name) : val;
}
8 changes: 4 additions & 4 deletions packages/babel-runtime/helpers/toArray/_index.mjs
@@ -1,7 +1,7 @@
import arrayWithHoles from "@babel/runtime/helpers/arrayWithHoles";
import iterableToArray from "@babel/runtime/helpers/iterableToArray";
import unsupportedIterableToArray from "@babel/runtime/helpers/unsupportedIterableToArray";
import nonIterableRest from "@babel/runtime/helpers/nonIterableRest";
import arrayWithHoles from "../arrayWithHoles/_index.mjs";
import iterableToArray from "../iterableToArray/_index.mjs";
import unsupportedIterableToArray from "../unsupportedIterableToArray/_index.mjs";
import nonIterableRest from "../nonIterableRest/_index.mjs";
export default function _toArray(arr) {
return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest();
}
48 changes: 48 additions & 0 deletions test/runtime-integration/bundlers.cjs
@@ -0,0 +1,48 @@
const cp = require("child_process");
const path = require("path");
const fs = require("fs");

for (const absolute of [false, true]) {
const output = absolute ? "output-absolute.js" : "output.js";
const title = absolute ? "(absolute runtime)" : "";

const webpack = absolute
? "webpack --config webpack.absolute.config.js"
: "webpack";
const rollup = absolute ? "rollup -c rollup.absolute.config.js" : "rollup -c";

// TODO: This never worked in any Babel version
if (!absolute) {
test(`Webpack 5 ${title}`, webpack, "webpack-5", output, true);
}
test(`Webpack 4 ${title}`, webpack, "webpack-4", output);
test(`Webpack 3 ${title}`, webpack, "webpack-3", output);
test(`Rollup ${title}`, rollup, "rollup", output);
}

function test(name, command, directory, output, first) {
console.log(`Building with ${name}`);
cp.execSync(`yarn ${command}`, {
cwd: path.join(__dirname, directory),
encoding: "utf8",
});
console.log(`Testing the ${name} bundle`);
const out = cp.execSync(`node ${output}`, {
cwd: path.join(__dirname, directory),
encoding: "utf8",
});

const expectedPath = path.join(__dirname, "expected-bundler.txt");
let expected = fs.readFileSync(expectedPath, "utf8");

if (expected === out) {
console.log("OK");
} else if (first && process.env.OVERWRITE) {
fs.writeFileSync(expectedPath, out);
expected = out;
console.log("UPDATED");
} else {
console.error("FAILED\n");
console.error(out);
}
}
20 changes: 20 additions & 0 deletions test/runtime-integration/expected-bundler-absolute.txt
@@ -0,0 +1,20 @@
================== import - auto ====================
typeof inheritsLoose: function
A.__proto__ === B true
================= import - esm ======================
typeof toArray: function
arr: 1,2,3
=============== import - corejs ====================
typeof Set: function
arr: 1,2,3
================= require - auto ====================
typeof objectWithoutProperties: function
typeof objectWithoutProperties.default: function
obj: { b: 2, [Symbol(Symbol.toStringTag)]: 5 }
================= require - esm =====================
typeof toPrimitive: object
typeof toPrimitive.default: function
Value: 2
=============== require - corejs ====================
typeof Set: function
arr: 1,2,3
20 changes: 20 additions & 0 deletions test/runtime-integration/expected-bundler.txt
@@ -0,0 +1,20 @@
================== import - auto ====================
typeof inheritsLoose: function
A.__proto__ === B true
================= import - esm ======================
typeof toArray: function
arr: 1,2,3
=============== import - corejs ====================
typeof Set: function
arr: 1,2,3
================= require - auto ====================
typeof objectWithoutProperties: function
typeof objectWithoutProperties.default: function
obj: { b: 2, [Symbol(Symbol.toStringTag)]: 5 }
================= require - esm =====================
typeof toPrimitive: object
typeof toPrimitive.default: function
Value: 2
=============== require - corejs ====================
typeof Set: function
arr: 1,2,3
9 changes: 9 additions & 0 deletions test/runtime-integration/expected-cjs-10.txt
@@ -0,0 +1,9 @@
================= require - auto ====================
typeof objectWithoutProperties: function
typeof objectWithoutProperties.default: function
obj: { b: 2, [Symbol(Symbol.toStringTag)]: 5 }
================= require - esm =====================
Error: Unexpected token export
=============== require - corejs ====================
typeof Set: function
arr: 1,2,3
9 changes: 9 additions & 0 deletions test/runtime-integration/expected-cjs-absolute-10.txt
@@ -0,0 +1,9 @@
================= require - auto ====================
typeof objectWithoutProperties: function
typeof objectWithoutProperties.default: function
obj: { b: 2, [Symbol(Symbol.toStringTag)]: 5 }
================= require - esm =====================
Error: Unexpected token export
=============== require - corejs ====================
typeof Set: function
arr: 1,2,3
9 changes: 9 additions & 0 deletions test/runtime-integration/expected-cjs-absolute-13.0.txt
@@ -0,0 +1,9 @@
================= require - auto ====================
typeof objectWithoutProperties: function
typeof objectWithoutProperties.default: function
obj: { b: 2, [Symbol(Symbol.toStringTag)]: 5 }
================= require - esm =====================
Error: Unexpected token 'export'
=============== require - corejs ====================
typeof Set: function
arr: 1,2,3
13 changes: 13 additions & 0 deletions test/runtime-integration/expected-cjs-absolute.txt
@@ -0,0 +1,13 @@
================= require - auto ====================
typeof objectWithoutProperties: function
typeof objectWithoutProperties.default: function
obj: { b: 2, [Symbol(Symbol.toStringTag)]: 5 }
================= require - esm =====================
Error: Must use import to load ES Module: <ROOT>/packages/babel-runtime/helpers/esm/toPrimitive.js
require() of ES modules is not supported.
require() of <ROOT>/packages/babel-runtime/helpers/esm/toPrimitive.js from <ROOT>/test/runtime-integration/src/absolute/require-esm.cjs is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename toPrimitive.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from <ROOT>/packages/babel-runtime/helpers/esm/package.json.

=============== require - corejs ====================
typeof Set: function
arr: 1,2,3
9 changes: 9 additions & 0 deletions test/runtime-integration/expected-cjs.txt
@@ -0,0 +1,9 @@
================= require - auto ====================
typeof objectWithoutProperties: function
typeof objectWithoutProperties.default: function
obj: { b: 2, [Symbol(Symbol.toStringTag)]: 5 }
================= require - esm =====================
Error: Must use import to load ES Module: <ROOT>/packages/babel-runtime/helpers/toPrimitive/_index.mjs
=============== require - corejs ====================
typeof Set: function
arr: 1,2,3
Empty file.
18 changes: 18 additions & 0 deletions test/runtime-integration/expected-esm.txt
@@ -0,0 +1,18 @@
================== import - auto ====================
typeof inheritsLoose: function
A.__proto__ === B true
================= import - esm ======================
typeof toArray: function
arr: 1,2,3
=============== import - corejs ====================
typeof Set: function
arr: 1,2,3
================= require - auto ====================
typeof objectWithoutProperties: function
typeof objectWithoutProperties.default: function
obj: { b: 2, [Symbol(Symbol.toStringTag)]: 5 }
================= require - esm =====================
Error: Must use import to load ES Module: <ROOT>/packages/babel-runtime/helpers/toPrimitive/_index.mjs
=============== require - corejs ====================
typeof Set: function
arr: 1,2,3

0 comments on commit 6a471de

Please sign in to comment.