or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-web--dev-server-esbuild

Plugin for using esbuild in @web/dev-server to transform TypeScript, JSX, TSX, and JavaScript files during development

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@web/dev-server-esbuild@1.0.x

To install, run

npx @tessl/cli install tessl/npm-web--dev-server-esbuild@1.0.0

index.mddocs/

@web/dev-server-esbuild

@web/dev-server-esbuild is a plugin for @web/dev-server that integrates esbuild to transform TypeScript, JSX, TSX, and JavaScript files during development. It provides fast, efficient code transformation with automatic browser target detection and supports configurable compilation options.

Package Information

  • Package Name: @web/dev-server-esbuild
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @web/dev-server-esbuild
  • Peer Dependencies: Requires @web/dev-server or @web/dev-server-core for plugin integration

Core Imports

The package exports a single function esbuildPlugin:

import { esbuildPlugin } from "@web/dev-server-esbuild";

For CommonJS:

const { esbuildPlugin } = require("@web/dev-server-esbuild");

Note: The package only exports the esbuildPlugin function. All types (EsBuildPluginArgs, Plugin, Context, etc.) are available for TypeScript users through the type definitions, but are not runtime exports.

Basic Usage

import { createConfig } from '@web/dev-server';
import { esbuildPlugin } from '@web/dev-server-esbuild';

export default createConfig({
  plugins: [
    // Basic TypeScript support
    esbuildPlugin({ ts: true }),
    
    // JSX support with custom factory
    esbuildPlugin({ 
      jsx: true, 
      jsxFactory: 'h',
      jsxFragment: 'Fragment'
    }),
    
    // Multiple file types with auto targeting
    esbuildPlugin({
      ts: true,
      tsx: true,
      jsx: true,
      target: 'auto'
    })
  ]
});

Capabilities

Plugin Factory

Creates and configures an esbuild plugin instance for @web/dev-server.

/**
 * Creates an esbuild plugin instance for @web/dev-server
 * @param args - Configuration options for the plugin
 * @returns Plugin instance compatible with @web/dev-server
 */
function esbuildPlugin(args?: EsBuildPluginArgs): Plugin;

interface EsBuildPluginArgs {
  /** Compilation target (e.g., 'es2020', 'auto', 'auto-always') or array of targets */
  target?: string | string[];
  /** Enable JavaScript compilation */
  js?: boolean;
  /** Enable TypeScript compilation */
  ts?: boolean;
  /** Enable JSON loading */
  json?: boolean;
  /** Enable JSX compilation */
  jsx?: boolean;
  /** Enable TSX compilation */
  tsx?: boolean;
  /** JSX factory function (e.g., 'React.createElement', 'h') */
  jsxFactory?: string;
  /** JSX fragment (e.g., 'React.Fragment', 'Fragment') */
  jsxFragment?: string;
  /** Custom file extension loaders */
  loaders?: Record<string, Loader>;
  /** Global constants replacement for define transforms */
  define?: { [key: string]: string };
  /** Path to TypeScript config file */
  tsconfig?: string;
  /** Code to prepend to all transformed files */
  banner?: string;
  /** Code to append to all transformed files */
  footer?: string;
}

Target Options

The target option controls compilation output:

  • 'auto' - Automatically detects browser capabilities from user agent. Skips compilation for modern browsers, falls back to ES module compatible code for older browsers
  • 'auto-always' - Similar to 'auto' but always compiles, using modern targets for recent browsers
  • Specific targets like 'es2020', 'es2019' - Compile to specific ECMAScript versions
  • Array of browser targets like ['chrome80', 'firefox75', 'safari13']

File Type Support

Enable transformation for different file types:

// TypeScript files (.ts)
esbuildPlugin({ ts: true })

// JSX files (.jsx) 
esbuildPlugin({ jsx: true })

// TSX files (.tsx)
esbuildPlugin({ tsx: true })

// JSON files (.json)
esbuildPlugin({ json: true })

// JavaScript files (.js) - useful with custom targets
esbuildPlugin({ js: true, target: 'es2015' })

// Multiple types
esbuildPlugin({ ts: true, tsx: true, jsx: true, json: true })

Custom Loaders

Configure how specific file extensions are processed:

esbuildPlugin({
  loaders: {
    '.foo': 'text',     // Load .foo files as text
    '.bar': 'json',     // Load .bar files as JSON
    'scss': 'css'       // Load .scss files as CSS (extension dot is optional)
  }
})

JSX Configuration

Customize JSX transformation:

// React
esbuildPlugin({ 
  jsx: true,
  jsxFactory: 'React.createElement',
  jsxFragment: 'React.Fragment'
})

// Preact
esbuildPlugin({ 
  jsx: true,
  jsxFactory: 'h',
  jsxFragment: 'Fragment'
})

// Custom JSX
esbuildPlugin({ 
  jsx: true,
  jsxFactory: 'myCreateElement',
  jsxFragment: 'myFragment'
})

TypeScript Integration

Use with TypeScript configuration:

esbuildPlugin({
  ts: true,
  tsconfig: './tsconfig.json'  // Path to TypeScript config
})

Code Transformation

Add code banners and footers:

esbuildPlugin({
  ts: true,
  banner: '/* Generated code - do not edit */',
  footer: '/* End of generated code */'
})

Global Definitions

Replace global constants during compilation:

esbuildPlugin({
  ts: true,
  define: {
    'process.env.NODE_ENV': '"development"',
    '__VERSION__': '"1.0.0"',
    'DEBUG': 'true'
  }
})

Types

The following types are available when using TypeScript. Import them from their respective packages:

// Main function and its configuration
import { esbuildPlugin } from '@web/dev-server-esbuild';
import type { EsBuildPluginArgs } from '@web/dev-server-esbuild';

// Plugin-related types from @web/dev-server-core
import type { Plugin, Context, PluginSyntaxError } from '@web/dev-server-core';

// esbuild types
import type { Loader } from 'esbuild';
/** esbuild loader type for different file extensions (from 'esbuild') */
type Loader = 'js' | 'jsx' | 'ts' | 'tsx' | 'css' | 'json' | 'text' | 'base64' | 'dataurl' | 'file' | 'binary';

/** @web/dev-server plugin interface (imported from '@web/dev-server-core') */
interface Plugin {
  name: string;
  injectWebSocket?: boolean;
  serverStart?(args: ServerStartParams): void | Promise<void>;
  serverStop?(): void | Promise<void>;
  serve?(context: Context): ServeResult | Promise<ServeResult>;
  transform?(context: Context): TransformResult | Promise<TransformResult>;
  transformCacheKey?(context: Context): string | undefined | Promise<string> | Promise<undefined>;
  resolveImport?(args: {
    source: string;
    context: Context;
    code?: string;
    column?: number;
    line?: number;
    resolveOptions?: ResolveOptions;
  }): ResolveResult | Promise<ResolveResult>;
  resolveImportSkip?(context: Context, source: string, importer: string): void;
  transformImport?(args: {
    source: string;
    context: Context;
    code?: string;
    column?: number;
    line?: number;
  }): ResolveResult | Promise<ResolveResult>;
  resolveMimeType?(context: Context): ResolveMimeTypeResult | Promise<ResolveMimeTypeResult>;
  fileParsed?(context: Context): void;
}

/** Server start parameters for plugin initialization */
interface ServerStartParams {
  config: DevServerCoreConfig;
  app: Koa;
  server?: Server;
  fileWatcher: FSWatcher;
  logger: Logger;
  webSockets?: WebSocketsManager;
}

/** Plugin method return types */
type ServeResult = void | string | { body: string; type?: string; headers?: Record<string, string> };
type TransformResult = void | string | { body?: string; headers?: Record<string, string>; transformCache?: boolean };
type ResolveResult = void | string | { id?: string };
type ResolveMimeTypeResult = void | string | { type?: string };

/** Resolve options for import resolution */
interface ResolveOptions {
  isEntry?: boolean;
  skipSelf?: boolean;
  [key: string]: unknown;
}

/** Koa Context interface (imported from 'koa' package) */
interface Context {
  /** Request URL path */
  path: string;
  /** Parsed URL object */
  url: URL;
  /** Request headers */
  headers: Record<string, string>;
  /** Request/Response body */
  body: string | Buffer;
  /** Response helpers */
  response: {
    /** Check if response matches a MIME type */
    is(type: string): boolean;
  };
  /** Additional Koa context properties available but not commonly used by plugins */
}

/** Error thrown when plugin encounters syntax errors during transformation */
class PluginSyntaxError extends Error {
  constructor(
    public message: string,
    public filePath: string,
    public code: string,
    public line: number,
    public column: number,
  );
}

Advanced Usage

Browser-Specific Targeting

The plugin automatically detects browser capabilities and adjusts compilation accordingly:

// Automatic browser detection
esbuildPlugin({ target: 'auto', ts: true })
// - Modern Chrome/Firefox/Edge: compiles to 'esnext' (minimal transformation)
// - Latest Safari: compiles to Safari-specific target
// - Older browsers: compiles to ES module compatible code

HTML Inline Script Transformation

The plugin automatically transforms inline scripts in HTML files:

<script type="module">
  // This TypeScript code will be transformed
  const message: string = 'Hello, world!';
  console.log(message);
</script>

Import Resolution

For TypeScript files, the plugin handles .js import resolution by checking for corresponding .ts files:

// In a .ts file, this import:
import { helper } from './utils.js';
// Will resolve to ./utils.ts if it exists

Error Handling

The plugin provides detailed error information for compilation failures through the PluginSyntaxError class:

// Example of syntax error thrown by the plugin
throw new PluginSyntaxError(
  'Unexpected token',           // Error message
  '/path/to/file.ts',          // File path where error occurred
  'const x: invalid syntax;',   // Code that caused the error
  5,                           // Line number (1-based)
  12                           // Column number (1-based)
);

Error Types:

  • Syntax Errors: Reports exact line and column numbers with code context via PluginSyntaxError
  • Type Errors: Integrates with TypeScript configuration for type checking (when tsconfig is specified)
  • Build Failures: Provides clear error messages from esbuild's internal error reporting
  • Warning Messages: Non-fatal warnings are logged but don't stop transformation

Common Error Scenarios:

  • Invalid TypeScript syntax in .ts/.tsx files
  • Missing JSX factory configuration when using JSX without React
  • Unsupported file extensions without proper loaders configured
  • Malformed tsconfig.json files when tsconfig option is specified
  • Invalid esbuild target specifications

Error Handling Behavior:

The plugin filters certain warnings (like "Unsupported source map comment") to reduce noise, but reports all compilation errors. Errors include detailed location information when available from esbuild.