JSPM

  • Created
  • Published
  • Downloads 1352
  • Score
    100M100P100Q103420F
  • License MIT

The develop step of Extension.js

Package Exports

  • extension-develop
  • extension-develop/dist/module.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (extension-develop) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Empowering Version Downloads

extension-develop

Develop, build, preview, and package Extension.js projects.

This package powers Extension.js during local development and production builds. It provides the commands and build plugins that compile your extension, run it in browsers, and produce distributable artifacts.

Installation

pnpm add extension-develop

Usage

import {
  extensionDev,
  extensionBuild,
  extensionStart,
  extensionPreview,
  cleanupCommand,
  type DevOptions,
  type BuildOptions,
  type StartOptions,
  type PreviewOptions
} from 'extension-develop'

async function run() {
  // Development server
  await extensionDev(undefined, {
    browser: 'chrome',
    open: true
  } satisfies DevOptions)

  // Production build + zip
  await extensionBuild(undefined, {
    browser: 'firefox',
    zip: true
  } satisfies BuildOptions)

  // Build then preview from dist/<browser>
  await extensionStart(undefined, {browser: 'edge'} satisfies StartOptions)

  // Preview using an existing output folder or project path
  await extensionPreview(undefined, {
    browser: 'chrome',
    mode: 'production'
  } satisfies PreviewOptions)

  // Cleanup orphaned browser instances
  await cleanupCommand()
}

run()

Features

  • Live reload/HMR development server with per-instance browser runners
  • Cross-browser support: Chrome, Edge, Firefox, Chromium-based, Gecko-based
  • Rspack-based build with opinionated plugin stack
  • Clean production output in dist/<browser>
  • Zipping: distribution and/or source packages (respects .gitignore)
  • Auto-install of missing dependencies and package manager detection
  • Type generation for TS projects via extension-env.d.ts
  • User config via extension.config.(js|mjs) for commands, browser launch, and webpack config hooks
  • Managed dependency guard to avoid conflicts

Commands

Name Summary
dev - Starts a local development server with live reload/HMR
- Auto-installs dependencies if missing
- Generates TypeScript shim types (extension-env.d.ts) when applicable
- Launches a target browser with an isolated/stable profile
build - Production build using the webpack/Rspack plugin stack
- Cleans dist/<browser> before emitting
- Optional packaging: distribution zip and/or source zip
- Merges user config; excludes browser runners during compilation
start - Runs a silent production build, then launches preview from dist/<browser>
- Mirrors the runtime environment of shipped output
preview - Launches the extension for manual testing without dev server
- Uses dist/<browser> when present, otherwise uses the project directory
- Preserves production settings; only browser runners are applied
cleanup - Removes orphaned browser instances and temporary profiles created during development

Command options

Options accepted by each command. Values shown are typical types or enumerations; see the tables for specifics.

Common (browser/runtime)

Option Type / Values Description
browser chrome, edge, firefox, chromium-based, gecko-based Target browser/runtime
profile string or false Profile path or disable profile persistence
startingUrl string Initial URL to open
open boolean Focus/open the browser window
chromiumBinary string Custom Chromium-based executable path
geckoBinary string Custom Gecko-based executable path

dev

Option Type / Values Description
mode development, production, none Build mode
polyfill boolean Include webextension-polyfill when possible
port number or string Dev server port
source string Inspect a source directory
watchSource boolean Watch the source directory

build

Option Type / Values Description
zip boolean Package dist/<browser> as an artifact (e.g., .zip, .xpi)
zipSource boolean Package source files (respects .gitignore)
zipFilename string Custom base name for artifacts
polyfill boolean Include webextension-polyfill when possible
silent boolean Suppress non-error logs

start

Option Type / Values Description
mode production Build mode
polyfill boolean Include webextension-polyfill when possible

preview

Option Type / Values Description
mode production Build mode
outputPath string Directory to run from (defaults to dist/<browser> when available)

Project detection and inputs

  • Path or remote: Commands accept a local path or a remote URL.
    • GitHub repo URL: downloaded via go-git-it into a subfolder named after the repository.
    • Other HTTP(S) URLs: treated as zip archives and extracted locally.
  • Monorepos: The nearest manifest.json is resolved recursively; the nearest valid package.json is then located and validated.

User config

  • Provide extension.config.js or extension.config.mjs in your project root.
  • Supported sections:
    • config(config: Configuration): mutate the assembled Rspack config.
    • commands.dev | .build | .start | .preview: per-command options (browser, profile, binaries, flags, preferences, packaging).
    • browser.chrome | .firefox | .edge | .chromium-based | .gecko-based: launch flags, excluded flags, preferences, binaries, and profile reuse.
  • When detected, a one‑time notice is printed to indicate config is active.

Environment variables in extension.config.*

  • extension.config.* runs in a Node context during command startup.
    • Use process.env.* to read environment variables inside the config file.
    • import.meta.env.* is available in your extension code at bundle time (via the Env plugin), not in the Node config.
  • During config loading, develop preloads environment files from the project directory into process.env using the following order (first match wins):
    1. .env.defaults (always merged first when present)
    2. .env.development
    3. .env.local
    4. .env
  • Only variables you read explicitly in the config are used there; client-side injection still requires the EXTENSION_PUBLIC_* prefix.
  • Example:
// extension.config.js (Node-based)
export default {
  browser: {
    chrome: {
      startingUrl:
        process.env.EXTENSION_PUBLIC_START_URL || 'https://example.com'
    }
  },
  config: (config) => config
}

Safety and ergonomics

  • Managed dependency guard: If your extension.config.* references dependencies that are managed by Extension.js itself, the command aborts with a detailed message to prevent version conflicts.
  • Auto‑install: If node_modules is missing, the appropriate package manager is detected and dependencies are installed before running.
  • Type generation: For TypeScript projects, extension-env.d.ts is generated/updated to include required types and polyfills.

Packaging outputs

  • Distribution artifacts live under dist/<browser>/ and source artifacts under dist/.
  • File names default to a sanitized form of manifest.name plus manifest.version (override with zipFilename).
  • Source packaging respects .gitignore.

Example layout when both zip and zipSource are enabled:

dist/
  chrome/
    <name>-<version>.zip
  <name>-<version>-source.zip

Notes and compatibility

  • Built on the same Rspack stack as @/webpack; user config is loaded when an extension.config.* is present.
  • Only EXTENSION_PUBLIC_* variables are injected into client code; avoid secrets in templated .json/.html.

Plugins

Name Group Summary
plugin-extension core - Core builder: emits pages and scripts
- Validates and rewrites manifest.json
- Ships icons, JSON, locales, and web resources
- Ensures dev parity between local and shipped output
plugin-css core - Auto‑wires CSS for HTML and content scripts
- Optional SASS/LESS/PostCSS when configs exist
- Integrates Stylelint when configured
plugin-js-frameworks core - Detects React/Preact/Vue/Svelte and TypeScript
- Configures SWC parsing, loaders/plugins, and safe aliases
- Sets tsconfig resolution
- Defers heavy work to beforeRun in production
plugin-static-assets core - Emits images, fonts, and misc files to assets/
- Inlines small SVGs (≤2KB), emits larger ones
- Content hashing in production; stable names in development
- Respects existing custom SVG rules
plugin-compatibility core - Cross‑browser helpers
- Normalizes browser‑specific manifest fields
- Optional webextension-polyfill for Chromium
plugin-compilation core - Loads env and templating (EXTENSION_PUBLIC_*)
- Optional dist/<browser> cleaning
- Compact, de‑duplicated compilation summary
plugin-reload core - Dev‑time live reload/HMR orchestration
- Per‑instance WebSocket server
- Manifest dev overrides
- Full recompiles on HTML entry changes

Notes and compatibility

  • Built against @rspack/core; Webpack 5 may work for some plugins but is not officially supported here.
  • Only EXTENSION_PUBLIC_* variables are injected into client code; avoid embedding secrets in templated .json/.html.
  • webpack/webpack-config.ts: Assembles the plugin stack and shared configuration.
  • webpack/dev-server.ts: Local development server wiring and reload orchestration.
  • webpack/webpack-types.ts: Common types for the plugin stack.

License

MIT (c) Cezar Augusto and the Extension.js Authors.