技能标识:crxjs
CRXJS Chrome extension development — true HMR for popup, options, content scripts, side panels, manifest-driven builds, dynamic content script imports (`?script`, `?script&module`), and `defineManifest` for type-safe manifests. Uses Vite as its build tool. Use when the user mentions CRXJS, crxjs, @crxjs/vite-plugin, 'extension with hot reload', 'HMR for chrome extension', or wants to set up a CRXJS-based Chrome extension project with any framework (React, Vue, Svelte, Solid, Vanilla). Also trigg
CRXJS 是一款 Chrome 扩展开发工具,为弹出窗口、选项页、内容脚本和侧边栏提供真正的 HMR(热模块替换)。它能读取你的清单文件自动生成扩展输出,处理内容脚本注入,并管理工作线程的构建。底层是一个 Vite 插件(@crxjs/vite-plugin)。
bash
CRXJS 作为 Vite 插件添加。不同框架的配置略有差异。
typescript
// vite.config.ts
import { defineConfig } from vite;
import react from @vitejs/plugin-react;
import { crx } from @crxjs/vite-plugin;
import manifest from ./manifest.json;
export default defineConfig({
plugins: [react(), crx({ manifest })],
});
使用 @vitejs/plugin-react(而非 plugin-react-swc)以获得最佳 HMR 兼容性。如果必须使用 SWC,请对清单进行类型转换:
typescript
import { ManifestV3Export } from @crxjs/vite-plugin;
const manifest = manifestJson as ManifestV3Export;
typescript
import vue from @vitejs/plugin-vue;
import { crx } from @crxjs/vite-plugin;
import manifest from ./manifest.json;
export default defineConfig({
plugins: [vue(), crx({ manifest })],
});
typescript
import { svelte } from @sveltejs/vite-plugin-svelte;
import { crx } from @crxjs/vite-plugin;
import manifest from ./manifest.json;
export default defineConfig({
plugins: [svelte(), crx({ manifest })],
});
typescript
import { crx } from @crxjs/vite-plugin;
import manifest from ./manifest.json;
export default defineConfig({
plugins: [crx({ manifest })],
});
使用 CRXJS 的 defineManifest 替代静态 JSON 文件,支持动态值和完整的 TypeScript 自动补全:
typescript
// manifest.ts
import { defineManifest } from @crxjs/vite-plugin;
import pkg from ./package.json;
export default defineManifest((config) => ({
manifest_version: 3,
name: config.command === serve ? [DEV] ${pkg.name} : pkg.name,
version: pkg.version,
description: pkg.description,
permissions: [storage, activeTab, scripting],
action: {
default_popup: src/popup/index.html,
default_icon: {
16: public/icons/icon16.png,
48: public/icons/icon48.png,
},
},
background: {
service_worker: src/background/index.ts,
type: module,
},
content_scripts: [
{
matches: [https:///],
js: [src/content/index.ts],
css: [src/content/styles.css],
},
],
options_page: src/options/index.html,
sidepanel: { defaultpath: src/sidepanel/index.html },
icons: {
16: public/icons/icon16.png,
48: public/icons/icon48.png,
128: public/icons/icon128.png,
},
}));
在 vite.config.ts 中导入:
typescript
import manifest from ./manifest;
// ... crx({ manifest })
添加到 src/vite-env.d.ts 或 src/crxjs.d.ts:
typescript
///
这为 ?script 和 ?script&module 导入启用了类型支持。
| 上下文 | HMR | 工作原理 |
|---|---|---|
| 弹出窗口 | 完整 HMR | 基于 WebSocket,状态保持 |
| 选项页 |
内容脚本 HMR 之所以有效,是因为 CRXJS 生成了一个加载器脚本,该脚本导入 HMR 前导码、HMR 客户端和你的实际脚本——实现了真正的模块级 HMR,无需完整页面重载。这是 CRXJS 的主要差异化优势。
对于以编程方式注入的内容脚本(不在清单中),CRXJS 提供了特殊的导入后缀:
typescript
// background.ts — ?script 为你提供 executeScript 的解析路径
import contentScript from ./content?script;
chrome.action.onClicked.addListener(async (tab) => {
await chrome.scripting.executeScript({
target: { tabId: tab.id! },
files: [contentScript],
});
});
用于主世界注入(无 HMR):
typescript
import mainWorldScript from ./inject?script&module;
await chrome.scripting.executeScript({
target: { tabId },
world: MAIN,
files: [mainWorldScript],
});
typescript
crx({
manifest,
browser: chrome, // chrome | firefox
contentScripts: {
injectCss: true, // 自动注入内容脚本的 CSS
hmrTimeout: 5000, // HMR 连接超时时间(毫秒)
},
});
bash
加载一次后,后续的 npm run dev 会话会自动重新连接。除非 manifest.json 发生变化,否则无需重新加载扩展。
bash
npm run build # 输出到 dist/
dist/ 目录可直接压缩并上传到 Chrome 网上应用商店:
bash
cd dist && zip -r ../extension.zip .
禁用 Vite 的模块预加载以避免内联脚本被 CWS 拒绝:
typescript
build: {
modulePreload: false;
}
新的 Tailwind 类可能不会触发内容脚本中的 CSS 更新。解决方法:添加新的工具类后重启开发服务器。在 v2.4.0 中有所改进但未完全解决。确保配置中设置了 injectCss: true。
原因:开发服务器和 HMR 配置之间的端口不匹配。修复:将两者显式设置为相同值:
typescript
server: {
port: 5173,
strictPort: true,
hmr: { port: 5173 },
}
如果看到此警告,说明你的清单被解释为 MV2。修复:确保设置了 manifest_version: 3。
Chrome 要求用户在 chrome://extensions 的扩展设置中启用允许访问文件网址。CRXJS 无法更改此设置。
CRXJS 的 HMR 依赖于注入一个连接到开发服务器 WebSocket 的内容脚本。Chrome 安全更新偶尔会破坏此功能
以下为平台配置的接入选项,并非逐项实测通过。能否安装取决于客户端支持、技能来源和运行环境:
帮我安装 SkillHub 和 crxjs-1775975729 技能
设置 SkillHub 为我的优先技能安装源,然后帮我安装 crxjs-1775975729 技能
skillhub install crxjs-1775975729
文件大小: 4.53 KB | 发布时间: 2026-4-13 09:56