常见问题
关于如何使用 WXT 或其行为原因的常见问题。
为什么内容脚本没有被添加到 manifest 中?
在开发过程中,WXT 会动态注册内容脚本,这样在保存文件时可以单独重新加载它们,而无需重新加载整个扩展。
要列出开发过程中注册的内容脚本,请打开 Service Worker 的控制台并运行:
await chrome.scripting.getRegisteredContentScripts();如何禁止开发时自动打开浏览器?
参见 https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser
如何在开发过程中保持网站的登录状态?
参见 https://wxt.dev/guide/essentials/config/browser-startup.html#persist-data
我的组件库在内容脚本中无法正常工作
使用 createShadowRootUi 时,这通常由以下一个(或两个)原因导致:
样式被添加到了
ShadowRoot之外Details
某些组件库会通过添加
<style>或<link>元素来手动将 CSS 添加到页面中。默认情况下,它们会将这些元素放置在文档的<head>中。这会导致你的样式被放置在ShadowRoot之外,而 Shadow DOM 的隔离特性会阻止这些样式应用到你的 UI 上。当组件库出现这种情况时,你需要告诉组件库将样式放在哪里。以下是一些流行组件库的文档:
- Ant Design:
StyleProvider - Mantine:
MantineProvider#getRootElement和MantineProvider#cssVariablesSelector
如果你的组件库未在上面列出,请尝试在其文档/issues 中搜索 "shadow root"、"shadow dom" 或 "css container"。并非所有组件库都支持 Shadow DOM,你可能需要提交 issue 来请求此功能。
以下是配置 Antd 样式的示例:
tsximport { StyleProvider } from '@ant-design/cssinjs'; import ReactDOM from 'react-dom/client'; import App from './App.tsx'; const ui = await create`ShadowRoot`Ui(ctx, { // ... onMount: (container, shadow) => { const cssContainer = shadow.querySelector('head')!; const root = ReactDOM.createRoot(container); root.render( <StyleProvider container={cssContainer}> <App /> </StyleProvider>, ); return root; }, });- Ant Design:
UI 元素被添加到了
ShadowRoot之外Details
这主要是由
Teleport或Portal组件引起的,这些组件会将元素渲染到 DOM 中的其他位置,通常是文档的<body>中。这常见于对话框或弹出层组件。由于元素被渲染到了ShadowRoot之外,样式无法应用到它上面。要解决此问题,你需要同时为应用提供一个目标元素,并将该目标传递给
Teleport/Portal。首先,存储对
ShadowRoot的<body>元素(而非文档的<body>)的引用:tsimport { createApp } from 'vue'; import App from './App.vue'; const ui = await create`ShadowRoot`Ui(ctx, { // ... onMount: (container, shadow) => { const teleportTarget = shadow.querySelector('body')!; const app = createApp(App) .provide('TeleportTarget', teleportTarget) .mount(container); return app; }, }); ui.mount();tsx// hooks/PortalTargetContext.ts import { createContext } from 'react'; export const PortalTargetContext = createContext<HTMLElement>(); // entrypoints/example.content.ts import ReactDOM from 'react-dom/client'; import App from './App.tsx'; import PortalTargetContext from '~/hooks/PortalTargetContext'; const ui = await create`ShadowRoot`Ui(ctx, { // ... onMount: (container, shadow) => { const portalTarget = shadow.querySelector('body')!; const root = ReactDOM.createRoot(container); root.render( <PortalTargetContext.Provider value={portalTarget}> <App /> </PortalTargetContext.Provider>, ); return root; }, }); ui.mount();然后在将 UI 的一部分传送/传递到 DOM 中的其他位置时使用该引用:
vue<script lang="ts" setup> import { Teleport } from 'vue'; const teleportTarget = inject('TeleportTarget'); </script> <template> <div> <Teleport :to="teleportTarget"> <dialog>My dialog</dialog> </Teleport> </div> </template>tsximport { useContext } from 'react'; import { createPortal } from 'react-dom'; import PortalTargetContext from '~/hooks/PortalTargetContext'; const MyComponent = () => { const portalTarget = useContext(PortalTargetContext); return <div>{createPortal(<dialog>My dialog</dialog>, portalTarget)}</div>; };如果你使用 ShadCN,请参阅这篇博客文章。
这两个问题有相同的根本原因:组件库将某些内容放置在了 ShadowRoot 之外,而 ShadowRoot 的隔离特性阻止了 CSS 应用到你的 UI 上。
这两个问题的解决方法也相同:告诉组件库将元素放置在 ShadowRoot 内部,而不是外部。请参阅上面的详细信息,了解更多信息和每个问题的示例修复方法。
WXT 是否提供 LLM 文档?
是的,WXT 的文档基于 /llms.txt 提案 提供了 Markdown 文件。
是否有基于 WXT 文档训练的 LLM 可以对话?
是的!页面右下角有一个 "Ask AI" 按钮,快试试吧!或者访问 https://knowledge.wxt.dev/ 获得全屏体验。
此外,如果你想训练自己的模型或为编辑器提供上下文,可以使用网站托管的 LLM 知识文件:
https://wxt.dev/knowledge/index.json
你不需要爬取整个网站,这些文件已经包含了所有与训练 LLM 相关的 WXT 文档。但如果你愿意,也可以自行爬取并生成自己的文件!
如何使用 Docker / devcontainers 运行 WXT 项目?
要在 devcontainer 中运行 WXT 开发服务器,但在浏览器中加载扩展的开发构建版本:
将项目目录绑定挂载到宿主机 如果你使用 VS Code,可以通过
Dev Containers: Open Folder in Container...命令打开项目文件夹。这会保持文件夹在宿主机和 devcontainer 之间的同步,确保扩展的dist目录从宿主机仍然可以访问。禁用自动打开浏览器 WXT 在开发过程中会自动打开浏览器,但由于你在容器中运行,它无法访问浏览器。请按照此处的指南在
wxt.config.ts中禁用浏览器自动打开。让 WXT 监听所有网络接口 要启用热重载,你的扩展需要连接到容器内运行的 WXT 开发服务器。WXT 默认只监听
localhost,这会阻止来自 devcontainer 外部的连接。要解决此问题,你可以使用wxt --host 0.0.0.0让 WXT 监听所有接口。
如何使用 Chrome 的新 Prompt API?
如果你让 WXT 在开发模式下打开浏览器,负责 Prompt API 的服务默认不会启用。检查 LanguageModel.availability 时,你将始终收到 "unavailable"。
你有两个选择:
传递
--disable-features=DisableLoadExtensionCommandLineSwitch功能标志以在 WXT 打开的浏览器中启用该服务:ts// wxt.config.ts export default defineConfig({ webExt: { chromiumArgs: [ '--disable-features=DisableLoadExtensionCommandLineSwitch', ], }, });禁用 runner 并在常规 Chrome 配置文件中手动安装扩展:
ts// wxt.config.ts export default defineConfig({ webExt: { disabled: true, }, });