静态资源
/assets 目录
在 <srcDir>/assets/ 目录中导入或引用的任何资源都会被 WXT 的打包工具处理。
以下是访问方式:
import imageUrl from '~/assets/image.png';
const img = document.createElement('img');
img.src = imageUrl;<!-- 在 HTML 标签中,必须使用相对路径 --->
<img src="../assets/image.png" />.bg-image {
background-image: url(~/assets/image.png);
}<script>
import image from '~/assets/image.png';
</script>
<template>
<img :src="image" />
</template>import image from '~/assets/image.png';
<img src={image} />;/public 目录
<rootDir>/public/ 目录中的文件会被原样复制到输出文件夹中,不会经过 WXT 的打包工具处理。
以下是访问方式:
import imageUrl from '/image.png';
const img = document.createElement('img');
img.src = imageUrl;<img src="/image.png" />.bg-image {
background-image: url(/image.png);
}<template>
<img src="/image.png" />
</template><img src="/image.png" />WARNING
public/ 目录中的资源在 Content Script 中默认**不可**访问。要在 Content Script 中使用公共资源,必须将其添加到 Manifest 的 web_accessible_resources 数组 中。
在 Content Script 中使用
Content Script 中的资源处理方式略有不同。默认情况下,当你导入一个资源时,它只返回资源的路径。这是因为 Vite 假设你从相同的主机名加载资源。
但在 Content Script 中,主机名是当前标签页所设置的。因此,如果你尝试获取该资源(无论是手动获取还是作为 <img> 的 src),它将从标签页的网站加载,而不是从你的扩展加载。
要解决这个问题,你需要使用 browser.runtime.getURL 将路径转换为完整的 URL:
import iconUrl from '/icon/128.png';
export default defineContentScript({
matches: ['*://*.google.com/*'],
main() {
console.log(iconUrl); // "/icon/128.png"
console.log(browser.runtime.getURL(iconUrl)); // "chrome-extension://<id>/icon/128.png"
},
});WASM
.wasm 文件的加载方式因包而异,但大多数都遵循一个基本模式:使用 JS API 来加载和执行 .wasm 文件。
对于扩展来说,这意味着两件事:
.wasm文件需要存在于输出文件夹中,以便被加载。- 你必须导入 JS API 来加载和初始化
.wasm文件,通常由 NPM 包提供。
举个例子,假设你有一个 Content Script 需要将 TS 代码解析为 AST。我们将使用 @oxc-parser/wasm 来完成!
首先,我们需要将 .wasm 文件复制到输出目录。我们通过 WXT 模块 来实现:
// modules/oxc-parser-wasm.ts
import { resolve } from 'node:path';
export default defineWxtModule((wxt) => {
wxt.hook('build:publicAssets', (_, assets) => {
assets.push({
absoluteSrc: resolve(
'node_modules/@oxc-parser/wasm/web/oxc_parser_wasm_bg.wasm',
),
relativeDest: 'oxc_parser_wasm_bg.wasm',
});
});
});运行 wxt build,你应该能看到 WASM 文件被复制到 .output/chrome-mv3 文件夹中!
接下来,由于这是在 Content Script 中,我们需要通过网络获取 WASM 文件来加载它,因此需要将该文件添加到 web_accessible_resources 中:
export default defineConfig({
manifest: {
web_accessible_resources: [
{
// 我们也会在 Content Script 中使用这个 matches
matches: ['*://*.github.com/*'],
// 使用与 WXT 模块中 `relativeDest` 相同的路径
resources: ['/oxc_parser_wasm_bg.wasm'],
},
],
},
});最后,我们需要在 Content Script 中加载并初始化 .wasm 文件才能使用它:
import initWasm, { parseSync } from '@oxc-parser/wasm';
export default defineContentScript({
matches: '*://*.github.com/*',
async main(ctx) {
if (!location.pathname.endsWith('.ts')) return;
// 从 GitHub 获取文本
const code = document.getElementById(
'read-only-cursor-text-area',
)?.textContent;
if (!code) return;
const sourceFilename = document.getElementById('file-name-id')?.textContent;
if (!sourceFilename) return;
// 加载 WASM 文件:
await initWasm({
module_or_path: browser.runtime.getURL('/oxc_parser_wasm_bg.wasm'),
});
// 加载完成后,就可以使用 `parseSync` 了!
const ast = parseSync(code, { sourceFilename });
console.log(ast);
},
});这段代码直接取自 @oxc-parser/wasm 文档,但有一个例外:我们手动传入了文件路径。在标准的 NodeJS 或 Web 项目中,默认路径可以正常工作,因此你不需要传入任何内容。然而,扩展是不同的。你应该始终显式传入输出目录中 WASM 文件的完整 URL,这正是 browser.runtime.getURL 返回的内容。
运行你的扩展,你应该能看到 OXC 解析 TS 文件了!