Use native Node.js functions when available (#12458)
This commit is contained in:
parent
c2fcd69e94
commit
98aa72ca74
131
babel.config.js
131
babel.config.js
@ -21,7 +21,7 @@ module.exports = function (api) {
|
||||
let convertESM = true;
|
||||
let ignoreLib = true;
|
||||
let includeRegeneratorRuntime = false;
|
||||
let polyfillRequireResolve = false;
|
||||
let needsPolyfillsForOldNode = false;
|
||||
|
||||
let transformRuntimeOptions;
|
||||
|
||||
@ -54,7 +54,7 @@ module.exports = function (api) {
|
||||
"packages/babel-compat-data"
|
||||
);
|
||||
if (env === "rollup") envOpts.targets = { node: nodeVersion };
|
||||
polyfillRequireResolve = true;
|
||||
needsPolyfillsForOldNode = true;
|
||||
break;
|
||||
case "test-legacy": // In test-legacy environment, we build babel on latest node but test on minimum supported legacy versions
|
||||
case "production":
|
||||
@ -62,7 +62,7 @@ module.exports = function (api) {
|
||||
envOpts.targets = {
|
||||
node: nodeVersion,
|
||||
};
|
||||
polyfillRequireResolve = true;
|
||||
needsPolyfillsForOldNode = true;
|
||||
break;
|
||||
case "development":
|
||||
envOpts.debug = true;
|
||||
@ -79,7 +79,7 @@ module.exports = function (api) {
|
||||
|
||||
if (process.env.STRIP_BABEL_8_FLAG && bool(process.env.BABEL_8_BREAKING)) {
|
||||
// Never apply polyfills when compiling for Babel 8
|
||||
polyfillRequireResolve = false;
|
||||
needsPolyfillsForOldNode = false;
|
||||
}
|
||||
|
||||
if (includeRegeneratorRuntime) {
|
||||
@ -129,7 +129,7 @@ module.exports = function (api) {
|
||||
pluginToggleBabel8Breaking,
|
||||
{ breaking: bool(process.env.BABEL_8_BREAKING) },
|
||||
],
|
||||
polyfillRequireResolve && pluginPolyfillRequireResolve,
|
||||
needsPolyfillsForOldNode && pluginPolyfillsOldNode,
|
||||
].filter(Boolean),
|
||||
overrides: [
|
||||
{
|
||||
@ -180,41 +180,102 @@ function bool(value) {
|
||||
return value && value !== "false" && value !== "0";
|
||||
}
|
||||
|
||||
// TODO(Babel 8) This polyfill is only needed for Node.js 6 and 8
|
||||
function pluginPolyfillRequireResolve({ template, types: t }) {
|
||||
// TODO(Babel 8) This polyfills are only needed for Node.js 6 and 8
|
||||
/** @param {import("@babel/core")} api */
|
||||
function pluginPolyfillsOldNode({ template, types: t }) {
|
||||
const polyfills = [
|
||||
{
|
||||
name: "require.resolve",
|
||||
necessary({ node, parent }) {
|
||||
return (
|
||||
t.isCallExpression(parent, { callee: node }) &&
|
||||
parent.arguments.length > 1
|
||||
);
|
||||
},
|
||||
supported({ parent: { arguments: args } }) {
|
||||
return (
|
||||
t.isObjectExpression(args[1]) &&
|
||||
args[1].properties.length === 1 &&
|
||||
t.isIdentifier(args[1].properties[0].key, { name: "paths" }) &&
|
||||
t.isArrayExpression(args[1].properties[0].value) &&
|
||||
args[1].properties[0].value.elements.length === 1
|
||||
);
|
||||
},
|
||||
// require.resolve's paths option has been introduced in Node.js 8.9
|
||||
// https://nodejs.org/api/modules.html#modules_require_resolve_request_options
|
||||
replacement: template({ syntacticPlaceholders: true })`
|
||||
parseFloat(process.versions.node) >= 8.9
|
||||
? require.resolve
|
||||
: (/* request */ r, { paths: [/* base */ b] }, M = require("module")) => {
|
||||
let /* filename */ f = M._findPath(r, M._nodeModulePaths(b).concat(b));
|
||||
if (f) return f;
|
||||
f = new Error(\`Cannot resolve module '\${r}'\`);
|
||||
f.code = "MODULE_NOT_FOUND";
|
||||
throw f;
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
// NOTE: This polyfills depends on the "make-dir" library. Any package
|
||||
// using fs.mkdirSync must have "make-dir" as a dependency.
|
||||
name: "fs.mkdirSync",
|
||||
necessary({ node, parent }) {
|
||||
return (
|
||||
t.isCallExpression(parent, { callee: node }) &&
|
||||
parent.arguments.length > 1
|
||||
);
|
||||
},
|
||||
supported({ parent: { arguments: args } }) {
|
||||
return (
|
||||
t.isObjectExpression(args[1]) &&
|
||||
args[1].properties.length === 1 &&
|
||||
t.isIdentifier(args[1].properties[0].key, { name: "recursive" }) &&
|
||||
t.isBooleanLiteral(args[1].properties[0].value, { value: true })
|
||||
);
|
||||
},
|
||||
// fs.mkdirSync's recursive option has been introduced in Node.js 10.12
|
||||
// https://nodejs.org/api/fs.html#fs_fs_mkdirsync_path_options
|
||||
replacement: template`
|
||||
parseFloat(process.versions.node) >= 10.12
|
||||
? fs.mkdirSync
|
||||
: require("make-dir").sync
|
||||
`,
|
||||
},
|
||||
{
|
||||
// NOTE: This polyfills depends on the "node-environment-flags"
|
||||
// library. Any package using process.allowedNodeEnvironmentFlags
|
||||
// must have "node-environment-flags" as a dependency.
|
||||
name: "process.allowedNodeEnvironmentFlags",
|
||||
necessary({ parent, node }) {
|
||||
// To avoid infinite replacement loops
|
||||
return !t.isLogicalExpression(parent, { operator: "||", left: node });
|
||||
},
|
||||
supported: () => true,
|
||||
// process.allowedNodeEnvironmentFlags has been introduced in Node.js 10.10
|
||||
// https://nodejs.org/api/process.html#process_process_allowednodeenvironmentflags
|
||||
replacement: template`
|
||||
process.allowedNodeEnvironmentFlags || require("node-environment-flags")
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
MemberExpression(path) {
|
||||
if (!path.matchesPattern("require.resolve")) return;
|
||||
if (!t.isCallExpression(path.parent, { callee: path.node })) return;
|
||||
for (const polyfill of polyfills) {
|
||||
if (!path.matchesPattern(polyfill.name)) continue;
|
||||
|
||||
const args = path.parent.arguments;
|
||||
if (args.length < 2) return;
|
||||
if (
|
||||
!t.isObjectExpression(args[1]) ||
|
||||
args[1].properties.length !== 1 ||
|
||||
!t.isIdentifier(args[1].properties[0].key, { name: "paths" }) ||
|
||||
!t.isArrayExpression(args[1].properties[0].value) ||
|
||||
args[1].properties[0].value.elements.length !== 1
|
||||
) {
|
||||
throw path.parentPath.buildCodeFrameError(
|
||||
"This 'require.resolve' usage is not supported by the inline polyfill."
|
||||
);
|
||||
if (!polyfill.necessary(path)) return;
|
||||
if (!polyfill.supported(path)) {
|
||||
throw path.buildCodeFrameError(
|
||||
`This '${polyfill.name}' usage is not supported by the inline polyfill.`
|
||||
);
|
||||
}
|
||||
|
||||
path.replaceWith(polyfill.replacement());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// require.resolve's paths option has been introduced in Node.js 8.9
|
||||
// https://nodejs.org/api/modules.html#modules_require_resolve_request_options
|
||||
path.replaceWith(template.ast`
|
||||
parseFloat(process.versions.node) >= 8.9
|
||||
? require.resolve
|
||||
: (/* request */ r, { paths: [/* base */ b] }, M = require("module")) => {
|
||||
let /* filename */ f = M._findPath(r, M._nodeModulePaths(b).concat(b));
|
||||
if (f) return f;
|
||||
f = new Error(\`Cannot resolve module '\${r}'\`);
|
||||
f.code = "MODULE_NOT_FOUND";
|
||||
throw f;
|
||||
}
|
||||
`);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
// @flow
|
||||
|
||||
import debounce from "lodash/debounce";
|
||||
import { sync as makeDirSync } from "make-dir";
|
||||
import slash from "slash";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
@ -17,7 +16,7 @@ const FILE_TYPE = Object.freeze({
|
||||
});
|
||||
|
||||
function outputFileSync(filePath: string, data: string | Buffer): void {
|
||||
makeDirSync(path.dirname(filePath));
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
fs.writeFileSync(filePath, data);
|
||||
}
|
||||
|
||||
@ -163,7 +162,7 @@ export default async function ({
|
||||
util.deleteDir(cliOptions.outDir);
|
||||
}
|
||||
|
||||
makeDirSync(cliOptions.outDir);
|
||||
fs.mkdirSync(cliOptions.outDir, { recursive: true });
|
||||
|
||||
startTime = process.hrtime();
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
import convertSourceMap from "convert-source-map";
|
||||
import sourceMap from "source-map";
|
||||
import slash from "slash";
|
||||
import { sync as makeDirSync } from "make-dir";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
@ -89,7 +88,7 @@ export default async function ({
|
||||
const result = buildResult(fileResults);
|
||||
|
||||
if (cliOptions.outFile) {
|
||||
makeDirSync(path.dirname(cliOptions.outFile));
|
||||
fs.mkdirSync(path.dirname(cliOptions.outFile), { recursive: true });
|
||||
|
||||
// we've requested for a sourcemap to be written to disk
|
||||
if (babelOptions.sourceMaps && babelOptions.sourceMaps !== "inline") {
|
||||
|
||||
@ -6,10 +6,6 @@
|
||||
import getV8Flags from "v8flags";
|
||||
import path from "path";
|
||||
|
||||
// TODO: When support for node < 10.10 will be dropped, this package
|
||||
// can be replaced with process.allowedNodeEnvironmentFlags
|
||||
import allowedNodeEnvironmentFlags from "node-environment-flags";
|
||||
|
||||
let args = [path.join(__dirname, "_babel-node")];
|
||||
|
||||
let babelArgs = process.argv.slice(2);
|
||||
@ -59,7 +55,7 @@ getV8Flags(function (err, v8Flags) {
|
||||
flag === "debug" || // node debug foo.js
|
||||
flag === "inspect" ||
|
||||
v8Flags.indexOf(getNormalizedV8Flag(flag)) >= 0 ||
|
||||
allowedNodeEnvironmentFlags.has(flag)
|
||||
process.allowedNodeEnvironmentFlags.has(flag)
|
||||
) {
|
||||
args.unshift(arg);
|
||||
} else {
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const makeDirSync = require("make-dir").sync;
|
||||
const helpers = require("@babel/helpers");
|
||||
const babel = require("@babel/core");
|
||||
const template = require("@babel/template");
|
||||
@ -15,7 +14,7 @@ const corejs2Definitions = require("../lib/runtime-corejs2-definitions").default
|
||||
const corejs3Definitions = require("../lib/runtime-corejs3-definitions").default();
|
||||
|
||||
function outputFile(filePath, data) {
|
||||
makeDirSync(path.dirname(filePath));
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
fs.writeFileSync(filePath, data);
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import { sync as makeDirSync } from "make-dir";
|
||||
import * as babel from "@babel/core";
|
||||
import findCacheDir from "find-cache-dir";
|
||||
|
||||
@ -39,7 +38,7 @@ export function save() {
|
||||
}
|
||||
|
||||
try {
|
||||
makeDirSync(path.dirname(FILENAME));
|
||||
fs.mkdirSync(path.dirname(FILENAME), { recursive: true });
|
||||
fs.writeFileSync(FILENAME, serialised);
|
||||
} catch (e) {
|
||||
switch (e.code) {
|
||||
@ -49,14 +48,14 @@ export function save() {
|
||||
case "EACCES":
|
||||
case "EPERM":
|
||||
console.warn(
|
||||
`Babel could not write cache to file: ${FILENAME}
|
||||
`Babel could not write cache to file: ${FILENAME}
|
||||
due to a permission issue. Cache is disabled.`,
|
||||
);
|
||||
cacheDisabled = true;
|
||||
break;
|
||||
case "EROFS":
|
||||
console.warn(
|
||||
`Babel could not write cache to file: ${FILENAME}
|
||||
`Babel could not write cache to file: ${FILENAME}
|
||||
because it resides in a readonly filesystem. Cache is disabled.`,
|
||||
);
|
||||
cacheDisabled = true;
|
||||
|
||||
@ -77,7 +77,13 @@ describe("@babel/register", function () {
|
||||
cleanCache();
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
afterEach(async () => {
|
||||
// @babel/register saves the cache on process.nextTick.
|
||||
// We need to wait for at least one tick so that when jest
|
||||
// tears down the testing environment @babel/register has
|
||||
// already finished.
|
||||
await new Promise(setImmediate);
|
||||
|
||||
revertRegister();
|
||||
currentHook = null;
|
||||
currentOptions = null;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user