Improve @babel/runtime esm stability (#12883)

This commit is contained in:
Nicolò Ribaudo
2021-02-24 20:04:03 +01:00
committed by GitHub
parent c9da9650eb
commit 6a471decc3
47 changed files with 2535 additions and 159 deletions

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,19 @@
const fs = require("fs");
const path = require("path");
const runtimePath = path.resolve(__dirname, "../../packages/babel-runtime");
const runtimeCorejs3Path = path.resolve(
__dirname,
"../../packages/babel-runtime-corejs3"
);
const input = path.resolve(__dirname, "src");
for (const file of fs.readdirSync(input)) {
if (!/\.[cm]js$/.test(file)) continue;
let contents = fs.readFileSync(path.join(input, file), "utf8");
contents = contents.replace("@babel/runtime-corejs3", runtimeCorejs3Path);
contents = contents.replace("@babel/runtime", runtimePath);
fs.writeFileSync(path.resolve(input, "absolute", file), contents);
}

View File

@@ -0,0 +1,65 @@
const cp = require("child_process");
const path = require("path");
const fs = require("fs");
const [major, minor] = process.versions.node.split(".").map(n => +n);
if (major > 12 || (major === 12 && minor >= 17)) {
test("ESM", "--experimental-modules ./src/main-esm.mjs", "expected-esm.txt");
// TODO: This never worked in any Babel version
// test("ESM - absoluteRuntime", "--esperimental-modules ./src/absolute/main-esm.mjs", "expected-esm-absolute.txt");
}
const expectedCjs =
major === 10 || (major === 12 && minor < 12.17)
? "expected-cjs-10.txt"
: "expected-cjs.txt";
test("CJS", "./src/main-cjs.cjs", expectedCjs);
const expectedCjsAbsolute =
major === 10 || (major === 12 && minor < 12.17)
? "expected-cjs-absolute-10.txt"
: major === 13 && minor <= 1
? "expected-cjs-absolute-13.0.txt"
: "expected-cjs-absolute.txt";
test(
"CJS - absoluteRuntime",
"./src/absolute/main-cjs.cjs",
expectedCjsAbsolute
);
function test(title, command, expectedName) {
const expectedPath = path.join(__dirname, expectedName);
const expected = fs.readFileSync(expectedPath, "utf8");
console.log(`Testing with Node.js ${process.version} - ${title}`);
const out = normalize(
cp.execSync(`node ${command}`, {
cwd: __dirname,
encoding: "utf8",
})
);
if (expected === out) {
console.log("OK");
} else if (process.env.OVERWRITE) {
fs.writeFileSync(expectedPath, out);
console.log("UPDATED");
} else {
console.error("FAILED\n\n");
console.error(out);
process.exitCode = 1;
}
console.log("\n");
}
function normalize(output) {
const root = path.resolve(__dirname, "../..");
let next;
while ((next = output.replace(root, "<ROOT>")) !== output) {
output = next;
}
return output;
}

View File

@@ -0,0 +1,10 @@
{
"name": "@babel-internal/runtime-integration-rollup",
"private": true,
"devDependencies": {
"@babel/runtime": "workspace:*",
"@rollup/plugin-commonjs": "^17.1.0",
"@rollup/plugin-node-resolve": "^11.2.0",
"rollup": "^2.39.1"
}
}

View File

@@ -0,0 +1,13 @@
import commonjs from "@rollup/plugin-commonjs";
import nodeResolve from "@rollup/plugin-node-resolve";
import path from "path";
export default {
input: path.resolve(__dirname, "../src/absolute/main-esm.mjs"),
plugins: [commonjs(), nodeResolve()],
output: {
file: path.resolve(__dirname, "output-absolute.js"),
format: "cjs",
},
};

View File

@@ -0,0 +1,13 @@
import commonjs from "@rollup/plugin-commonjs";
import nodeResolve from "@rollup/plugin-node-resolve";
import path from "path";
export default {
input: path.resolve(__dirname, "../src/main-esm.mjs"),
plugins: [commonjs(), nodeResolve()],
output: {
file: path.resolve(__dirname, "output.js"),
format: "cjs",
},
};

View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -0,0 +1,10 @@
import inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
console.log("================== import - auto ====================");
console.log("typeof inheritsLoose:", typeof inheritsLoose);
function A() {}
function B() {}
inheritsLoose(A, B);
console.log("A.__proto__ === B", A.__proto__ === B);

View File

@@ -0,0 +1,7 @@
import Set from "@babel/runtime-corejs3/core-js/set.js";
console.log("=============== import - corejs ====================");
console.log("typeof Set:", typeof Set);
const arr = Array.from(new Set([1, 2, 3]));
console.log("arr:", arr.toString());

View File

@@ -0,0 +1,8 @@
import toArray from "@babel/runtime/helpers/esm/toArray";
console.log("================= import - esm ======================");
console.log("typeof toArray:", typeof toArray);
const arr = toArray(new Set([1, 2, 3]));
console.log("arr:", arr.toString());

View File

@@ -0,0 +1,3 @@
require("./require-auto.cjs");
require("./require-esm.cjs");
require("./require-corejs.cjs");

View File

@@ -0,0 +1,6 @@
import "./import-auto.mjs";
import "./import-esm.mjs";
import "./import-corejs.mjs";
import "./require-auto.cjs";
import "./require-esm.cjs";
import "./require-corejs.cjs";

View File

@@ -0,0 +1,8 @@
{
"name": "@babel-internal/runtime-integration-src",
"private": true,
"devDependencies": {
"@babel/runtime": "workspace:*",
"@babel/runtime-corejs3": "workspace:*"
}
}

View File

@@ -0,0 +1,14 @@
const objectWithoutProperties = require("@babel/runtime/helpers/objectWithoutProperties");
console.log("================= require - auto ====================");
console.log("typeof objectWithoutProperties:", typeof objectWithoutProperties);
console.log(
"typeof objectWithoutProperties.default:",
typeof objectWithoutProperties.default
);
const obj = objectWithoutProperties(
{ a: 1, b: 2, c: 3, [Symbol.iterator]: 4, [Symbol.toStringTag]: 5 },
["a", "c", Symbol.iterator]
);
console.log("obj:", obj);

View File

@@ -0,0 +1,7 @@
const Set = require("@babel/runtime-corejs3/core-js/set.js");
console.log("=============== require - corejs ====================");
console.log("typeof Set:", typeof Set);
const arr = Array.from(new Set([1, 2, 3]));
console.log("arr:", arr.toString());

View File

@@ -0,0 +1,13 @@
console.log("================= require - esm =====================");
try {
const toPrimitive = require("@babel/runtime/helpers/esm/toPrimitive");
console.log("typeof toPrimitive:", typeof toPrimitive);
console.log("typeof toPrimitive.default:", typeof toPrimitive.default);
const value = toPrimitive.default({ valueOf: () => 2 });
console.log("Value:", value);
} catch (error) {
console.log("Error:", error.message);
}

View File

@@ -0,0 +1,8 @@
{
"name": "@babel-internal/runtime-integration-webpack-3",
"private": true,
"devDependencies": {
"@babel/runtime": "workspace:*",
"webpack": "^3.12.0"
}
}

View File

@@ -0,0 +1,11 @@
const path = require("path");
module.exports = {
entry: path.join(__dirname, "../src/absolute/main-esm.mjs"),
output: {
path: __dirname,
filename: "output-absolute.js",
},
devtool: false,
};

View File

@@ -0,0 +1,11 @@
const path = require("path");
module.exports = {
entry: path.join(__dirname, "../src/main-esm.mjs"),
output: {
path: __dirname,
filename: "output.js",
},
devtool: false,
};

View File

@@ -0,0 +1,9 @@
{
"name": "@babel-internal/runtime-integration-webpack-4",
"private": true,
"devDependencies": {
"@babel/runtime": "workspace:*",
"webpack": "^4.46.0",
"webpack-cli": "^4.5.0"
}
}

View File

@@ -0,0 +1,13 @@
const path = require("path");
module.exports = {
mode: "development",
entry: path.join(__dirname, "../src/absolute/main-esm.mjs"),
output: {
path: __dirname,
filename: "output-absolute.js",
},
devtool: false,
};

View File

@@ -0,0 +1,13 @@
const path = require("path");
module.exports = {
mode: "development",
entry: path.join(__dirname, "../src/main-esm.mjs"),
output: {
path: __dirname,
filename: "output.js",
},
devtool: false,
};

View File

@@ -0,0 +1,10 @@
{
"name": "@babel-internal/runtime-integration-webpack-5",
"private": true,
"exports": "./index.js",
"devDependencies": {
"@babel/runtime": "workspace:*",
"webpack": "^5.24.1",
"webpack-cli": "^4.5.0"
}
}

View File

@@ -0,0 +1,13 @@
const path = require("path");
module.exports = {
mode: "development",
entry: path.join(__dirname, "../src/absolute/main-esm.mjs"),
output: {
path: __dirname,
filename: "output-absolute.js",
},
devtool: false,
};

View File

@@ -0,0 +1,13 @@
const path = require("path");
module.exports = {
mode: "development",
entry: path.join(__dirname, "../src/main-esm.mjs"),
output: {
path: __dirname,
filename: "output.js",
},
devtool: false,
};