首页 / WXT 浏览器扩展框架教程 / 调试与避坑手册

WXT 浏览器扩展框架教程

调试与避坑手册

本教程共 45 篇 · 第 40 篇 · 更新于 2026-08-13 · 约 4 分钟阅读

WXT调试Console常见错误避坑service worker

本节目标:掌握「先判断环境、再按顺序排查」的调试方法论,学会定位扩展开发中最高频的几类错误,并了解全册已经讲过的坑点清单。

第一步:错误属于哪个环境

扩展代码跑在多个环境里,每个环境有自己的 Console。只盯着启动 WXT 的终端,是调试最常见的误区——终端只报构建和类型错误,运行时报错要去浏览器里看。

问题位置打开方式
弹窗(popup)右键弹窗内部 → 检查
选项页 / newtab / tabs在对应页面打开 DevTools
侧边栏检查侧边栏面板页面
后台(background)chrome://extensions 里点击 service worker
内容脚本在匹配的目标网页打开 DevTools
Firefox 后台about:debugging 里检查该扩展
构建 / 类型错误运行 WXT 的终端

先复现,再记录:浏览器、入口点、URL、是否刚刷新过扩展、准确报错文本。记录越全,定位越快。

推荐检查顺序

小改动完成后,按成本从低到高:

  1. typecheck——类型错误最先暴露;
  2. lint;
  3. 涉及已有逻辑时,跑最窄的单元测试(如 §36 所述);
  4. 涉及 wxt.config.ts、入口点、public 资源、manifest 时,跑 build;
  5. 完整发布检查:lint → typecheck → test → build。

这些命令替代不了真实 UI、OAuth 和跨浏览器的人工验证。

高频错误定位

Cannot find module ‘#imports’ 或 WXT 类型缺失

生成类型没跟上。重新跑 wxt prepare(postinstall 里通常已配置)。确认 tsconfig.json 继承了 .wxt/tsconfig.json——不要手写一个假的 #imports 声明去骗编译器(如 §29 所述)。

内容脚本没有运行

按顺序查六项:

  1. 文件是否在入口点目录、命名是否符合规则(如 §11 所述);
  2. 当前 URL 是否匹配 matches;
  3. 扩展和目标标签页是否都刷新过;
  4. 是否在目标网页的 Console 里看日志(不是扩展页);
  5. 生成 manifest 里是否包含该脚本;
  6. 开发模式下内容脚本是动态注册的,不进 manifest,这是正常现象。用 service worker 控制台确认:
await chrome.scripting.getRegisteredContentScripts();

Extension context invalidated

扩展重载后,旧页面里残留的脚本会报这个错。刷新目标标签页;更根本的解法是用内容脚本的 ctx 管理监听器与异步任务,失效时自动清理(如 §14 所述)。

background 日志找不到

background 的 console 不在弹窗里,去 chrome://extensions 点 service worker 打开。MV3 worker 休眠是正常行为(如 §10 所述),先触发对应事件或消息,再观察日志。

跨域或网络错误

检查四处是否一致:.env 里的 API 地址、生成 manifest 的 host permissions、后端 CORS、认证服务的 trusted origins。改 .env 后必须重启开发进程。不要用 <all_urls> 掩盖配置问题。

manifest 配置改了没生效

WXT 的 HMR 不总能替换扩展安装清单。停掉开发进程、重新启动、在扩展管理页刷新,必要时移除旧的临时扩展再加载。

弹窗里的下拉菜单被裁剪、主题不对

在真实弹窗里检查,不要直接开 popup.html 标签页(环境不同)。确认 portal 所在文档的 有 dark class,检查固定宽度与滚动容器。

检查产物,别把 build 当源码

构建后打开 .output/{browser}-{mv}/manifest.json,核对权限、入口、版本、图标与 _locales(如 §38 所述)。build 目录是生成物,修改它不等于修了源码。

日志安全

允许记录:功能阶段、状态码、不含隐私的错误类型。禁止记录:bearer token 与 Authorization 头、密码与表单完整内容、OAuth 完整回调 URL、未经需要的页面正文与浏览历史。

全册坑点速查

下面是 mkext 项目代码审查里真实踩过的坑,详细展开都在前文各章,这里只列入口:

  • 内容脚本清理:WXT 不会调用 main() 的返回值,清理逻辑要挂在 ctx.onInvalidated 上(§14);
  • 重扫风暴:高频 DOM 变更用 ctx.setTimeout 防抖(§14);
  • OAuth 错误区分:getAuthToken 的错误码与 UI 文案要一致,用户取消要单独识别(§35 的 Firefox 兼容部分);
  • token 缓存失效:后端拒绝 token 后要调 removeCachedAuthToken,否则重试永远用死 token(§35);
  • Chrome 专属字段混入 Firefox 包:key、oauth2 等要按浏览器剥离(§35);
  • 依赖废弃 API:升级依赖时留意,如 Zod 4 已废弃 z.nativeEnum(mkext 的 env.config.ts 就踩过);
  • worker 内存不持久:状态要进 storage,别指望内存(§10、§18);
  • 消息不可信:跨上下文消息入参按 unknown 校验(§17);
  • 类型导入:避免无谓 re-export 拖入无关代码,注意 bundle 体积(§22)。

调试心态

先复现,再二分:是构建问题、权限问题,还是 URL 不匹配?三类问题在生成 manifest 里都能看到痕迹。检查产物而不是猜,是调试效率最高的习惯。

小结

  • 先复现,再二分:构建问题、权限问题、URL 不匹配,在生成 manifest 里都有痕迹。
  • 各环境(后台 / 内容脚本 / 弹窗 / 扩展页面)的 Console 是分开的,先找对地方。
  • 高频坑点速查表挂在 mkext 的真实代码审查上,遇到问题先查一遍再动手。