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
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.
- GitHub repo URL: downloaded via
- Monorepos: The nearest
manifest.json
is resolved recursively; the nearest validpackage.json
is then located and validated.
User config
- Provide
extension.config.js
orextension.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.
- Use
- During config loading, develop preloads environment files from the project directory into
process.env
using the following order (first match wins):.env.defaults
(always merged first when present).env.development
.env.local
.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 underdist/
. - File names default to a sanitized form of
manifest.name
plusmanifest.version
(override withzipFilename
). - 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 anextension.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
.
Related files in this folder
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.