首页 / WXT 浏览器扩展框架教程 / 接上前端框架:React / Vue / Svelte

WXT 浏览器扩展框架教程

接上前端框架:React / Vue / Svelte

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

WXTReactVueSvelte前端框架路由

本节目标:学会用官方模块接入主流前端框架,理解多应用架构与 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),别依赖内存。