or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bundling.mdcli-commands.mdconfiguration.mddevelopment-server.mdindex.md
tile.json

bundling.mddocs/

Bundling Operations

Core bundling functionality for creating production bundles, development builds, and dependency analysis. Metro provides comprehensive bundling capabilities with support for multiple platforms, source maps, asset processing, and incremental builds.

Capabilities

Build Production Bundle

Creates a production-ready JavaScript bundle with optional minification, source maps, and asset processing.

/**
 * Build a production bundle from an entry point
 * @param config - Metro configuration object
 * @param options - Build options and callbacks
 * @returns Promise resolving to bundle code, source map, and assets
 */
function runBuild(
  config: ConfigT,
  options: RunBuildOptions
): Promise<RunBuildResult>;

interface RunBuildOptions {
  /** Entry point file path (required) */
  entry: string;
  /** Include assets in build result (default: false) */
  assets?: boolean;
  /** Enable development mode (default: false) */
  dev?: boolean;
  /** Output file path for bundle */
  out?: string;
  /** Bundle output file path (alternative to out) */
  bundleOut?: string;
  /** Source map output file path */
  sourceMapOut?: string;
  /** Callback when build starts */
  onBegin?: () => void;
  /** Callback when build completes */
  onComplete?: () => void;
  /** Progress callback with file counts */
  onProgress?: (transformedFileCount: number, totalFileCount: number) => void;
  /** Enable minification (default: true) */
  minify?: boolean;
  /** Custom output handler */
  output?: OutputHandler;
  /** Target platform (default: 'web') */
  platform?: string;
  /** Generate source maps (default: false) */
  sourceMap?: boolean;
  /** Custom source map URL */
  sourceMapUrl?: string;
  /** Custom resolver options */
  customResolverOptions?: CustomResolverOptions;
  /** Custom transform options */
  customTransformOptions?: CustomTransformOptions;
  /** Transform profile for optimization */
  unstable_transformProfile?: TransformProfile;
}

interface RunBuildResult {
  /** Generated bundle code */
  code: string;
  /** Source map content */
  map: string;
  /** Array of asset metadata if assets: true */
  assets?: ReadonlyArray<AssetData>;
}

Usage Example:

import { runBuild, loadConfig } from "metro";

const config = await loadConfig({
  projectRoot: process.cwd(),
});

// Basic production build
const result = await runBuild(config, {
  entry: "./src/index.js",
  out: "./dist/bundle.js",
  platform: "web",
  minify: true,
  sourceMap: true,
  onProgress: (completed, total) => {
    console.log(`Progress: ${completed}/${total} files`);
  },
});

console.log("Bundle size:", result.code.length);

Build Dependency Graph

Builds a dependency graph without creating a bundle, useful for analysis and understanding module relationships.

/**
 * Build dependency graph for entry points without bundling
 * @param config - Metro configuration object
 * @param options - Graph building options
 * @returns Promise resolving to read-only dependency graph
 */
function buildGraph(
  config: InputConfigT,
  options: BuildGraphOptions
): Promise<ReadOnlyGraph<void>>;

interface BuildGraphOptions {
  /** Array of entry point file paths */
  entries: ReadonlyArray<string>;
  /** Custom transform options */
  customTransformOptions?: CustomTransformOptions;
  /** Enable development mode (default: false) */
  dev?: boolean;
  /** Enable minification (default: false) */
  minify?: boolean;
  /** Progress callback with file counts */
  onProgress?: (transformedFileCount: number, totalFileCount: number) => void;
  /** Target platform (default: 'web') */
  platform?: string;
  /** Module type: 'module' or 'script' (default: 'module') */
  type?: 'module' | 'script';
}

Usage Example:

import { buildGraph, loadConfig } from "metro";

const config = await loadConfig({
  projectRoot: process.cwd(),
});

// Analyze dependencies
const graph = await buildGraph(config, {
  entries: ["./src/index.js", "./src/worker.js"],
  platform: "web",
  onProgress: (completed, total) => {
    console.log(`Analyzing: ${completed}/${total} modules`);
  },
});

console.log("Dependency graph created with", graph.dependencies.size, "modules");

Create Metro Server

Creates a Metro server instance for programmatic bundling without starting an HTTP server.

/**
 * Create Metro server instance for programmatic bundling
 * @param config - Metro configuration object
 * @param options - Server creation options
 * @returns Promise resolving to MetroServer instance
 */
function runMetro(
  config: InputConfigT,
  options?: RunMetroOptions
): Promise<MetroServer>;

interface RunMetroOptions extends ServerOptions {
  /** Wait for bundler initialization before resolving */
  waitForBundler?: boolean;
}

interface MetroServer {
  /** Shutdown server and cleanup resources */
  end(): Promise<void>;
  /** Get the underlying incremental bundler */
  getBundler(): IncrementalBundler;
  /** Get module ID factory function */
  getCreateModuleId(): (path: string) => number;
  /** Build bundle with specified options */
  build(options: BundleOptions): Promise<{code: string; map: string; assets?: ReadonlyArray<AssetData>}>;
  /** Get RAM bundle information */
  getRamBundleInfo(options: BundleOptions): Promise<RamBundleInfo>;
  /** Get assets for bundle */
  getAssets(options: BundleOptions): Promise<ReadonlyArray<AssetData>>;
  /** Get ordered dependency paths */
  getOrderedDependencyPaths(options: Object): Promise<Array<string>>;
  /** Connect middleware function */
  processRequest: Middleware;
}

Usage Example:

import { runMetro, loadConfig } from "metro";

const config = await loadConfig({
  projectRoot: process.cwd(),
});

// Create Metro server
const server = await runMetro(config, {
  waitForBundler: true,
});

try {
  // Build bundle programmatically
  const bundle = await server.build({
    entryFile: "./src/index.js",
    platform: "web",
    dev: false,
    minify: true,
  });
  
  console.log("Bundle created:", bundle.code.length, "bytes");
} finally {
  await server.end();
}

Bundle Options Types

interface BundleOptions {
  entryFile: string;
  platform: string;
  dev: boolean;
  minify: boolean;
  inlineSourceMap?: boolean;
  sourceMapUrl?: string;
  createModuleIdFactory?: () => (path: string) => number;
  onProgress?: (transformedFileCount: number, totalFileCount: number) => void;
  customResolverOptions?: CustomResolverOptions;
  customTransformOptions?: CustomTransformOptions;
  unstable_transformProfile?: TransformProfile;
}

interface CustomTransformOptions {
  [key: string]: unknown;
}

interface CustomResolverOptions {
  [key: string]: unknown;
}

interface AssetData {
  httpServerLocation: string;
  hash: string;
  name: string;
  scales: number[];
  type: string;
}

interface RamBundleInfo {
  getDependencies: () => Array<string>;
  getModules: () => Array<Module>;
  getStartupModules: () => Array<Module>;
}

interface OutputHandler {
  build: (
    server: MetroServer,
    requestOptions: RequestOptions,
    buildOptions?: BuildOptions
  ) => Promise<{
    code: string;
    map: string;
    assets?: ReadonlyArray<AssetData>;
  }>;
  save: (
    bundle: { code: string; map: string },
    outputOptions: OutputOptions,
    logger: (message: string) => void
  ) => Promise<void>;
}

interface TransformProfile {
  dev: boolean;
  hot: boolean;
  minify: boolean;
  platform?: string;
}

interface Module {
  [key: string]: unknown;
}