Files
2026-05-09 14:55:30 +08:00

6.1 KiB
Raw Permalink Blame History

inclusion
inclusion
manual

Plasmo 框架技术说明

1️⃣ 框架定位

Plasmo 是一个 Chrome 扩展开发框架,核心价值是:让你用写 React 项目的方式来写 Chrome 插件

它帮你处理了:

  • manifest.json 自动生成(不用手写)
  • TypeScript/React 编译打包(内置,不用配 webpack)
  • Content Script 样式隔离(Shadow DOM
  • 开发时热更新(改代码自动刷新扩展)

2️⃣ 约定式文件结构

src/
├── popup.tsx              # 点击插件图标弹出的小窗口
├── options.tsx            # 插件设置页(右键图标→选项)
├── newtab.tsx             # 覆盖浏览器新标签页
├── sidepanel.tsx          # 浏览器侧边栏面板
│
├── background/
│   └── index.ts           # 后台 Service Worker,监听事件、做中转
│
├── contents/
│   └── xxx.tsx / xxx.ts   # 注入到目标网页里的脚本(可以有多个)
│
├── components/            # 自己的 UI 组件(非框架约定)
│   └── Button.tsx
│
└── lib/                   # 工具函数(非框架约定)
    └── api.ts

核心规则:文件放对位置就自动生效,不需要任何注册或配置。

文件 有就生效,没有就没这功能
popup.tsx 有 → 点图标弹窗;没有 → 点图标触发 background 事件
options.tsx 有 → 有设置页;没有 → 没设置页
newtab.tsx 有 → 新标签页被接管;没有 → 正常新标签页
sidepanel.tsx 有 → 有浏览器侧边栏;没有 → 没有
background/index.ts 有 → 有后台服务;没有 → 没后台逻辑
contents/任意名.tsx 有几个就注入几个脚本到网页里

3️⃣ 文件后缀规则

跟目录无关,跟内容有关:

后缀 能写 HTML 标签(JSX)吗 用途
.ts 不能 纯逻辑、工具函数、类型定义
.tsx 任何需要写 <div><button> 等标签的文件

简单记:有尖括号标签的用 .tsx,没有的用 .ts

4️⃣ TSX vs Vue 文件对比

.vue .tsx
框架 Vue React
结构 template / script / style 三段式 全部写在一个函数里
HTML 写法 写在 <template> 里,正常 HTML 写在 JS 的 return 里,叫 JSX
变量绑定 {{ msg }} 双花括号 {msg} 单花括号
思路 HTML 为主,往里面插逻辑 JS 为主,在逻辑里写 HTML

一句话:.vue 是"HTML 里面嵌 JS".tsx 是"JS 里面嵌 HTML"。

5️⃣ Background Service Worker

执行时机

  • 没有固定执行时机,完全由事件驱动
  • 有事件触发时唤醒,没事干 30 秒左右自动休眠
  • 全局只有一个实例

能做什么

  • 监听插件图标点击
  • 接收/转发消息(content script ↔ background
  • 调用 chrome.cookieschrome.tabs 等完整 Chrome API
  • 定时任务(必须用 chrome.alarms,不能用 setInterval

不能做什么

  • 不能访问 DOM(没有页面)
  • 不能写持续运行的逻辑(会被休眠打断)

代码结构

里面基本全是事件监听器注册:

chrome.action.onClicked.addListener(...)    // 图标被点击
chrome.runtime.onMessage.addListener(...)   // 收到消息
chrome.runtime.onInstalled.addListener(...) // 安装/更新

6️⃣ Content Script

执行时机

  • 页面加载时自动注入(匹配 matches 规则的 URL
  • 默认在 document_idle 时机注入(DOM 解析完成后)
  • 每个匹配的标签页各一个独立实例(内存不共享)

能做什么

  • 读写目标网页的 DOM
  • 往网页里注入 UI 组件(通过 Shadow DOM 隔离样式)
  • 通过 chrome.runtime.sendMessage 与 background 通信
  • 调用部分 Chrome APIstorage、runtime 等)

不能做什么

  • 不能直接调用 chrome.cookies(需要通过 background 中转)
  • 不能访问其他标签页

两种用法

用法 文件后缀 例子
往网页里塞 UI .tsx 侧边栏面板、悬浮按钮
只跑逻辑不画界面 .ts 读取页面数据、监听事件

7️⃣ Content Script UIShadow DOM

当 content script 需要往网页里渲染 UI 时,Plasmo 自动用 Shadow DOM 包裹:

目标网页
├── 网页自己的 HTML、CSS
└── Shadow DOM(隔离墙)
    └── 你的 React 组件 + 你的样式
  • 网页的 CSS 影响不到你的组件
  • 你的 CSS 也不会搞乱网页
  • 通过 getStyle 导出函数将样式注入 Shadow DOM 内部

8️⃣ Manifest 配置

Plasmo 不需要手写 manifest.json,通过 package.jsonmanifest 字段声明权限:

{
  "manifest": {
    "permissions": ["activeTab", "storage", "tabs", "cookies"],
    "host_permissions": ["<all_urls>"],
    "action": {}
  }
}

框架会自动合并源码中的信息(如 content script 的 matches 配置)生成最终的 manifest.json。

9️⃣ 开发工作流

# 安装依赖
npm install

# 开发模式(热更新)
npm run dev
# 产物在 build/chrome-mv3-dev

# 生产构建
npm run build
# 产物在 build/chrome-mv3-prod

# 打包 zip(用于上架)
npm run package

加载到 Chrome

  1. 打开 chrome://extensions/
  2. 右上角开启「开发者模式」
  3. 点击「加载已解压的扩展程序」
  4. 选择 build/chrome-mv3-dev 目录

查看日志

代码位置 在哪看日志
Background 扩展管理页 → 点击 "Service Worker" 链接 → 打开 DevTools
Content Script 目标网页 → F12 → Console
Popup / SidePanel 右键插件图标 → 审查弹出内容

🔟 环境变量

Plasmo 支持 .env 文件,变量必须以 PLASMO_PUBLIC_ 前缀命名才能在代码中访问:

PLASMO_PUBLIC_API_URL=http://localhost:8080/api

代码中通过 process.env.PLASMO_PUBLIC_API_URL 读取。

本项目未使用此机制,而是通过 src/config.ts 手动管理多环境配置。