CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-static-site-generator-webpack-plugin

Minimal, unopinionated static site generator powered by webpack

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

index.mddocs/

Static Site Generator Webpack Plugin

Static Site Generator Webpack Plugin is a minimal, unopinionated static site generator powered by webpack. It enables static site generation by executing a custom render function at build time to generate HTML files for specified paths, supporting both manual path specification and automatic site crawling.

Package Information

  • Package Name: static-site-generator-webpack-plugin
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install --save-dev static-site-generator-webpack-plugin

Core Imports

const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');

For ES modules:

import StaticSiteGeneratorPlugin from 'static-site-generator-webpack-plugin';

Basic Usage

// webpack.config.js
const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');

module.exports = {
  entry: './index.js',
  
  output: {
    filename: 'index.js',
    path: 'dist',
    libraryTarget: 'umd' // Required for Node.js execution
  },
  
  plugins: [
    new StaticSiteGeneratorPlugin({
      paths: ['/hello/', '/world/'],
      locals: {
        greet: 'Hello'
      }
    })
  ]
};

// index.js - render function
module.exports = function render(locals) {
  return '<html>' + locals.greet + ' from ' + locals.path + '</html>';
};

// ES module default export pattern
export default function render(locals) {
  return `<html>${locals.greet} from ${locals.path}</html>`;
};

Architecture

The plugin integrates into webpack's compilation process through several key components:

  • Plugin Constructor: Configures paths, locals, globals, and crawling behavior
  • Webpack Integration: Hooks into webpack's thisCompilation and optimizeAssets phases
  • Render Function Execution: Evaluates the compiled entry file as a render function
  • Asset Generation: Creates HTML assets in webpack's output for each rendered path
  • Crawling Engine: Optionally discovers additional paths by parsing HTML for relative links

Capabilities

Plugin Configuration

Creates a webpack plugin instance with configuration options for static site generation.

/**
 * Static Site Generator Webpack Plugin constructor
 * @param {Object} options - Configuration options
 */
function StaticSiteGeneratorWebpackPlugin(options);

interface StaticSiteGeneratorOptions {
  /** Webpack entry chunk name (defaults to first chunk if not specified) */
  entry?: string;
  /** Array of paths OR single path to render (defaults to ['/'] if not provided) */
  paths?: string[] | string;
  /** Custom properties merged into locals object passed to render function */
  locals?: object;
  /** Object that exists in global scope when executing render function */
  globals?: object;
  /** Enables automatic crawling of relative links and iframes */
  crawl?: boolean;
}

Usage Examples:

// Basic configuration with multiple paths
new StaticSiteGeneratorPlugin({
  paths: ['/about/', '/contact/', '/blog/'],
  locals: {
    siteName: 'My Website',
    version: '1.0.0'
  }
});

// Single path configuration (automatically converted to array)
new StaticSiteGeneratorPlugin({
  paths: '/', // Equivalent to paths: ['/']
  locals: { data: 'value' }
});

// Crawling mode
new StaticSiteGeneratorPlugin({
  crawl: true,
  paths: ['/'], // Entry point for crawling
  locals: { navigation: menuData }
});

// Custom entry point and globals
new StaticSiteGeneratorPlugin({
  entry: 'main',
  paths: ['/'],
  globals: { window: {} }, // For browser-dependent libraries
  locals: { config: appConfig }
});

Render Function Requirements

The entry file must export a render function that accepts locals and returns HTML. The plugin supports three execution patterns:

/** Synchronous render function */
function render(locals: RenderLocals): string;

/** Callback-based render function */
function render(locals: RenderLocals, callback: (error: Error | null, html: string) => void): void;

/** Promise-based render function */
function render(locals: RenderLocals): Promise<string>;

/** Multi-path render function returning object with path-to-HTML mapping */
function render(locals: RenderLocals): string | Promise<string> | { [path: string]: string };

interface RenderLocals {
  /** The path currently being rendered */
  path: string;
  /** Object containing all webpack assets by chunk name */
  assets: { [chunkName: string]: string };
  /** Advanced webpack compilation statistics */
  webpackStats: object;
  /** Custom properties from plugin configuration */
  [key: string]: any;
}

Usage Examples:

// Synchronous rendering
module.exports = function render(locals) {
  return `<html><body><h1>Welcome to ${locals.path}</h1></body></html>`;
};

// Async rendering with callbacks
module.exports = function render(locals, callback) {
  setTimeout(() => {
    const html = generatePage(locals.path, locals.data);
    callback(null, html);
  }, 100);
};

// Promise-based rendering
module.exports = function render(locals) {
  return fetchPageData(locals.path)
    .then(data => renderTemplate(data))
    .then(html => html);
};

// Multi-path rendering
module.exports = function render(locals) {
  return {
    '/': '<html>Home Page</html>',
    '/about': '<html>About Page</html>',
    '/contact': '<html>Contact Page</html>'
  };
};

// Using assets in render function
module.exports = function render(locals) {
  const jsFiles = Object.values(locals.assets).filter(file => file.endsWith('.js'));
  const cssFiles = Object.values(locals.assets).filter(file => file.endsWith('.css'));
  
  return `
    <html>
      <head>
        ${cssFiles.map(css => `<link rel="stylesheet" href="${css}">`).join('\\n')}
      </head>
      <body>
        <h1>Page: ${locals.path}</h1>
        ${jsFiles.map(js => `<script src="${js}"></script>`).join('\\n')}
      </body>
    </html>
  `;
};

// Note: Asset paths in locals.assets automatically include webpack's 
// output.publicPath if configured, so no manual path resolution needed

Crawling Mode

Automatic discovery of additional paths by parsing HTML for relative links and iframe sources.

When crawl: true is enabled, the plugin:

  1. Renders the initial paths specified in configuration
  2. Parses generated HTML for <a href="..."> and <iframe src="..."> tags
  3. Extracts relative URLs (excluding external links and protocol-relative URLs)
  4. Recursively renders discovered paths until no new paths are found

Crawling Rules:

  • Only follows relative paths (not absolute URLs or external links)
  • Converts /path to /path/index.html if no file extension
  • Ignores protocol-relative URLs (//example.com)
  • Ignores URLs with protocols (http://, https://, ftp://)
  • Processes both root-relative (/about) and document-relative (../contact) links
// Enable crawling with entry points
new StaticSiteGeneratorPlugin({
  crawl: true,
  paths: ['/', '/blog/'], // Multiple crawl entry points
  locals: { siteData: data }
});

Custom File Names

Generate custom file names by providing paths ending in .html.

// Configuration for custom file names
new StaticSiteGeneratorPlugin({
  paths: [
    '/index.html',
    '/news.html', 
    '/about.html'
  ]
});

Note: Custom file names may break compatibility with client-side routing if using frameworks like React Router.

Legacy Constructor Arguments

Support for legacy constructor signature with positional arguments.

/**
 * Legacy constructor signature (deprecated)
 * @param {string} entry - Entry chunk name
 * @param {string[]} paths - Paths to render
 * @param {object} locals - Local variables
 * @param {object} globals - Global variables
 */
function StaticSiteGeneratorWebpackPlugin(entry, paths, locals, globals);

Usage Example:

// Legacy usage (deprecated)
new StaticSiteGeneratorPlugin(
  'main',           // entry
  ['/'],           // paths  
  { data: 'value' }, // locals
  { window: {} }     // globals
);

Error Handling

The plugin handles several error conditions:

  • Missing Entry File: Throws error if specified entry chunk is not found in webpack assets
  • Invalid Render Function: Throws error if entry file export is not a function
  • Render Function Errors: Captures render function exceptions and adds them to webpack's compilation errors
  • Asset Generation Errors: Handles errors during HTML asset creation

Common error messages:

  • Source file not found: "entryName" - Entry chunk not found in webpack output
  • Export from "entryName" must be a function that returns an HTML string. Is output.libraryTarget in the configuration set to "umd"? - Entry file doesn't export a function or webpack output configuration is incorrect
  • Render function stack traces are preserved in compilation.errors

Webpack Integration Requirements

  • Output Configuration: Must set output.libraryTarget to 'umd' or 'commonjs' for Node.js execution
  • Compilation Phase: Plugin executes during webpack's optimize-assets phase
  • Asset Generation: Creates new assets in webpack's compilation.assets object
  • Compatibility: Supports both webpack 3.x/4.x (legacy plugin API) and webpack 5.x (hooks API) with automatic detection
// Required webpack configuration
module.exports = {
  output: {
    libraryTarget: 'umd' // Essential for Node.js execution
  },
  plugins: [
    new StaticSiteGeneratorPlugin(options)
  ]
};

docs

index.md

tile.json