CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-fuse-box

A comprehensive JavaScript and TypeScript bundler with fast bundling, hot module replacement, and development server capabilities

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

build-automation.mddocs/

Build Automation (Sparky)

Sparky is FuseBox's built-in task automation framework for creating custom build workflows, CI/CD integration, and development tools. It provides a fluent API for file operations, task management, and build orchestration.

Main Function

function sparky<T>(Ctx: new () => T): {
  task: (name: string | RegExp, fn: (ctx: T) => void) => void;
  exec: (name: string) => Promise<void>;
  src: (glob: string) => SparkyChain;
  rm: (folder: string) => void;
};

The sparky() function creates a task management system with a custom context type. It automatically executes tasks based on command-line arguments.

Task Management

Task Definition

task(name: string | RegExp, fn: (ctx: T) => void): void;

Define named tasks that can be executed individually or as part of a workflow. Tasks can use string names or regex patterns for flexible matching.

Task Execution

exec(name: string): Promise<void>;

Execute a specific task by name. Tasks are automatically timed and logged during execution.

File Operations

Source Selection

src(glob: string): SparkyChain;

Select files using glob patterns for processing. Returns a chainable interface for file operations.

Directory Removal

rm(folder: string): void;

Remove directories and their contents. Paths are resolved relative to the script location.

Sparky Chain Interface

The src() method returns a chainable interface for file operations:

interface SparkyChain {
  dest(destination: string): SparkyChain;
  clean(destination: string): SparkyChain;
  watch(glob?: string): SparkyChain;
  file(pattern: string, handler: (file: SparkyFile) => void): SparkyChain;
  exec(): Promise<void>;
}

interface SparkyFile {
  root: string;
  name: string;
  filepath: string;
  absPath: string;
  contents: Buffer;
  read(): void;
  save(): void;
}

Usage Examples

Basic Task Setup

import { sparky } from "fuse-box";

class BuildContext {
  isProduction = false;
  
  setProduction() {
    this.isProduction = true;
  }
}

const { task, exec, src, rm } = sparky(BuildContext);

task("default", async (ctx) => {
  console.log("Running default task");
  await exec("clean");
  await exec("build");
});

task("clean", (ctx) => {
  rm("dist/");
});

task("build", async (ctx) => {
  if (ctx.isProduction) {
    console.log("Production build");
  } else {
    console.log("Development build");
  }
});

File Processing Tasks

import { sparky } from "fuse-box";

class Context {}
const { task, src } = sparky(Context);

task("copy-assets", async () => {
  await src("src/assets/**/*")
    .dest("dist/assets/")
    .exec();
});

task("process-templates", async () => {
  await src("src/templates/*.html")
    .file("*.html", (file) => {
      file.read();
      const content = file.contents.toString();
      file.contents = Buffer.from(
        content.replace(/{{VERSION}}/g, "1.0.0")
      );
    })
    .dest("dist/templates/")
    .exec();
});

Watch Mode Tasks

import { sparky } from "fuse-box";

class Context {}
const { task, src } = sparky(Context);

task("watch", async () => {
  await src("src/**/*.ts")
    .watch()
    .dest("dist/")
    .exec();
});

task("watch-assets", async () => {
  await src("src/assets/**/*")
    .watch("src/assets/**/*")
    .clean("dist/assets/")
    .dest("dist/assets/")
    .exec();
});

Complex Build Workflow

import { sparky } from "fuse-box";
import { fusebox, pluginCSS, pluginSass } from "fuse-box";

class BuildContext {
  isProduction = false;
  version = "1.0.0";
  
  setVersion(v: string) {
    this.version = v;
  }
  
  enableProduction() {
    this.isProduction = true;
  }
}

const { task, exec, src, rm } = sparky(BuildContext);

task("default", async (ctx) => {
  await exec("clean");
  await exec("copy-assets");
  await exec("bundle");
});

task("production", async (ctx) => {
  ctx.enableProduction();
  await exec("clean");
  await exec("copy-assets");
  await exec("bundle");
  await exec("optimize");
});

task("clean", () => {
  rm("dist/");
});

task("copy-assets", async () => {
  await src("src/assets/**/*")
    .dest("dist/assets/")
    .exec();
});

task("bundle", async (ctx) => {
  const fuse = fusebox({
    target: "browser",
    entry: "src/index.ts",
    plugins: [pluginCSS(), pluginSass()]
  });
  
  if (ctx.isProduction) {
    await fuse.runProd({
      uglify: true,
      manifest: true
    });
  } else {
    await fuse.runDev();
  }
});

task("optimize", async () => {
  // Additional optimization tasks
  console.log("Running optimization tasks");
});

Regex-Based Task Matching

import { sparky } from "fuse-box";

class Context {}
const { task } = sparky(Context);

// Match tasks starting with "test:"
task(/^test:/, async (ctx) => {
  console.log("Running test task");
});

// Match specific patterns
task(/^build:(dev|prod)$/, async (ctx) => {
  console.log("Running build task");
});

Integration with External Tools

import { sparky } from "fuse-box";
import { exec as execProcess } from "child_process";
import { promisify } from "util";

const execAsync = promisify(execProcess);

class Context {}
const { task, exec } = sparky(Context);

task("test", async () => {
  await execAsync("npm test");
});

task("lint", async () => {
  await execAsync("eslint src/**/*.ts");
});

task("typecheck", async () => {
  await execAsync("tsc --noEmit");
});

task("ci", async () => {
  await exec("lint");
  await exec("typecheck");
  await exec("test");
  await exec("build");
});

Custom Context with State Management

import { sparky } from "fuse-box";

class BuildContext {
  private _startTime: number;
  private _stats = {
    filesProcessed: 0,
    errors: 0
  };
  
  start() {
    this._startTime = Date.now();
  }
  
  finish() {
    const duration = Date.now() - this._startTime;
    console.log(`Build completed in ${duration}ms`);
    console.log(`Files processed: ${this._stats.filesProcessed}`);
    console.log(`Errors: ${this._stats.errors}`);
  }
  
  incrementFiles() {
    this._stats.filesProcessed++;
  }
  
  incrementErrors() {
    this._stats.errors++;
  }
  
  get stats() {
    return { ...this._stats };
  }
}

const { task, exec, src } = sparky(BuildContext);

task("build-with-stats", async (ctx) => {
  ctx.start();
  
  try {
    await src("src/**/*.ts")
      .file("*.ts", (file) => {
        try {
          // Process file
          ctx.incrementFiles();
        } catch (error) {
          ctx.incrementErrors();
          console.error(`Error processing ${file.name}:`, error);
        }
      })
      .dest("dist/")
      .exec();
  } finally {
    ctx.finish();
  }
});

Automatic Task Execution

Sparky automatically executes tasks based on command-line arguments:

# Runs the "build" task
node sparky-script.js build

# Runs the "test:unit" task (if defined)
node sparky-script.js test:unit

# Runs the "default" task if no arguments provided
node sparky-script.js

Logging and Time Measurement

Sparky includes built-in logging and time measurement:

  • Task execution is automatically timed
  • Start and completion messages are logged
  • Failed tasks display error information
  • Support for colored output and progress indicators

docs

build-automation.md

core-bundling.md

index.md

plugins.md

transformation.md

tile.json