@babel/node
Version:
Babel command line
245 lines (241 loc) • 7.65 kB
JavaScript
import path from 'node:path';
import child_process from 'node:child_process';
import { fileURLToPath } from 'node:url';
import getV8FlagsRaw from 'v8flags';
import { program } from './program-setup-shared.js';
const _nodeFlagsWithValue = [
"--allow-fs-read",
"--allow-fs-write",
"--build-sea",
"--build-snapshot-config",
"--conditions",
"--cpu-prof-dir",
"--cpu-prof-interval",
"--cpu-prof-name",
"--diagnostic-dir",
"--disable-proto",
"--disable-warning",
"--dns-result-order",
"--env-file",
"--env-file-if-exists",
"--eval",
"--experimental-config-file",
"--experimental-default-type",
"--experimental-loader",
"--experimental-policy",
"--experimental-sea-config",
"--experimental-specifier-resolution",
"--experimental-test-isolation",
"--heap-prof-dir",
"--heap-prof-interval",
"--heap-prof-name",
"--heapsnapshot-near-heap-limit",
"--heapsnapshot-signal",
"--http-parser",
"--http-server-default-timeout",
"--icu-data-dir",
"--import",
"--input-type",
"--inspect",
"--inspect-brk",
"--inspect-port",
"--inspect-publish-uid",
"--inspect-wait",
"--loader",
"--localstorage-file",
"--max-http-header-size",
"--max-old-space-size-percentage",
"--network-family-autoselection-attempt-timeout",
"--openssl-config",
"--policy-integrity",
"--print",
"--redirect-warnings",
"--report-dir",
"--report-filename",
"--report-signal",
"--require",
"--run",
"--secure-heap",
"--secure-heap-min",
"--snapshot-blob",
"--test-concurrency",
"--test-coverage-branches",
"--test-coverage-exclude",
"--test-coverage-functions",
"--test-coverage-include",
"--test-coverage-lines",
"--test-global-setup",
"--test-isolation",
"--test-name-pattern",
"--test-random-seed",
"--test-reporter",
"--test-reporter-destination",
"--test-rerun-failures",
"--test-shard",
"--test-skip-pattern",
"--test-timeout",
"--title",
"--tls-cipher-list",
"--tls-keylog",
"--trace-event-categories",
"--trace-event-file-pattern",
"--trace-require-module",
"--unhandled-rejections",
"--use-largepages",
"--v8-pool-size",
"--watch-kill-signal",
"--watch-path",
"-C",
"-e",
"-p",
"-r"
];
const nodeFlagsWithValue = new Set(_nodeFlagsWithValue);
const nodeFlagsWithNoFile = new Set(["-p", "--print", "-e", "--eval"]);
function splitArgs(argv, extraOptionsWithValue) {
const programArgs = [];
let explicitSeparator = false;
let ignoreFileName = null;
let i = 0;
for (; i < argv.length; i++) {
const arg = argv[i];
if (arg === "-") break;
if (arg === "--") {
explicitSeparator = true;
i++;
break;
}
if (arg.startsWith("-")) {
programArgs.push(arg);
if ((nodeFlagsWithValue.has(arg) || extraOptionsWithValue?.has(arg)) && i < argv.length - 1 && !argv[i + 1].startsWith("-")) {
i++;
programArgs.push(argv[i]);
}
if (nodeFlagsWithNoFile.has(arg)) ignoreFileName ??= true;
} else if (i === 0 && arg === "inspect") {
programArgs.push(arg);
ignoreFileName = false;
} else {
break;
}
}
const fileName = !ignoreFileName && i < argv.length ? argv[i++] : null;
const userArgs = argv.slice(i);
return {
programArgs,
fileName,
userArgs,
explicitSeparator
};
}
function getV8Flags() {
function getNormalizedV8Flag(arg) {
const matches = /--(?:no)?(.+)/.exec(arg);
if (matches) {
return `--${matches[1].replace(/_/g, "-")}`;
}
return arg;
}
return new Promise((resolve, reject) => {
getV8FlagsRaw((err, flags) => {
if (err) {
reject(err);
return;
}
const flagsSet = new Set(flags.map(getNormalizedV8Flag));
resolve(test => flagsSet.has(getNormalizedV8Flag(test)) || process.allowedNodeEnvironmentFlags.has(test));
});
});
}
const babelNodePath = path.join(path.dirname(fileURLToPath(import.meta.url)), "_babel-node");
(async () => {
const babelOptions = new Set([]);
const babelOptionsWithValue = new Set([]);
for (const option of program.options) {
const hasValue = option.flags.includes("[");
if (option.short) {
babelOptions.add(option.short);
if (hasValue) babelOptionsWithValue.add(option.short);
}
if (option.long) {
babelOptions.add(option.long);
if (hasValue) babelOptionsWithValue.add(option.long);
}
}
const {
programArgs,
fileName,
userArgs,
explicitSeparator
} = splitArgs(process.argv.slice(2), babelOptionsWithValue);
const babelArgs = [];
const nodeArgs = [];
for (let i = 0; i < programArgs.length; i++) {
const arg = programArgs[i];
const list = babelOptions.has(arg.split("=")[0]) ? babelArgs : nodeArgs;
list.push(arg);
if (i + 1 < programArgs.length && !programArgs[i + 1].startsWith("-")) {
list.push(programArgs[++i]);
}
}
if (!explicitSeparator) {
const isV8flag = await getV8Flags();
const ambiguousArgsNames = [];
const ambiguousArgs = [];
let unambiguousArgs = null;
for (let i = 0; i < userArgs.length; i++) {
const [arg, value] = userArgs[i].split("=");
if (babelOptions.has(arg) || isV8flag(arg)) {
unambiguousArgs ??= userArgs.slice(0, i);
ambiguousArgsNames.push(arg);
ambiguousArgs.push(userArgs[i]);
if (value === undefined && (babelOptionsWithValue.has(arg) || nodeFlagsWithValue.has(arg)) && i + 1 < userArgs.length) {
ambiguousArgs.push(userArgs[++i]);
}
} else {
unambiguousArgs?.push(userArgs[i]);
}
}
if (ambiguousArgsNames.length > 0) {
const them = ambiguousArgsNames.length === 1 ? "it" : "them";
const they = ambiguousArgsNames.length === 1 ? "it" : "they";
const are = ambiguousArgsNames.length === 1 ? "is" : "are";
console.warn(`Warning: ${ambiguousArgsNames.join(", ")} ${are} a valid option for Babel or Node.js, ` + `but ${they} ${are} defined after the script name. Up to Babel 7 ${they} would have ` + `been passed to Babel, while now ${they} ${are} passed to the script itself.\n` + ` If the intention is to pass ${them} to Babel, move ${them} before the filename:\n` + ` babel-node ${programArgs.join(" ")} ${ambiguousArgs.join(" ")} ${fileName} ${unambiguousArgs.join(" ")}\n` + ` If passing ${them} to the script is intended, you can silence this warning by explicitly ` + `using the -- separator before the script name:\n` + ` babel-node ${programArgs.join(" ")} -- ${fileName} ${userArgs.join(" ")}`);
}
}
await spawn([...nodeArgs, "--", babelNodePath, ...babelArgs, "--", fileName, ...userArgs]);
})().catch(err => {
console.error(err);
process.exitCode = 1;
});
async function spawn(args) {
try {
const {
default: kexec
} = await import('kexec');
kexec(process.argv[0], args);
} catch (err) {
if (err.code !== "ERR_MODULE_NOT_FOUND" && err.code !== "MODULE_NOT_FOUND" && err.code !== "UNDECLARED_DEPENDENCY") {
throw err;
}
const shouldPassthroughIPC = process.send !== undefined;
const proc = child_process.spawn(process.argv[0], args, {
stdio: shouldPassthroughIPC ? ["inherit", "inherit", "inherit", "ipc"] : "inherit"
});
proc.on("exit", function (code, signal) {
process.on("exit", function () {
if (signal) {
process.kill(process.pid, signal);
} else {
process.exitCode = code ?? undefined;
}
});
});
if (shouldPassthroughIPC) {
proc.on("message", message => process.send(message));
}
process.on("SIGINT", () => proc.kill("SIGINT"));
process.on("SIGTERM", () => proc.kill("SIGTERM"));
}
}
//# sourceMappingURL=babel-node.js.map