diff --git a/babel.config.js b/babel.config.js index a763f5c2e4b9..d09102538b47 100644 --- a/babel.config.js +++ b/babel.config.js @@ -158,6 +158,7 @@ module.exports = function (api) { convertESM ? "@babel/proposal-export-namespace-from" : null, convertESM ? "@babel/transform-modules-commonjs" : null, + convertESM ? pluginNodeImportInterop : null, pluginPackageJsonMacro, @@ -413,3 +414,54 @@ function pluginPackageJsonMacro({ types: t }) { }, }; } + +// Match the Node.js behavior (the default import is module.exports) +function pluginNodeImportInterop({ template }) { + return { + visitor: { + ImportDeclaration(path) { + const specifiers = path.get("specifiers"); + if (specifiers.length === 0) { + return; + } + + const { source } = path.node; + if ( + source.value.startsWith(".") || + source.value.startsWith("@babel/") || + source.value === "charcodes" + ) { + // For internal modules, it's either "all CJS" or "all ESM". + // We don't need to worry about interop. + return; + } + + const defImport = specifiers.find(s => s.isImportDefaultSpecifier()); + const nsImport = specifiers.find(s => s.isImportNamespaceSpecifier()); + + if (defImport) { + path.insertAfter( + template.ast` + const ${defImport.node.local} = require(${source}); + ` + ); + defImport.remove(); + } + + if (nsImport) { + path.insertAfter( + template.ast` + const ${nsImport.node.local} = { + ...require(${source}), + default: require(${source}), + }; + ` + ); + nsImport.remove(); + } + + if (path.node.specifiers.length === 0) path.remove(); + }, + }, + }; +} diff --git a/lib/babel-polyfills.js.flow b/lib/babel-polyfills.js.flow index cd137e17cb89..3187b1d95f24 100644 --- a/lib/babel-polyfills.js.flow +++ b/lib/babel-polyfills.js.flow @@ -1,9 +1,9 @@ declare module "babel-plugin-polyfill-regenerator" { - declare module.exports: Function; + declare module.exports: { default: Function }; } declare module "babel-plugin-polyfill-corejs2" { - declare module.exports: Function; + declare module.exports: { default: Function }; } declare module "babel-plugin-polyfill-corejs3" { - declare module.exports: Function; + declare module.exports: { default: Function }; } 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 138325388071..511df65feca0 100644 --- a/packages/babel-helper-transform-fixture-test-runner/src/index.js +++ b/packages/babel-helper-transform-fixture-test-runner/src/index.js @@ -13,10 +13,12 @@ import assert from "assert"; import fs from "fs"; import path from "path"; import vm from "vm"; -import checkDuplicatedNodes from "babel-check-duplicated-nodes"; import QuickLRU from "quick-lru"; import escapeRegExp from "./escape-regexp.cjs"; +import _checkDuplicatedNodes from "babel-check-duplicated-nodes"; +const checkDuplicatedNodes = _checkDuplicatedNodes.default; + const EXTERNAL_HELPERS_VERSION = "7.100.0"; const cachedScripts = new QuickLRU({ maxSize: 10 }); diff --git a/packages/babel-highlight/src/index.ts b/packages/babel-highlight/src/index.ts index 6ef68de5fe88..373f37edcd7e 100644 --- a/packages/babel-highlight/src/index.ts +++ b/packages/babel-highlight/src/index.ts @@ -1,7 +1,8 @@ /// -import jsTokens, * as jsTokensNs from "js-tokens"; import type { Token, JSXToken } from "js-tokens"; +import jsTokens from "js-tokens"; + import { isStrictReservedWord, isKeyword, @@ -158,9 +159,6 @@ if (process.env.BABEL_8_BREAKING) { } }; } else { - // This is only available in js-tokens@4, and not in js-tokens@6 - const { matchToToken } = jsTokensNs as any; - /** * RegExp to test for what seems to be a JSX tag name. */ @@ -204,8 +202,8 @@ if (process.env.BABEL_8_BREAKING) { tokenize = function* (text: string) { let match; - while ((match = (jsTokens as any).exec(text))) { - const token = matchToToken(match); + while ((match = (jsTokens as any).default.exec(text))) { + const token = (jsTokens as any).matchToToken(match); yield { type: getTokenType(token, match.index, text), diff --git a/packages/babel-plugin-transform-runtime/src/index.js b/packages/babel-plugin-transform-runtime/src/index.js index 5af64df8ab00..1893b9d410cf 100644 --- a/packages/babel-plugin-transform-runtime/src/index.js +++ b/packages/babel-plugin-transform-runtime/src/index.js @@ -5,9 +5,12 @@ import { types as t } from "@babel/core"; import { hasMinVersion } from "./helpers"; import getRuntimePath from "./get-runtime-path"; -import pluginCorejs2 from "babel-plugin-polyfill-corejs2"; -import pluginCorejs3 from "babel-plugin-polyfill-corejs3"; -import pluginRegenerator from "babel-plugin-polyfill-regenerator"; +import _pluginCorejs2 from "babel-plugin-polyfill-corejs2"; +import _pluginCorejs3 from "babel-plugin-polyfill-corejs3"; +import _pluginRegenerator from "babel-plugin-polyfill-regenerator"; +const pluginCorejs2 = _pluginCorejs2.default; +const pluginCorejs3 = _pluginCorejs3.default; +const pluginRegenerator = _pluginRegenerator.default; const pluginsCompat = "#__secret_key__@babel/runtime__compatibility"; diff --git a/packages/babel-preset-env/src/index.js b/packages/babel-preset-env/src/index.js index 4fd86e674bf1..5e3a9e5e2641 100644 --- a/packages/babel-preset-env/src/index.js +++ b/packages/babel-preset-env/src/index.js @@ -16,9 +16,12 @@ import overlappingPlugins from "@babel/compat-data/overlapping-plugins"; import removeRegeneratorEntryPlugin from "./polyfills/regenerator"; import legacyBabelPolyfillPlugin from "./polyfills/babel-polyfill"; -import pluginCoreJS2 from "babel-plugin-polyfill-corejs2"; -import pluginCoreJS3 from "babel-plugin-polyfill-corejs3"; -import pluginRegenerator from "babel-plugin-polyfill-regenerator"; +import _pluginCoreJS2 from "babel-plugin-polyfill-corejs2"; +import _pluginCoreJS3 from "babel-plugin-polyfill-corejs3"; +import _pluginRegenerator from "babel-plugin-polyfill-regenerator"; +const pluginCoreJS2 = _pluginCoreJS2.default; +const pluginCoreJS3 = _pluginCoreJS3.default; +const pluginRegenerator = _pluginRegenerator.default; import getTargets, { prettifyTargets,