CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-metalsmith

An extremely simple, pluggable static site generator for NodeJS

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-processing.mddocs/

Build and Processing

Core build methods for processing files through the plugin pipeline and outputting results. These methods orchestrate the complete Metalsmith workflow from reading files to writing output.

Capabilities

Build Method

Execute the complete build process: read files, process through plugins, and write to destination.

/**
 * Build with current settings, outputting to destination directory
 * @param callback - Optional callback for completion
 * @returns Promise resolving to processed files (if no callback provided)
 */
build(callback?: BuildCallback): Promise<Files> | void;

type BuildCallback = (error: Error | null, files: Files) => void;

Usage Examples:

import Metalsmith from "metalsmith";

// Promise-based build
try {
  const files = await metalsmith.build();
  console.log(`Built ${Object.keys(files).length} files`);
} catch (error) {
  console.error('Build failed:', error);
}

// Callback-based build
metalsmith.build((error, files) => {
  if (error) {
    console.error('Build failed:', error);
    return;
  }
  console.log(`Built ${Object.keys(files).length} files`);
});

Process Method

Process files through plugins without writing to the filesystem. Useful for in-memory processing and testing.

/**
 * Process files through plugins without writing to filesystem
 * @param callback - Optional callback for completion
 * @returns Promise resolving to processed files (if no callback provided)
 */
process(callback?: BuildCallback): Promise<Files> | void;

Usage Examples:

// Process files in memory only
const processedFiles = await metalsmith.process();

// Useful for testing or preview mode
metalsmith.process((error, files) => {
  if (error) throw error;
  
  // Files are processed but not written to disk
  Object.keys(files).forEach(filepath => {
    console.log(`Processed: ${filepath}`);
    console.log(`Content: ${files[filepath].contents.toString()}`);
  });
});

Run Method

Run a specific set of files through the plugin pipeline with optional custom plugin list.

/**
 * Run files through plugin pipeline
 * @param files - Files object to process
 * @param callback - Callback for completion
 */
run(files: Files, callback: BuildCallback): void;

/**
 * Run files through specific plugins
 * @param files - Files object to process
 * @param plugins - Array of plugins to use (defaults to instance plugins)
 * @param callback - Callback for completion
 */
run(files: Files, plugins: Plugin[], callback: BuildCallback): void;

/**
 * Run files through plugin pipeline (Promise version)
 * @param files - Files object to process
 * @param plugins - Optional array of plugins to use
 * @returns Promise resolving to processed files
 */
run(files: Files, plugins?: Plugin[]): Promise<Files>;

Usage Examples:

import Metalsmith from "metalsmith";
import markdown from "@metalsmith/markdown";

// Run with default plugins
const inputFiles = {
  'index.md': {
    contents: Buffer.from('# Hello World'),
    title: 'Home Page'
  }
};

const outputFiles = await metalsmith.run(inputFiles);

// Run with specific plugins only
const customPlugins = [markdown()];
const result = await metalsmith.run(inputFiles, customPlugins);

// Callback version
metalsmith.run(inputFiles, (error, files) => {
  if (error) throw error;
  console.log('Processed files:', Object.keys(files));
});

Build Pipeline Process

The build pipeline follows this sequence:

  1. Clean (if enabled): Remove destination directory contents
  2. Read: Load files from source directory with front-matter parsing
  3. Process: Execute plugins in sequence
  4. Write: Output processed files to destination directory

Build Process Control:

// Full build with all steps
await metalsmith
  .clean(true)          // Clean destination first
  .source('src')        // Read from src/
  .destination('build') // Write to build/
  .build();

// Process only (skip file I/O)
await metalsmith.process(); // Only steps 3 (plugins)

// Custom processing
const files = await metalsmith.read();           // Step 2 only
const processed = await metalsmith.run(files);   // Step 3 only  
await metalsmith.write(processed);               // Step 4 only

Error Handling

Build methods provide comprehensive error handling for all stages of processing.

// Promise error handling
try {
  await metalsmith.build();
} catch (error) {
  if (error.code === 'invalid_frontmatter') {
    console.error('Front-matter parsing failed:', error.message);
  } else if (error.code === 'failed_read') {
    console.error('File reading failed:', error.message);
  } else if (error.code === 'failed_write') {
    console.error('File writing failed:', error.message);
  } else {
    console.error('Plugin error:', error.message);
  }
}

// Callback error handling
metalsmith.build((error, files) => {
  if (error) {
    console.error('Build error:', error.message);
    console.error('Stack trace:', error.stack);
    return;
  }
  
  console.log('Build successful');
});

Watch Mode Processing

Process files continuously when source files change (experimental feature).

/**
 * Enable file watching for continuous rebuilds
 * @param options - Watch configuration or boolean
 * @returns Metalsmith instance or current watch settings
 */
watch(options?: boolean | string | string[] | WatchOptions): Metalsmith | boolean | WatchOptions;

interface WatchOptions {
  /** Paths to watch (default: source directory) */
  paths?: string[];
  /** Wait for write operations to complete */
  awaitWriteFinish?: boolean;
  /** Additional chokidar options */
  [key: string]: any;
}

Watch Mode Examples:

// Enable watching of source directory
metalsmith
  .clean(false)     // Use partial rebuilds
  .watch(true)      // Watch source directory
  .build((error, files) => {
    if (error) {
      console.error('Build error:', error);
      return;
    }
    console.log(`Rebuilt ${Object.keys(files).length} files`);
  });

// Watch specific directories
metalsmith
  .watch(['src', 'templates'])
  .process((error, files) => {
    // Continuous in-memory processing
    console.log('Files reprocessed');
  });

// Stop watching
metalsmith.watch(false);

Build Performance

Tips for optimizing build performance:

// Limit file concurrency to prevent resource exhaustion
metalsmith.concurrency(50);

// Use partial rebuilds in watch mode
metalsmith.clean(false);

// Enable debug logging to identify slow plugins
metalsmith.env('DEBUG', '@metalsmith/*');

// Measure build time
const startTime = performance.now();
await metalsmith.build();
const buildTime = ((performance.now() - startTime) / 1000).toFixed(1);
console.log(`Build completed in ${buildTime}s`);

docs

build-processing.md

cli.md

core-configuration.md

debugging.md

file-operations.md

frontmatter.md

index.md

plugin-system.md

utilities.md

tile.json