A comprehensive JavaScript and TypeScript bundler with fast bundling, hot module replacement, and development server capabilities
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The core bundling functionality provides the main API for creating development and production builds with extensive configuration options.
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 serverrunProd(): Executes a production build with optimizations like minification and tree shakinginterface 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";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;
}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>;
};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
});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"
}
});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");
}
});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" }
}
});interface IDevServerProps {
httpServer?: {
port?: number;
hostname?: string;
};
proxy?: Array<{
path: string;
target: string;
}>;
middleware?: Array<(req: any, res: any, next: any) => void>;
}interface IWebIndexConfig {
template?: string;
publicPath?: string;
target?: string;
}interface ISourceMap {
css?: boolean;
project?: boolean;
sourceRoot?: string;
vendor?: boolean;
}interface IHMRProps {
enabled?: boolean;
port?: number;
socketURI?: string;
}interface ICacheProps {
enabled?: boolean;
root?: string;
strategy?: "fs" | "memory";
}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 }>;
}