or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

build-automation.mdcore-bundling.mdindex.mdplugins.mdtransformation.md
tile.json

core-bundling.mddocs/

Core Bundling

The core bundling functionality provides the main API for creating development and production builds with extensive configuration options.

Main Function

function fusebox(publicConfig: IPublicConfig): {
  runDev: (runProps?: IRunProps) => Promise<IRunResponse>;
  runProd: (runProps?: IRunProps) => Promise<IRunResponse>;
};

The fusebox() function creates a bundler instance configured for both development and production builds. It returns an object with two methods:

  • runDev(): Executes a development build with hot module replacement and development server
  • runProd(): Executes a production build with optimizations like minification and tree shaking

Configuration Interface

interface IPublicConfig {
  // Build Settings
  target?: ITarget;
  entry?: Array<string> | string;
  plugins?: Array<(ctx: Context) => void>;
  
  // Development Features
  devServer?: IDevServerProps | boolean;
  webIndex?: IWebIndexConfig | boolean;
  cache?: ICacheProps | boolean;
  hmr?: IHMRProps | boolean;
  watcher?: IWatcherPublicConfig | boolean;
  
  // Build Optimization
  sourceMap?: boolean | ISourceMap;
  dependencies?: IDependencies;
  compilerOptions?: ICompilerOptions;
  threading?: IThreadingConfig;
  
  // Module Resolution
  alias?: { [key: string]: string };
  modules?: Array<string>;
  env?: { [key: string]: string };
  
  // Asset Processing
  resources?: IResourceConfig;
  stylesheet?: IStyleSheetProps;
  webWorkers?: IWebWorkerConfig;
  
  // Framework Support
  electron?: IElectronOptions;
  
  // Plugin Configuration
  logging?: IFuseLoggerProps;
  json?: IJSONPluginProps;
  link?: IPluginLinkOptions;
}

type ITarget = "browser" | "electron" | "server" | "web-worker";

Runtime Properties

interface IRunProps {
  buildTarget?: ITypescriptTarget;
  bundles?: IPublicOutputConfig;
  cleanCSS?: any;
  manifest?: IManifest | boolean;
  target?: ITarget;
  tsHelpersPath?: string;
  uglify?: any;
}

type ITypescriptTarget = "ES2015" | "ES2016" | "ES2017" | "ES3" | "ES5" | "ES6";

interface IPublicOutputConfig {
  [bundleName: string]: {
    path?: string;
    publicPath?: string;
  };
}

interface IManifest {
  fileName?: string;
  publicPath?: string;
}

Build Response

interface IRunResponse {
  bundleContext?: IBundleContext;
  bundles: Array<IBundleWriteResponse>;
  entries?: Array<IModule>;
  manifest: string;
  modules?: Array<IModule>;
  splitEntries?: ISplitEntries;
  onComplete: (fn: (props: IRunOnCompleteHandler) => void) => void;
  onWatch?: (fn: (bundles: Array<IBundleWriteResponse>) => void) => void;
}

interface IBundleWriteResponse {
  absPath: string;
  contents: string;
  size: number;
  gzipSize?: number;
  relativePath: string;
}

interface IRunOnCompleteHandler {
  electron?: IServerProcess;
  server?: IServerProcess;
  onWatch?: (fn: () => void) => void;
}

interface IServerProcess {
  start: (props?: IServerStartProps) => ChildProcess;
  stop: () => void;
}

interface IServerStartProps {
  argsAfter?: Array<string>;
  argsBefore?: Array<string>;
  options?: Record<string, any>;
  processName?: string;
}

interface ISplitEntries {
  entries: Array<ISplitEntry>;
  ids: Record<number, boolean>;
  register: (splitEntry: ISplitEntry) => void;
}

interface ISplitEntry {
  entry: IModule;
  modules: Array<IModule>;
  references: Array<IImport>;
}

interface IImport {
  source: string;
  statement: string;
}

type IBundleContext = {
  cache?: ICache;
  currentId: number;
  injectedDependencies: Record<string, IModule>;
  modules: Record<string, IModule>;
  packages: Record<string, IPackage>;
};

Usage Examples

Basic Browser Bundle

import { fusebox } from "fuse-box";

const fuse = fusebox({
  target: "browser",
  entry: "src/index.ts",
  devServer: true,
  webIndex: {
    template: "src/index.html"
  }
});

// Development build
const devResult = await fuse.runDev();
console.log(`Built ${devResult.bundles.length} bundles`);

// Production build
const prodResult = await fuse.runProd({
  uglify: true,
  manifest: true
});

Server-Side Bundle

import { fusebox } from "fuse-box";

const fuse = fusebox({
  target: "server",
  entry: "src/server.ts",
  alias: {
    "@": "src/"
  },
  compilerOptions: {
    target: "ES2018",
    module: "CommonJS"
  }
});

const result = await fuse.runProd({
  buildTarget: {
    target: "ES2018",
    module: "CommonJS"
  }
});

Electron Application

import { fusebox } from "fuse-box";

const fuse = fusebox({
  target: "electron",
  entry: "src/main.ts",
  electron: {
    nodeIntegration: true,
    contextIsolation: false
  },
  devServer: false
});

const result = await fuse.runDev();
result.onComplete(({ electron }) => {
  if (electron) {
    console.log("Electron app started");
  }
});

Multi-Entry Configuration

import { fusebox } from "fuse-box";

const fuse = fusebox({
  target: "browser",
  entry: ["src/main.ts", "src/worker.ts"],
  webWorkers: {
    enabled: true
  }
});

const result = await fuse.runProd({
  bundles: {
    main: { path: "dist/main.js" },
    worker: { path: "dist/worker.js" }
  }
});

Configuration Options

Development Server

interface IDevServerProps {
  httpServer?: {
    port?: number;
    hostname?: string;
  };
  proxy?: Array<{
    path: string;
    target: string;
  }>;
  middleware?: Array<(req: any, res: any, next: any) => void>;
}

Web Index Configuration

interface IWebIndexConfig {
  template?: string;
  publicPath?: string;
  target?: string;
}

Source Maps

interface ISourceMap {
  css?: boolean;
  project?: boolean;
  sourceRoot?: string;
  vendor?: boolean;
}

Hot Module Replacement

interface IHMRProps {
  enabled?: boolean;
  port?: number;
  socketURI?: string;
}

Caching

interface ICacheProps {
  enabled?: boolean;
  root?: string;
  strategy?: "fs" | "memory";
}

Build Context

The build context provides access to the internal build state and configuration:

interface Context {
  config: IConfig;
  log: IFuseLogger;
  ict: IInterComponentCommunication;
  meta: { [key: string]: any };
  isWorking: boolean;
}

interface IModule {
  absPath: string;
  contents: string;
  extension: string;
  captured?: boolean;
  isStylesheet?: boolean;
  read(): void;
  resolve(statement: string): Promise<{ module: IModule }>;
}