or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-rollup-plugin-serve

Development server plugin for Rollup that serves bundled files during development

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/rollup-plugin-serve@3.0.x

To install, run

npx @tessl/cli install tessl/npm-rollup-plugin-serve@3.0.0

index.mddocs/

Rollup Plugin Serve

Rollup Plugin Serve is a development server plugin for Rollup that serves bundled files during development, similar to webpack-dev-server. It provides static file serving with features like HTTPS support, history API fallback, custom headers, MIME types, and browser auto-opening.

Package Information

  • Package Name: rollup-plugin-serve
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install --save-dev rollup-plugin-serve

Core Imports

import serve from "rollup-plugin-serve";

For CommonJS:

const serve = require("rollup-plugin-serve");

Basic Usage

// rollup.config.js
import serve from "rollup-plugin-serve";

export default {
  input: "src/main.js",
  output: {
    file: "dist/bundle.js",
    format: "cjs"
  },
  plugins: [
    serve("dist") // Serve files from dist directory
  ]
};

Architecture

The plugin creates an HTTP/HTTPS server during Rollup's build process and integrates with Rollup's plugin system through the generateBundle hook. Key components include:

  • Server Management: Handles HTTP/HTTPS server lifecycle, including graceful restart on configuration changes
  • Static File Serving: Serves files from configurable content directories with path traversal protection
  • History API Support: SPA-friendly fallback routing for client-side routing applications
  • MIME Type Handling: Extensible MIME type detection and custom type registration
  • Development Features: Browser auto-opening, verbose logging, and custom header injection

Capabilities

Plugin Function

Creates a Rollup plugin instance that provides development server functionality.

/**
 * Serve your rolled up bundle like webpack-dev-server
 * @param options - Configuration options, string shorthand for contentBase, or array of contentBase paths
 * @returns Rollup plugin object
 */
function serve(options?: RollupServeOptions | string | string[]): Plugin;

**Shorthand Usage:**

```javascript
// String shorthand for contentBase
serve("public");

// Array shorthand for multiple contentBase paths
serve(["dist", "static"]);

Advanced Configuration:

serve({
  contentBase: ["dist", "static"],
  port: 3000,
  host: "0.0.0.0",
  open: true,
  openPage: "/dashboard",
  historyApiFallback: true,
  https: {
    key: fs.readFileSync("server.key"),
    cert: fs.readFileSync("server.crt")
  },
  headers: {
    "Access-Control-Allow-Origin": "*",
    "Cache-Control": "no-cache"
  },
  mimeTypes: {
    "application/javascript": ["js_proxy"]
  },
  onListening: (server) => {
    const address = server.address();
    console.log(`Server running at http://localhost:${address.port}`);
  }
});

Configuration Options

Complete configuration interface for the serve plugin.

interface RollupServeOptions {
  /** Launch browser after first bundle is generated (default: false) */
  open?: boolean;
  
  /** 
   * Page to open when browser launches. Must start with '/'.
   * Only used when open=true (default: '') 
   */
  openPage?: string;
  
  /** Show server address in console (default: true) */
  verbose?: boolean;
  
  /** 
   * Folder(s) to serve static files from. 
   * Supports string or array of strings (default: current directory)
   */
  contentBase?: string | string[];
  
  /** 
   * Return index.html (200) instead of 404 for SPA routing.
   * Use true for default '/index.html' or string for custom fallback path
   */
  historyApiFallback?: boolean | string;
  
  /** Server host address (default: 'localhost') */
  host?: string;
  
  /** Server port number (default: 10001) */
  port?: number | string;
  
  /** HTTPS server configuration from Node.js https module */
  https?: ServerOptions;
  
  /** Custom HTTP response headers */
  headers?: IncomingHttpHeaders | OutgoingHttpHeaders | {
    [name: string]: number | string | ReadonlyArray<string>;
  };
  
  /** Custom MIME type definitions using mime package format */
  mimeTypes?: TypeMap;
  
  /** Callback executed after server begins listening */
  onListening?: (server: Server) => void;
}

Content Base Configuration

The contentBase option supports multiple patterns for serving static files:

// Single directory
serve({ contentBase: "dist" });

// Multiple directories (fallback order)
serve({ contentBase: ["dist", "public", "assets"] });

// Current directory (default)
serve({ contentBase: "" });

When multiple content bases are specified, the server attempts to serve files from each directory in order until a file is found.

History API Fallback

For single-page applications with client-side routing:

// Default fallback to /index.html
serve({ historyApiFallback: true });

// Custom fallback page
serve({ historyApiFallback: "/app.html" });

// Conditional fallback with contentBase priority
serve({
  contentBase: ["dist", "public"],
  historyApiFallback: "/fallback.html"
});

HTTPS Configuration

Enable HTTPS with SSL/TLS certificates:

import fs from "fs";

serve({
  https: {
    key: fs.readFileSync("path/to/private-key.pem"),
    cert: fs.readFileSync("path/to/certificate.pem"),
    ca: fs.readFileSync("path/to/ca-certificate.pem") // Optional
  },
  port: 443
});

Custom Headers

Set response headers for all served files:

serve({
  headers: {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE",
    "Cache-Control": "no-cache, no-store, must-revalidate",
    "X-Custom-Header": "development-server"
  }
});

MIME Type Configuration

Define custom MIME types for file extensions:

serve({
  mimeTypes: {
    "application/javascript": ["js_commonjs-proxy", "js_module"],
    "text/x-custom": ["custom", "cst"],
    "application/wasm": ["wasm"]
  }
});

Server Lifecycle Callbacks

Handle server events and customize behavior:

serve({
  onListening: function(server) {
    const address = server.address();
    const protocol = this.https ? "https" : "http";
    const host = address.address === "::" ? "localhost" : address.address;
    
    console.log(`🚀 Server ready at ${protocol}://${host}:${address.port}`);
    
    // Access plugin options via 'this'
    if (this.verbose) {
      console.log("Serving from:", this.contentBase);
    }
  }
});

Types

// From Node.js net module (used by http.Server)
interface AddressInfo {
  address: string;
  family: string;
  port: number;
}

// From Node.js http module
interface Server {
  listen(port: number, host?: string, callback?: () => void): void;
  close(callback?: () => void): void;
  address(): AddressInfo | string | null;
  on(event: string, listener: Function): void;
}

// From Node.js https module  
interface ServerOptions {
  key?: string | Buffer | Array<string | Buffer>;
  cert?: string | Buffer | Array<string | Buffer>;
  ca?: string | Buffer | Array<string | Buffer>;
  // Additional HTTPS options...
}

// From Node.js http module
interface IncomingHttpHeaders {
  [header: string]: string | string[] | undefined;
}

interface OutgoingHttpHeaders {
  [header: string]: number | string | string[] | undefined;
}

// From mime package
interface TypeMap {
  [mimeType: string]: string[];
}

// Rollup Plugin interface
interface Plugin {
  name: string;
  generateBundle?: () => void;
}

// Server Error interface (Node.js)
interface ServerError extends Error {
  code?: string;
  errno?: number;
  syscall?: string;
  address?: string;
  port?: number;
}

Error Handling

The plugin handles common server errors automatically:

  • Port in use (EADDRINUSE): Logs error message and exits process with process.exit()
  • File not found (ENOENT): Returns 404 with descriptive error page showing file path
  • Server errors: Returns 500 with error details, file path, and plugin identifier
  • Path traversal attempts: Uses posix.normalize() to prevent directory traversal attacks

Common error scenarios:

// Error handling is automatic, but you can detect port conflicts:
serve({
  port: 8080,
  onListening: (server) => {
    console.log("Server started successfully");
  }
});

// If port 8080 is in use, the plugin will log:
// "http://localhost:8080 is in use, either stop the other server or use a different port."