@multiplatform.one / vite-plugin-webext
构建浏览器web扩展(MV3视图,
后台服务工作者,内容脚本)作为目标的一个
多平台。三个vite构建覆盖了三个JS世界
(DOM扩展页面、worker、注入内容脚本);
runWebextPrepare 编写清单和开发模式HMR脚手架
到一个可加载的暂存目录:
<stagingDir>/manifest.json
<stagingDir>/dist/views/<view>/index.html (popup/options/sidepanel/…)
<stagingDir>/dist/background/index.mjs (service worker / bg script)
<stagingDir>/dist/contentScripts/index.global.js
<stagingDir>/dist/contentScripts/webext.css (web-accessible resource)
使用
每个JS世界一个配置文件,加上一个准备脚本。每一个目录
下 <targetDir>/views/ 与一个 index.html 变成了一个扩展
页面。
// vite.config.webext.ts — extension pages (popup/options/…)
import { resolve } from "node:path";
import { createWebextViewsConfig } from "@multiplatform.one/vite-plugin-webext";
import { defineConfig } from "vite";
import packageJson from "./package.json";
export default defineConfig(async () =>
createWebextViewsConfig({
targetDir: resolve(import.meta.dirname, "webext"),
stagingDir: resolve(import.meta.dirname, "dist-webext"),
tamaguiConfig: resolve(import.meta.dirname, "config/tamagui.config.ts"),
packageInfo: packageJson,
// MANDATORY for extension builds — see "one must be aliased" below.
aliases: [{ find: /^one$/, replacement: "@multiplatform.one/router/seam" }],
}),
);
createWebextBackgroundConfig (同步)和 createWebextContentConfig
(async)对worker和content-script构建采用相同的选项;
runWebextPrepare({ targetDir, stagingDir, getManifest, isDev, port, watch }) 阶段清单、静态资产和开发HMR脚手架。
所需的依赖(真正的消费者契约)
声明的对等节点-将它们安装在这个插件旁边:
| 包 | 为什么 |
|---|---|
vite > = 5 | 构建工具本身 |
@vitejs/plugin-react | 视图构建(反应快速刷新+ jsx)。在工厂调用时惰性导入 |
@tamagui/vite-plugin | 视图+内容构建(静态提取)。Lazy-imported |
除了声明的对等体之外,真正的应用构建还需要:
@tamagui/web作为应用的直接依赖。 的Tamagui 静态提取器捆绑你的tamaguiConfig来<cwd>/.tamagui/tamagui.config.{cjs,mjs}并要求它从那里, 与@tamagui/web左外部。在pnpm的默认隔离node_modules传递包不能从你的应用中解析, 所以提取器失败,提示“错误绑定tamagui配置:不能。 找到包‘@tamagui/web’…" -然后(上游)默默地吞下它 发布一个非优化的运行时风格的构建。这个插件改变了这一点 在生产构建中变成一个硬错误;通过添加@tamagui/web到你的应用程序dependencies.react-i18next+i18next,如果您呈现i18n-using目录 组件。@multiplatform.one/components翻译的内置 copy (Alert, Toast, Carousel, ConfirmDialog, Pagination, views/, 布局/,…)通过可选的react-i18next同行。从不使用的应用 渲染这些组件可能会忽略包和树摇 组件;渲染它们的应用程序会得到一个命名的运行时错误 告诉你安装react-i18next和i18next.
one 必须别名到路由器接缝
扩展页不能捆绑真实的 one 运行时:拖进
@react-navigation/core (以及仅服务器模块),构建失败。
这是强制性的,而不是风格上的别名 one 到堆栈导航
每个webext配置中呈现共享特性代码的Seam:
aliases: [{ find: /^one$/, replacement: "@multiplatform.one/router/seam" }],
接缝(@multiplatform.one/router/seam)实现One的路由器API
在DOM页面上,所以共享 features/ 针对路由器编写的代码
在扩展内工作不变。
同理, one的客户端代码导入 ./vite/one-server-only.mjs
(节点只);工厂重定向 one-server-only 到某人家里去
发布的浏览器/本机无操作。重定向解析已安装的
one 包通过节点解析(然后构建cwd)
workspaceRoot);当 one 根本没有安装重定向
跳过并显示一行警告,然后继续进行正常的解析。
workspaceRoot 语义
workspaceRoot 默认为git顶层(git rev-parse --show-toplevel)。它有两种用法:
- 工作区源别名。 在多平台内部。一个monorepo,
每一个
public/*包(及其子路径导出)别名为其 TypeScript的源代码永远不会消耗旧的dist工件。 没有回购public/在词根下,是混叠 下面,@multiplatform.one/*解决了从node_modules就像 任何其他包-当发生这种情况时,工厂记录一行:no public/ under <root> — resolving @multiplatform.one/* from node_modules. - 只有一个服务器的重定向 回到解决
one从workspaceRoot当无法从生成命令中解析时。
通过 workspaceRoot 当你的应用程序从一个目录构建时
它的git顶层不是依赖根(例如一个嵌套的repo)。