diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7ba56891acb5..24ee25de11ec 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -46,7 +46,6 @@ module.exports = { "@babel/development/no-deprecated-clone": "error", "guard-for-in": "error", "import/extensions": ["error", { json: "always", cjs: "always" }], - "no-restricted-globals": ["error", ...cjsGlobals], }, globals: { PACKAGE_JSON: "readonly" }, }, @@ -73,6 +72,9 @@ module.exports = { }, { files: [ + "packages/*/src/**/*.{js,ts}", + "codemods/*/src/**/*.{js,ts}", + "eslint/*/src/**/*.{js,ts}", "packages/*/test/**/*.js", "codemods/*/test/**/*.js", "eslint/*/test/**/*.js", @@ -81,7 +83,7 @@ module.exports = { ], excludedFiles: [ // @babel/register is the require() hook, so it will always be CJS-based - "packages/babel-register/test/**/*.js", + "packages/babel-register/**/*.js", ], rules: { "no-restricted-globals": ["error", ...cjsGlobals], diff --git a/babel.config.js b/babel.config.js index cce8c854f426..c18c39d16263 100644 --- a/babel.config.js +++ b/babel.config.js @@ -473,12 +473,18 @@ function pluginImportMetaUrl({ types: t }) { t.isIdentifier(node.meta, { name: "import" }) && t.isIdentifier(node.property, { name: "meta" }); + const isImportMetaUrl = node => + t.isMemberExpression(node, { computed: false }) && + t.isIdentifier(node.property, { name: "url" }) && + isImportMeta(node.object); + return { visitor: { Program(programPath) { // We must be sure to run this before the instanbul plugins, because its // instrumentation breaks our detection. programPath.traverse({ + // fileURLToPath(import.meta.url) CallExpression(path) { const { node } = path; @@ -501,6 +507,25 @@ function pluginImportMetaUrl({ types: t }) { path.replaceWith(t.identifier("__filename")); }, + + // const require = createRequire(import.meta.url) + VariableDeclarator(path) { + const { node } = path; + + if ( + !t.isIdentifier(node.id, { name: "require" }) || + !t.isCallExpression(node.init) || + !t.isIdentifier(node.init.callee, { name: "createRequire" }) || + node.init.arguments.length !== 1 || + !isImportMetaUrl(node.init.arguments[0]) + ) { + return; + } + + // Let's just remove this declaration to unshadow the "global" cjs require. + path.remove(); + }, + MetaProperty(path) { if (isImportMeta(path.node)) { throw path.buildCodeFrameError("Unsupported import.meta"); diff --git a/lib/third-party-libs.js.flow b/lib/third-party-libs.js.flow index f114c0bc1ef6..fb405b854c7e 100644 --- a/lib/third-party-libs.js.flow +++ b/lib/third-party-libs.js.flow @@ -2,6 +2,10 @@ * Basic declarations for the npm modules we use. */ + declare module "module" { + declare export function createRequire(url: any): any; + } + declare module "debug" { declare export default (namespace: string) => (formatter: string, ...args: any[]) => void; } diff --git a/packages/babel-cli/src/babel/util.js b/packages/babel-cli/src/babel/util.js index 5dfa6217bca5..70d2c6b48d4b 100644 --- a/packages/babel-cli/src/babel/util.js +++ b/packages/babel-cli/src/babel/util.js @@ -4,6 +4,7 @@ import readdirRecursive from "fs-readdir-recursive"; import * as babel from "@babel/core"; import path from "path"; import fs from "fs"; +import { createRequire } from "module"; export function chmod(src: string, dest: string): void { try { @@ -119,6 +120,9 @@ process.on("uncaughtException", function (err) { }); export function requireChokidar(): Object { + // $FlowIgnore - https://github.com/facebook/flow/issues/6913#issuecomment-662787504 + const require = createRequire(import /*::("")*/.meta.url); + try { // todo(babel 8): revert `@nicolo-ribaudo/chokidar-2` hack return parseInt(process.versions.node) >= 8 diff --git a/packages/babel-core/src/config/files/configuration.js b/packages/babel-core/src/config/files/configuration.js index 45162669757e..fe3da4593ad3 100644 --- a/packages/babel-core/src/config/files/configuration.js +++ b/packages/babel-core/src/config/files/configuration.js @@ -18,6 +18,10 @@ import type { CallerMetadata } from "../validation/options"; import * as fs from "../../gensync-utils/fs"; +import { createRequire } from "module"; +// $FlowIgnore - https://github.com/facebook/flow/issues/6913#issuecomment-662787504 +const require = createRequire(import /*::("")*/.meta.url); + const debug = buildDebug("babel:config:loading:files:configuration"); export const ROOT_CONFIG_FILENAMES = [ diff --git a/packages/babel-core/src/config/files/module-types.js b/packages/babel-core/src/config/files/module-types.js index 0e6d4a431886..de75ada49337 100644 --- a/packages/babel-core/src/config/files/module-types.js +++ b/packages/babel-core/src/config/files/module-types.js @@ -2,6 +2,9 @@ import { isAsync, waitFor } from "../../gensync-utils/async"; import type { Handler } from "gensync"; import path from "path"; import { pathToFileURL } from "url"; +import { createRequire } from "module"; + +const require = createRequire(import.meta.url); let import_; try { diff --git a/packages/babel-core/src/config/files/plugins.js b/packages/babel-core/src/config/files/plugins.js index 747592cad9bd..4e2f4ba88e27 100644 --- a/packages/babel-core/src/config/files/plugins.js +++ b/packages/babel-core/src/config/files/plugins.js @@ -9,6 +9,10 @@ import path from "path"; import { type Handler } from "gensync"; import loadCjsOrMjsDefault from "./module-types"; +import { createRequire } from "module"; +// $FlowIgnore - https://github.com/facebook/flow/issues/6913#issuecomment-662787504 +const require = createRequire(import /*::("")*/.meta.url); + const debug = buildDebug("babel:config:loading:files:plugins"); const EXACT_RE = /^module:/; diff --git a/packages/babel-helper-fixtures/src/index.ts b/packages/babel-helper-fixtures/src/index.ts index 5c4c4bd203a1..2f8beb723497 100644 --- a/packages/babel-helper-fixtures/src/index.ts +++ b/packages/babel-helper-fixtures/src/index.ts @@ -3,6 +3,9 @@ import semver from "semver"; import path from "path"; import fs from "fs"; import { fileURLToPath } from "url"; +import { createRequire } from "module"; + +const require = createRequire(import.meta.url); const nodeVersion = semver.clean(process.version.slice(1)); diff --git a/packages/babel-helper-transform-fixture-test-runner/src/index.js b/packages/babel-helper-transform-fixture-test-runner/src/index.js index f79868cef081..146f1ae90454 100644 --- a/packages/babel-helper-transform-fixture-test-runner/src/index.js +++ b/packages/babel-helper-transform-fixture-test-runner/src/index.js @@ -17,6 +17,9 @@ import QuickLRU from "quick-lru"; import escapeRegExp from "./escape-regexp.cjs"; import { fileURLToPath } from "url"; +import { createRequire } from "module"; +const require = createRequire(import.meta.url); + import _checkDuplicatedNodes from "babel-check-duplicated-nodes"; const checkDuplicatedNodes = _checkDuplicatedNodes.default; diff --git a/packages/babel-node/src/_babel-node.js b/packages/babel-node/src/_babel-node.js index 4c19979c607c..9792d975831a 100644 --- a/packages/babel-node/src/_babel-node.js +++ b/packages/babel-node/src/_babel-node.js @@ -10,6 +10,9 @@ import "regenerator-runtime/runtime"; import register from "@babel/register"; import { fileURLToPath } from "url"; +import { createRequire } from "module"; +const require = createRequire(import.meta.url); + const program = new commander.Command("babel-node"); function collect(value, previousValue): Array { diff --git a/packages/babel-plugin-transform-runtime/src/get-runtime-path/index.js b/packages/babel-plugin-transform-runtime/src/get-runtime-path/index.js index c7a9c09d9228..56e3a5a1ed49 100644 --- a/packages/babel-plugin-transform-runtime/src/get-runtime-path/index.js +++ b/packages/babel-plugin-transform-runtime/src/get-runtime-path/index.js @@ -1,5 +1,8 @@ import path from "path"; +import { createRequire } from "module"; +const require = createRequire(import.meta.url); + export default function (moduleName, dirname, absoluteRuntime) { if (absoluteRuntime === false) return moduleName;