or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

dynamic-imports.mdindex.mdlazy-loading.mdmodule-metadata.mdmodule-names.mdmodule-transformation.md
tile.json

dynamic-imports.mddocs/

Dynamic Imports

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.

Capabilities

Dynamic Import Builder

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 expression
  • deferToThen - Whether to defer execution using Promise.resolve().then()
  • wrapWithPromise - Whether to wrap the result in a Promise
  • builder - Function that transforms the import specifier into the target expression

Usage 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)

Dynamic Import Source Extraction (Legacy)

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")])

Implementation Details

String Literal Handling

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"))

Computed Import Handling

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)

Template Literal Conversion

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}`