Module required for evaluating Metro bundles with async loading and HMR support.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core functionality for loading modules asynchronously with bundle splitting support. This system enables dynamic imports and code splitting in Metro bundles, allowing for lazy loading of application features and optimized bundle sizes.
Loads a module asynchronously, with support for bundle splitting and dynamic loading.
/**
* Asynchronously loads a module with bundle splitting support
* @param moduleID - Numeric identifier of the module to load
* @param paths - Mapping of module IDs to bundle paths for lazy loading
* @param moduleName - Optional module name for debugging (unused in implementation)
* @returns Promise resolving to the loaded module
*/
function asyncRequire(
moduleID: number,
paths: ?DependencyMapPaths,
moduleName?: string
): Promise<any>;
type DependencyMapPaths = ?$ReadOnly<{[moduleID: number | string]: mixed}>;Usage Examples:
const asyncRequire = require("metro-runtime/modules/asyncRequire");
// Load a feature module dynamically
const loadDashboard = async () => {
const dashboardModule = await asyncRequire(
123, // module ID assigned by Metro
{ 123: "/bundles/dashboard.bundle.js" }, // bundle path mapping
"dashboard" // optional name for debugging
);
return dashboardModule.default;
};
// Load multiple modules
const loadModules = async () => {
const [analytics, utils] = await Promise.all([
asyncRequire(200, { 200: "/bundles/analytics.js" }),
asyncRequire(201, { 201: "/bundles/utils.js" })
]);
return { analytics, utils };
};Synchronous version of asyncRequire that can still return a promise if the module requires bundle loading.
/**
* Loads a module synchronously if available, asynchronously if bundle loading required
* @param moduleID - Numeric identifier of the module to load
* @param paths - Mapping of module IDs to bundle paths
* @returns Either the loaded module directly, or a Promise resolving to it
*/
asyncRequire.unstable_importMaybeSync = function(
moduleID: number,
paths: ?DependencyMapPaths
): Promise<any> | any;Usage Examples:
// Import that may be sync or async depending on bundle availability
const maybeLoadModule = (moduleId, paths) => {
const result = asyncRequire.unstable_importMaybeSync(moduleId, paths);
if (result instanceof Promise) {
// Module requires bundle loading
return result.then(module => {
console.log("Module loaded asynchronously");
return module;
});
} else {
// Module was already available
console.log("Module loaded synchronously");
return result;
}
};Pre-loads a bundle without executing the module, useful for optimizing perceived performance.
/**
* Pre-loads a bundle without executing the module
* @param moduleID - Numeric identifier of the module to prefetch
* @param paths - Mapping of module IDs to bundle paths
* @param moduleName - Optional module name for debugging (unused)
*/
asyncRequire.prefetch = function(
moduleID: number,
paths: ?DependencyMapPaths,
moduleName?: string
): void;Usage Examples:
// Prefetch modules that might be needed soon
const prefetchFeatures = () => {
const bundlePaths = {
100: "/bundles/settings.js",
101: "/bundles/profile.js",
102: "/bundles/notifications.js"
};
// Prefetch all feature bundles
asyncRequire.prefetch(100, bundlePaths, "settings");
asyncRequire.prefetch(101, bundlePaths, "profile");
asyncRequire.prefetch(102, bundlePaths, "notifications");
};
// Prefetch on user interaction
button.addEventListener("click", () => {
// Start loading the module before user needs it
asyncRequire.prefetch(150, { 150: "/bundles/heavy-feature.js" });
});The async loading system works by:
paths parameter maps module IDs to their bundle URLsglobal[__METRO_GLOBAL_PREFIX__ + '__loadBundleAsync'] to load bundlesrequire.importAllBundle paths in the paths parameter should be configured based on your deployment:
// Development configuration
const devPaths = {
42: "http://localhost:8081/bundles/feature.bundle.js"
};
// Production configuration
const prodPaths = {
42: "https://cdn.example.com/bundles/feature.bundle.js"
};
// React Native configuration
const nativePaths = {
42: "./bundles/feature.bundle"
};Bundle loading errors are handled gracefully:
const safeAsyncRequire = async (moduleId, paths) => {
try {
const module = await asyncRequire(moduleId, paths);
return module;
} catch (error) {
console.error(`Failed to load module ${moduleId}:`, error);
// Return fallback or default implementation
return null;
}
};Metro Runtime's async loading system is designed to work seamlessly with Metro bundler's code splitting: