Support for lazy module loading with configurable lazy loading strategies. This functionality helps optimize bundle size and loading performance by deferring module initialization until first access.
Note: The lazy loading utilities are internal to the package and not directly exported. They are used through the lazy option in rewriteModuleStatementsAndPrepareHeader and related configuration functions.
Configure which modules should be loaded lazily.
/**
* Configuration for lazy module loading.
* - boolean: true = lazy load external modules, false = eager load all
* - string[]: array of module names to load lazily
* - function: custom function to determine lazy loading per module
*/
type Lazy = boolean | string[] | ((source: string) => boolean);Convert lazy configuration into a function that determines wrapper payloads.
/**
* Convert lazy configuration to a wrapper payload getter function.
* Returns a function that determines if a module should be lazy loaded.
*/
function toGetWrapperPayload(
lazy: Lazy
): (source: string, metadata: SourceModuleMetadata) => null | "lazy";Usage Examples:
// Note: These functions are internal utilities and not directly exported.
// They are used internally by rewriteModuleStatementsAndPrepareHeader
// when the lazy option is provided.
// Example of how lazy loading is configured (conceptually):
const lazyConfig: Lazy = true; // Boolean configuration - lazy load external modules only
console.log(booleanPayload("./local-file.js", metadata)); // null (eager)
console.log(booleanPayload("lodash", metadata)); // "lazy"
// Array configuration - specific modules to lazy load
const arrayPayload = Lazy.toGetWrapperPayload(["lodash", "moment"]);
console.log(arrayPayload("lodash", metadata)); // "lazy"
console.log(arrayPayload("react", metadata)); // null (eager)
// Function configuration - custom logic
const fnPayload = Lazy.toGetWrapperPayload((source) => {
return source.startsWith("@babel/") || source.includes("heavy-lib");
});
console.log(fnPayload("@babel/core", metadata)); // "lazy"
console.log(fnPayload("react", metadata)); // null (eager)
// Disabled lazy loading
const eagerPayload = Lazy.toGetWrapperPayload(false);
console.log(eagerPayload("any-module", metadata)); // null (all eager)Wrap module references with lazy loading call expressions.
/**
* Wrap reference with lazy loading call if the payload indicates lazy loading.
* Returns null if no wrapping is needed (eager loading).
*/
function wrapReference(
ref: Identifier,
payload: unknown
): Expression | null;Usage Examples:
// Note: These functions are internal utilities and not directly exported.
// They are used internally by the module transformation system.
import { types as t } from "@babel/core";
const moduleRef = t.identifier("_lodash");
// Lazy loading behavior (conceptually):
// - When payload is "lazy": converts reference to function call like _lodash()
// - When payload is null: uses original reference directlyWhen lazy is a boolean:
true - Lazy load external dependencies (those without . in the name), eager load relative importsfalse - Eager load all modules// true: External modules are lazy, local files are eager
import lodash from "lodash"; // → lazy
import utils from "./utils.js"; // → eager
import api from "../api/client.js"; // → eager
// false: All modules are eager
import lodash from "lodash"; // → eager
import utils from "./utils.js"; // → eagerWhen lazy is a string array, only modules in the array are lazy loaded:
const lazyModules = ["lodash", "moment", "heavy-computation"];
import lodash from "lodash"; // → lazy (in array)
import moment from "moment"; // → lazy (in array)
import react from "react"; // → eager (not in array)
import compute from "heavy-computation"; // → lazy (in array)When lazy is a function, it's called for each module to determine lazy loading:
const lazyFn = (source: string) => {
// Lazy load all Babel packages
if (source.startsWith("@babel/")) return true;
// Lazy load specific heavy libraries
if (["lodash", "moment", "three"].includes(source)) return true;
// Eager load everything else
return false;
};
import core from "@babel/core"; // → lazy (starts with @babel/)
import lodash from "lodash"; // → lazy (in heavy libraries list)
import react from "react"; // → eager (function returns false)Side effect imports and re-export-all statements are never lazy loaded, regardless of configuration:
// These are always eager, even with lazy: true
import "./polyfills.js"; // Side effect import
export * from "some-module"; // Re-export allLazy loaded modules are wrapped in function calls that initialize the module on first access:
// Original code
import { debounce } from "lodash";
console.log(debounce);
// Transformed with lazy loading
const _lodash = () => require("lodash");
console.log(_lodash().debounce);The wrapReference function converts identifier references into function calls:
// Input: identifier reference to lazy module
const ref = t.identifier("_lodash");
// Output: function call expression
const wrapped = Lazy.wrapReference(ref, "lazy");
// AST equivalent of: _lodash()Lazy loading provides benefits for:
However, it adds overhead for: