Skip to main content
dev 是日常浏览器扩展开发的命令:watch 模式、启动浏览器,以及感知上下文的更新行为。 dev 会运行开发流水线并监听你的项目文件。它会根据变更类型采取不同的更新策略:热模块替换(HMR)、硬重载,或者当变更需要时进行完整重启。

什么时候使用 dev

  • 构建特性并实时验证改动。
  • 在一个或多个浏览器目标里调试扩展行为。
生产产物用 build;生产构建 + 启动用 start;只运行已有构建产物用 preview 如果你的扩展放在 monorepo / 子模块里,请查看 extension.config.* 如何加载 env 文件(包括工作区根的回退):环境变量

dev 命令的能力

用法

如果省略路径,Extension.js 会使用当前工作目录。你也可以传入一个 GitHub tree URL(例如 https://github.com/user/repo/tree/main/path)。Extension.js 会下载该仓库并在本地副本上以开发模式运行。

最常用的 flag

下面这些覆盖了 80% 的场景。其余的请跳到 完整参考

参数与 flag

自动化元数据(推荐用于脚本 / agent)

dev 运行时,Extension.js 会向这些位置写入机器可读的元数据:
  • dist/extension-js/<browser>/ready.json
  • dist/extension-js/<browser>/events.ndjson(每行一个 JSON)
对于自动化(Playwright、持续集成(CI)、AI agent),请优先使用这些文件,而不是解析终端日志。 ready.json 当作就绪契约来用:
  • 启动期间 status: "starting"
  • 运行时就绪时 status: "ready"
  • 启动 / 编译失败时 status: "error"
  • runId 唯一标识一次运行时会话
  • startedAt 标记运行时会话的起始时间戳
  • command 记录产生它的命令(devstartpreviewbuild
  • toolchainVersionextensionNameextensionVersion 记录是哪个 Extension.js 版本、为哪个扩展产出了这棵目录树——终端滚屏丢失后,这个文件仍是一份构建回执
  • controlPort / instanceId 定位 extension logs 与 act verb 使用的控制桥
events.ndjson 只属于当前这次运行:新一次运行开始时文件会重置,且每条记录都盖有本次运行的 runId(与 ready.json 一致),消费者不会看到上一个会话的事件与当前会话交错。 会话行为异常时,运行 extension doctor——它按顺序检查契约、控制通道、令牌、执行器与浏览器,并指出第一个失败的环节和修复方法。

--no-browser 与就绪同步

--no-browser 只会禁用浏览器启动。它并不会在编译完成之前阻塞外部 runner。 对于 Playwright / CI / AI 工作流:
  1. extension dev --no-browser 作为长期运行的进程。
  2. extension dev --wait --browser=<browser> 作为就绪闸门。
  3. 只有在 status: "ready" 之后才启动外部浏览器自动化。
--wait 面向第二个进程(或 CI 步骤),在 error / 超时时以非零状态退出。 当 --wait 看到一个来自已死进程的过期 ready.jsonpid 已不存在)时,它会继续等待一个活跃的生产者。 如果你在同一条命令中同时传入 --wait--no-browser--wait 优先。命令会以 wait-only 模式运行。

--no-reload:得到一个干净的 dev bundle

--no-reload 会跳过 content script 重注入包装器与重建时的重载派发。dev 下的 dist 会更接近生产 bundle,文件变更时已打开的标签页也不会被打扰。你需要自己重载扩展或页面来看到改动。 --no-reload 仅在 extension dev 上受支持。把它传给 startpreviewbuild 会以错误退出。内部上它会设置 EXTENSION_NO_RELOAD=true,方便 develop 进程在 CLI argv 之外读取。

日志 flag

共享的全局选项

也支持 全局 flag

monorepo 与工作区根

你可以把 dev(以及 build)指向一个 monorepo 的根目录,而不是扩展包本身。Extension.js 会检测工作区根,并自动解析其中的扩展包:
如果只找到一个扩展包,Extension.js 会解析它并打印:
如果存在多个候选,会列出来让你指向具体那一个:

示例

运行一个本地扩展

从 GitHub 运行一个远程扩展

把 GitHub tree URL 作为参数传入,即可在本地开发远程扩展:

在 Firefox 中运行

依次在多个浏览器中运行

在 Docker 或 dev container 中运行

当你在 Docker、dev container 或 GitHub Codespaces 中运行时,把 dev 服务器绑定到 0.0.0.0,宿主机才能访问到它:
搭配 --port 0 让 OS 自动选择一个可用端口:

用 Brave 作为自定义二进制运行

最佳实践

  • 浏览器兼容性: 在不同浏览器中测试你的扩展,确保在每个目标上都能工作。
  • polyfill: 如果 Firefox 或 Gecko-based 浏览器也是目标,使用 --polyfill。这个 flag 在 Chromium-based 浏览器中启用 browser.* API 兼容。
  • 自动化可靠性:dev 当作 watch 模式的伴侣(--no-browser + dev --wait);把 start 当作生产的伴侣(--no-browser + start --wait)。脚本与 CI 自动化使用 --wait-format=json

下一步