如何使用CRXJS Vite Plugin开发从零开始开发一款浏览器插件

2 阅读7分钟

下面是从零开始使用 CRXJS Vite Plugin 开发浏览器插件的详细步骤。CRXJS 的核心优势在于它极大地简化了配置和开发流程,特别是 Manifest V3 的处理和热模块替换 (HMR)。

我们将以创建一个简单的 React + TypeScript 插件为例,该插件包含一个弹出窗口 (Popup) 和一个内容脚本 (Content Script)。

前提条件:

  1. Node.js 和 npm/yarn/pnpm: 确保你的系统安装了 Node.js (推荐 LTS 版本) 和对应的包管理器。
  2. 代码编辑器: 如 VS Code。
  3. 目标浏览器: Google Chrome 或 Microsoft Edge (或其他支持 Manifest V3 的 Chromium 浏览器)。
  4. 基础 Web 开发知识: 了解 HTML, CSS, JavaScript (以及你选择的框架,如 React/TypeScript)。

步骤 1: 创建项目

CRXJS 推荐使用官方的 Vite starter 模板来创建项目。这能确保你获得一个已经配置好 CRXJS 的基础结构。

打开你的终端,运行以下命令 (将 my-crxjs-plugin 替换为你的项目名称):

# 使用 npm
npm create vite@latest my-crxjs-plugin --template react-ts

# 或者使用 yarn
# yarn create vite my-crxjs-plugin --template react-ts

# 或者使用 pnpm
# pnpm create vite my-crxjs-plugin --template react-ts

进入项目目录:

cd my-crxjs-plugin

步骤 2: 安装 CRXJS 和依赖

现在,安装 CRXJS Vite Plugin 和项目的其他依赖:

# 使用 npm
npm install @crxjs/vite-plugin@latest --save-dev
npm install

# 或者使用 yarn
# yarn add @crxjs/vite-plugin@latest --dev
# yarn install

# 或者使用 pnpm
# pnpm add @crxjs/vite-plugin@latest --save-dev
# pnpm install

步骤 3: 配置 Vite (vite.config.ts)

打开项目根目录下的 vite.config.ts 文件。你需要导入 CRXJS 插件并将其添加到 Vite 配置中。同时,你需要导入你的基础 manifest.json 文件 (我们稍后创建它)。

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { crx } from '@crxjs/vite-plugin'
// 导入你的 manifest 文件 (可以是 .json 或 .ts/.js)
// 注意:如果你的 manifest 是 .json 文件,需要添加 assert { type: 'json' }
// import manifest from './manifest.json' assert { type: 'json' }
// 或者,如果使用 .ts/.js (更灵活):
import manifest from './manifest.config' // 无需 .ts 后缀

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    // 在这里调用 crx 插件,传入 manifest
    crx({ manifest }),
  ],
})

步骤 4: 创建基础 Manifest 文件 (manifest.config.tsmanifest.json)

CRXJS 的一个强大之处在于你只需要提供一个基础 Manifest。CRXJS 会在构建或开发时自动为你添加必要的字段(例如内容脚本的入口、HMR 相关配置、web 可访问资源等)。

推荐使用 .ts.js 文件来定义 Manifest,这样可以添加注释、使用变量等,更加灵活。

在项目根目录创建 manifest.config.ts 文件:

import { defineManifest } from '@crxjs/vite-plugin'
import packageJson from './package.json' // 可以读取 package.json 的信息

// 将版本号的小数点转换为 Chrome 扩展要求的整数版本
const version = packageJson.version.replace(/[.-]/g, '')
// 注意:Chrome 扩展版本号最多 4 段,每段不能超过 65535
// 如果你的 package.json 版本是 x.y.z,这里简化为 xyz0
const chromeVersion = `${version}0`

export default defineManifest({
  manifest_version: 3,
  name: packageJson.name || 'My CRXJS Extension', // 从 package.json 读取名称
  description: packageJson.description || 'A basic extension built with CRXJS',
  version: chromeVersion, // 使用处理后的版本号
  version_name: packageJson.version, // 显示原始版本号

  // -------- 常规配置 --------
  icons: {
    '16': 'src/assets/icons/icon16.png', // 示例路径,确保图标存在
    '48': 'src/assets/icons/icon48.png',
    '128': 'src/assets/icons/icon128.png',
  },

  // -------- 定义插件的主要交互点 --------
  action: {
    // default_popup: 'index.html', // 指向你的 Popup HTML 入口
    // 通常,Vite 项目的入口是根目录的 index.html,CRXJS 会处理
    default_icon: { // 图标也需要在这里指定
      '16': 'src/assets/icons/icon16.png',
      '48': 'src/assets/icons/icon48.png',
    },
  },

  // -------- 后台脚本 (Service Worker) --------
  background: {
    service_worker: 'src/background/index.ts', // 指向你的后台脚本入口
    type: 'module', // 必须是 module 类型
  },

  // -------- 内容脚本 --------
  // CRXJS 会自动检测 src/content/ 目录下的脚本,并添加到这里
  // 你也可以在这里手动定义更复杂的匹配规则
  // content_scripts: [
  //   {
  //     matches: ['<all_urls>'],
  //     js: ['src/content/index.tsx'], // 指向内容脚本入口
  //   },
  // ],

  // -------- 网页可访问资源 --------
  // CRXJS 会自动处理脚本注入所需的资源,通常无需手动配置
  // web_accessible_resources: [
  //   {
  //     resources: ['src/assets/*'], // 如果需要在页面上直接访问资源
  //     matches: ['<all_urls>'],
  //   },
  // ],

  // -------- 权限声明 --------
  permissions: [
    'storage', // 示例:允许使用 chrome.storage
    'activeTab', // 示例:允许临时访问活动标签页
    // "tabs", // 按需添加
    // "scripting", // 如果需要通过 API 注入脚本或 CSS
  ],

  // -------- 主机权限 (Manifest V3 必须) --------
  host_permissions: [
    // '<all_urls>', // 谨慎使用,只在必要时申请
    '*://*.google.com/*', // 示例:允许访问 Google 域名
  ],

  // -------- 选项页面 --------
  // options_page: 'options.html', // 如果有选项页面,指向其 HTML
})

注意:

  • 你需要创建对应的图标文件 (src/assets/icons/...)。
  • CRXJS 默认会自动查找 src/content/index.{js,ts,jsx,tsx} 作为内容脚本入口,src/background/index.{js,ts} 作为后台脚本入口,index.html 作为 Popup 或 Options 页面的入口。如果你的文件结构不同,需要在 Manifest 或 CRXJS 配置中指定。
  • 仔细配置 permissionshost_permissions,遵循最小权限原则。

步骤 5: 开发插件组件

  1. Popup:

    • Vite 模板通常使用根目录的 index.htmlsrc/main.tsx 作为入口。这就是你的 Popup 页面。
    • 像开发普通 React 应用一样修改 src/App.tsx 和其他组件。
    • 你可以在 Popup 的 JS/TS 文件中使用 chrome.* API (前提是已在 Manifest 申请权限),例如 chrome.storage.local.set(...)
  2. Content Script:

    • src/ 下创建一个 content 目录 (如果不存在)。
    • src/content/ 下创建 index.tsindex.tsx
    • CRXJS 会自动检测这个文件,并将其配置为注入到 manifest.jsoncontent_scriptsmatches 字段指定的所有页面(默认可能是 <all_urls>,可以在 Manifest 中修改)。
    • 在这个文件里,你可以编写操作页面 DOM 的代码。
    • 注入 CSS: 如果你想为内容脚本添加样式,只需在 index.ts(x) 中导入 CSS 文件即可:
      // src/content/index.tsx
      import React from 'react';
      import ReactDOM from 'react-dom/client';
      import App from './App';
      import './content.css'; // 导入 CSS 文件
      
      console.log('Content script loaded!');
      
      const root = document.createElement('div');
      root.id = 'crxjs-react-root';
      document.body.append(root);
      
      ReactDOM.createRoot(root).render(
        <React.StrictMode>
          <App />
        </React.StrictMode>
      );
      
      CRXJS 会负责将这个 CSS 文件正确注入到页面。
    • HMR 支持: 这是 CRXJS 的亮点!当你修改内容脚本 (JS/TS 或 CSS) 时,CRXJS 会尝试热更新,你通常不需要手动刷新扩展或页面就能看到效果。
  3. Background Script (Service Worker):

    • src/ 下创建一个 background 目录 (如果不存在)。
    • src/background/ 下创建 index.ts
    • CRXJS 会自动检测这个文件 并将其配置为 Service Worker。
    • 在这里编写监听浏览器事件的代码 (如 chrome.runtime.onInstalled, chrome.tabs.onUpdated, 消息监听等)。
    • 注意:Service Worker 是事件驱动的,会在不活动时终止,不要依赖全局变量来保持状态(应使用 chrome.storage)。

步骤 6: 运行和调试

  1. 启动开发服务器:

    npm run dev
    # or yarn dev / pnpm dev
    ```Vite 和 CRXJS 会启动开发服务器,并构建一个包含 HMR 功能的**未打包**的扩展到 `dist` 目录。
    
    
  2. 加载插件到浏览器:

    • 打开 Chrome/Edge。
    • 地址栏输入 chrome://extensionsedge://extensions
    • 打开右上角的 “开发者模式” 开关。
    • 点击 “加载已解压的扩展程序” 按钮。
    • 选择项目的 dist 文件夹 (而不是项目根目录!CRXJS 的开发模式是将构建结果输出到 dist)。
    • 你的插件图标应该会出现在工具栏。
  3. 调试:

    • Popup: 右键点击工具栏图标,选择“检查弹出式窗口”。
    • Content Script: 打开一个匹配 matches 规则的网页,按 F12 打开开发者工具,在 “Sources” (源代码) -> “Content scripts” 标签页下找到你的脚本,或者直接在 Console 中查看 console.log 输出。
    • Background Script:chrome://extensions 页面,找到你的插件,点击 “服务工作进程” (Service Worker) 链接。
    • HMR: 尝试修改 Popup、Content Script 或 Background Script 的代码并保存。观察浏览器控制台或插件行为,很多时候更改会立即生效,无需手动刷新扩展(尤其是 Content Script)。

步骤 7: 构建生产版本

当你完成开发后,运行构建命令:

npm run build
# or yarn build / pnpm build

这会在 dist 目录中生成一个优化过的、不含 HMR 代码的生产版本扩展。你可以将 dist 目录的内容打包成 .zip 文件提交到 Chrome Web Store 或其他应用商店。

总结 CRXJS 的优势:

  • 简化的 Manifest: 只需编写基础 Manifest,CRXJS 自动处理构建细节。
  • 优秀的 HMR: 大幅提升开发体验,特别是内容脚本的 HMR。
  • 自动资源处理: 简化了 CSS 注入和 web 可访问资源的管理。
  • 框架集成: 与 Vite 生态和各种前端框架无缝协作。

通过以上步骤,你应该能够使用 CRXJS Vite Plugin 顺利地从零开始开发你的浏览器插件了。记得查阅 CRXJS 的官方文档以获取更详细的配置选项和高级用法。


文章告一段落。如果你意犹未尽,渴望持续提升技术实力、拓宽视野,欢迎关注同名微信公众号“码觉客”。我们致力于分享高质量的技术干货、实战经验和前沿资讯,助你在技术的道路上走得更远。即刻搜索关注,解锁更多精彩!