接上前端框架:React / Vue / Svelte
本教程共 45 篇 · 第 24 篇 · 更新于 2026-08-13 · 约 3 分钟阅读
本节目标:学会用官方模块接入主流前端框架,理解多应用架构与 hash 路由,并知道如何用 Vite 插件接入任意框架。
官方模块:一行配置接入
WXT 为最流行的框架准备了内置模块:@wxt-dev/module-react、@wxt-dev/module-vue、@wxt-dev/module-svelte、@wxt-dev/module-solid。
安装模块,再在 wxt.config.ts 里声明:
pnpm add -D @wxt-dev/module-vue
import { defineConfig } from 'wxt';
export default defineConfig({
modules: ['@wxt-dev/module-vue'],
});
模块会帮你配好 Vite 插件,并加上框架相关的自动导入。wxt_books 的 simple_demo 就是 React 版:装好 react、react-dom 和 @wxt-dev/module-react,配置里写一行 modules: ['@wxt-dev/module-react'],剩下的全是普通 React 代码。
框架组件不仅能用于弹窗、选项页这类页面,也能用在内容脚本的 UI 注入里(如 §15 所述)。模块会处理好构建配置,你在 HTML 页面还是内容脚本里写组件,都能正常工作。
没有官方模块?Vite 插件兜底
任何有 Vite 插件的框架都能用。把插件加进 vite 配置即可:
import { defineConfig } from 'wxt';
import react from '@vitejs/plugin-react';
export default defineConfig({
vite: () => ({
plugins: [react()],
}),
});
官方模块本质上就是「帮你配好插件 + 自动导入」,差别不大。比如 wxt-nuxt-ui-starter 用 Vue 模块,再加 Nuxt UI 的 Vite 插件,就能在扩展里用整套 Nuxt UI 组件。
Note网上老教程里的
extensionApi: 'chrome'配置在 0.21.4 已移除,别照抄。跨浏览器兼容由wxt/browser统一处理,如 §20 所述。
多应用架构:一个入口一个应用
扩展通常有多个 UI 入口:弹窗、选项页、侧边栏、新标签页……每个入口要各自创建一个应用实例。推荐的目录结构:
入口点用单文件还是目录都行(如 §07 所述)。带 UI 的入口用目录形式,把组件、样式、入口脚本放在一起,好维护。
src/
├─ assets/ # 共享资源
├─ components/ # 共享组件
└─ entrypoints/
└─ options/ # 用目录形式,里面放 index.html
├─ pages/ # 路由页面
├─ index.html
├─ App.tsx
├─ main.tsx # 创建并挂载应用
└─ style.css
simple_demo 的弹窗入口就是这个结构。index.html 只放挂载点和入口脚本:
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Default Popup Title</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
main.tsx 负责创建应用:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './style.css';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
Vue 版的入口文件同样简单,把挂载函数换成 createApp 就行:
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import './style.css';
createApp(App).mount('#app');
Svelte 的挂载方式略有不同,但入口结构一致:index.html + main 脚本 + 根组件。框架不同,套路不变。
Tip注意 script 标签的
type="module",HTML 入口必须这样写,原因见 §22。
弹窗、选项页、侧边栏的入口文件约定,分别见 §08、§09、§12。开发模式下,页面入口有即时热更新,改组件立刻可见;脚本类入口改动后,扩展会整体重载。
路由:用 hash 模式
框架自带的路由器默认按 URL 路径工作。但扩展页面是静态文件,URL 形如 chrome-extension://{id}/options.html,没法自由改路径。解决方案是让路由器跑在 hash 模式下:路由信息放进 URL 的 # 后面,比如 options.html#/account/settings。
react-router 用 createHashRouter,vue-router 用 createWebHashHistory,Svelte 系常用 svelte-spa-router(本身就是 hash 路由),Solid 用 solid-router 的 hash 模式。具体写法查各路由文档。
hash 模式天然适合扩展的静态页面:刷新不会 404,#/ 后面的部分也不会发给服务器。这是 popup 里做多页面的标准姿势。
多应用之间怎么协作
每个入口是独立应用,但共享代码照常复用:组件放 src/components/,逻辑放 src/lib/,通过别名导入(如 §22 所述)。状态持久化不要依赖内存,统一走存储,如 §18 所述;入口之间通信走消息通信,如 §17 所述。
小结
- 官方框架模块(module-react / module-vue / module-svelte)一行接入,或手动挂 Vite 插件。
- 每个入口是独立应用,共享代码照常复用(组件、lib、别名)。
- 状态持久化走 storage(§18),跨入口通信走消息(§17),别依赖内存。