Support for transforming dynamic import expressions with various promise wrapping and deferring strategies. These utilities help transform import() expressions into different target formats while maintaining proper asynchronous behavior.
Transform dynamic import expressions with configurable wrapping strategies.
/**
* Build dynamic import expressions with various wrapping strategies.
* Handles both string literals and computed import specifiers.
*/
function buildDynamicImport(
node: CallExpression | ImportExpression,
deferToThen: boolean,
wrapWithPromise: boolean,
builder: (specifier: Expression) => Expression
): Expression;Parameters:
node - The original dynamic import call or import expressiondeferToThen - Whether to defer execution using Promise.resolve().then()wrapWithPromise - Whether to wrap the result in a Promisebuilder - Function that transforms the import specifier into the target expressionUsage Examples:
import { buildDynamicImport } from "@babel/helper-module-transforms";
import { types as t } from "@babel/core";
// Transform import("./module") to require("./module") with Promise wrapping
const dynamicImport = t.callExpression(t.import(), [t.stringLiteral("./module")]);
const transformed = buildDynamicImport(
dynamicImport,
false, // Don't defer to then
true, // Wrap with Promise
(specifier) => t.callExpression(t.identifier("require"), [specifier])
);
// Result: new Promise(r => r(require("./module")))
// Transform with deferred execution for string literals
const deferredTransform = buildDynamicImport(
dynamicImport,
true, // Defer to then
false, // Don't wrap with Promise
(specifier) => t.callExpression(t.identifier("require"), [specifier])
);
// Result: Promise.resolve().then(() => require("./module"))
// Transform computed dynamic imports
const computedImport = t.callExpression(t.import(), [t.identifier("moduleName")]);
const computedTransform = buildDynamicImport(
computedImport,
false,
true,
(specifier) => t.callExpression(t.identifier("require"), [specifier])
);
// Result: (specifier => new Promise(r => r(require(`${specifier}`))))(moduleName)Extract the source specifier from dynamic import expressions (Babel 7 compatibility).
/**
* Extract source from dynamic import node.
* Only available in CommonJS environments for Babel 7 compatibility.
* @deprecated This function is only available in legacy Babel 7 builds
*/
function getDynamicImportSource(
node: CallExpression
): StringLiteral | TemplateLiteral;Note: This function is only available when process.env.BABEL_8_BREAKING is falsy and in CommonJS environments. It's provided for backward compatibility with existing Babel 7 plugins.
Usage Example (Babel 7 only):
// Only available in CommonJS environments
const { getDynamicImportSource } = require("@babel/helper-module-transforms");
// Extract source from import() call
const importCall = t.callExpression(t.import(), [t.stringLiteral("./module")]);
const source = getDynamicImportSource(importCall);
// Returns: t.stringLiteral("./module")
// Handles template literals
const computedImport = t.callExpression(t.import(), [t.identifier("moduleName")]);
const computedSource = getDynamicImportSource(computedImport);
// Returns: t.templateLiteral([...], [t.identifier("moduleName")])When the import specifier is a string literal or an empty template literal, the transformation is straightforward:
// Direct transformation without wrapping
import("./module") → require("./module")
// With promise deferring
import("./module") → Promise.resolve().then(() => require("./module"))For computed imports (variables or expressions), the specifier is converted to a string and wrapped in an IIFE:
// Without promise wrapping
import(moduleName) → (specifier => require(`${specifier}`))(moduleName)
// With promise wrapping
import(moduleName) → (specifier => new Promise(r => r(require(`${specifier}`))))(moduleName)
// With deferred execution
import(moduleName) → (specifier =>
new Promise(r => r(`${specifier}`))
.then(s => require(s))
)(moduleName)The transformer automatically handles template literal conversion for computed imports:
// Variable specifier gets wrapped in template literal
const specifierToString = t.templateLiteral(
[t.templateElement({ raw: "" }), t.templateElement({ raw: "" })],
[t.identifier("specifier")]
);
// Results in: `${specifier}`