入口点加载器
在构建时生成 manifest 和其他文件,WXT 必须导入每个入口点以获取它们的选项,例如内容脚本 matches
。对于 HTML 文件,这很简单。但对于 JS/TS 入口点,这个过程要复杂得多。
当加载你的 JS/TS 入口点时,它们会被导入到 NodeJS 环境中,而不是它们通常运行的浏览器环境。这可能导致在 NodeJS 环境中运行仅适用于浏览器的代码时出现的问题,例如缺少全局变量。
WXT 会进行多步预处理以尽量避免在此过程中出现错误:
- 使用
linkedom
创建一组小的浏览器全局(如window
、document
等)。 - 使用
@webext-core/fake-browser
创建一个假的chrome
和browser
全局,这些全局由扩展期望。 - 预处理 JS/TS 代码,移除主函数,然后从文件中切片未使用的代码
然而,这个过程并不完美。它没有设置浏览器中所有找到的全局,并且 API 的行为可能不同。因此,请避免在你的入口点的主要函数外使用浏览器或扩展 API!
TIP
如果你在导入入口点时遇到错误,请运行 wxt prepare --debug
以查看此过程中的更多细节。在调试时,WXT 会输出预处理的代码以帮助你识别问题。
一旦环境已多填补并你的代码预处理完成,就由入口点加载器导入你的代码并提取选项。
你可以通过以下两种方式加载你的入口点:
vite-node
- 默认从v0.19.0
开始jiti
(已弃用,将在v0.20.0
中删除) - 在v0.19.0
之前默认
vite-node
自 v0.19.0
以来,WXT 使用 vite-node
(即 powers Vitest 和 Nuxt 的同一工具)来导入你的入口点文件。它重新使用了构建你扩展时使用的相同 Vite 配置,因此是最稳定的入口点加载器。
jiti
要启用 jiti
:
ts
export default defineConfig({
entrypointLoader: 'jiti',
});
这是 WXT 使用的原始方法来导入 TS 文件。然而,因为它不支持 Vite 节外生枝如 vite-node
,所以它执行一个额外的预处理步骤:它移除 所有 导入。
这意味着你不能在 JS 入口点的主要函数外使用外部变量(例如内容脚本 matches
或其他选项):
ts
// entrypoints/content.ts
import { GOOGLE_MATCHES } from '~/utils/match-patterns';
export default defineContentScript({
matches: GOOGLE_MATCHES,
main() {
// ...
},
});
$ wxt build
wxt build
WXT 0.14.1
ℹ Building chrome-mv3 for production with Vite 5.0.5
✖ Command failed after 360 ms
[8:55:54 AM] ERROR entrypoints/content.ts: Cannot use imported variable "GOOGLE_MATCHES" before main function.
通常,这个错误发生在试图将选项提取到共享文件中或在主要函数外运行代码时。要修复上面的例子,请改为使用字面值而不是导入它们:
ts
import { GOOGLE_MATCHES } from '~/utils/match-patterns';
export default defineContentScript({
matches: GOOGLE_MATCHES,
matches: ['*//*.google.com/*'],
main() {
// ...
},
});