Skip to Content
LaunchExt | Chrome 扩展开发平台 (Next.js + Plasmo) 🚀 Read more → 
文档迁移到 Plasmo

迁移到 Plasmo Framework

Plasmo 浏览器扩展框架通过其声明式开发方法,极大地简化了浏览器扩展的构建过程。它消除了繁琐的样板代码,提供了基于文件的配置系统,让开发变得直观、高效,并且支持灵活退出

在本指南中,我们将引导您完成从现有扩展项目到 Plasmo 的完整迁移过程,并重点介绍需要关注的关键变更点。

安装 Plasmo CLI

Plasmo 框架的核心驱动是 Plasmo CLI。这是一个专为浏览器扩展开发定制的 Node.js 包,集成了编译器、打包器、开发服务器和打包工具:

pnpm install plasmo

启动开发服务器:plasmo dev 构建扩展:plasmo build 打包扩展:plasmo package

manifest.json 配置

Plasmo 将 manifest.json 的功能整合到 package.json 中,并对核心属性进行了抽象化处理:

Manifest 字段Plasmo 抽象方式
icons自动从 assets 目录中的 icon.png 生成
action, browser_actions通过 popup.tsx 文件配置
options_ui通过 options.tsx 文件配置
content_scripts通过 contents/*.{ts,tsx}, content.ts, content.tsx 配置
background通过 background.ts 文件配置
sandbox通过 sandbox.tsx沙盒页面 配置
manifest_version通过 --target 构建标志设置,默认为 3
version使用 package.json 中的 version 字段设置
name使用 package.json 中的 displayName 字段设置
description使用 package.json 中的 description 字段设置
author使用 package.json 中的 author 字段设置
homepage_url使用 package.json 中的 homepage 字段设置

Plasmo 集中管理 package.jsonmanifest.json 之间的通用元数据,并自动解析所有静态文件引用(如操作、后台、内容脚本等)。

这使您能够专注于重要的元数据配置,例如名称、描述、OAuth、declarative_net_request 等。

此外,这种设计让框架能够提供更强大的功能,包括:

弹出窗口、选项页和新标签页

Plasmo 消除了手动挂载 React/Svelte/Vue 组件的需求。

在传统的非 Plasmo 扩展项目中,挂载 React 组件需要创建 HTML 模板和相关的 JavaScript 代码:

popup.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Popup</title> </head> <body> <div id="root"></div> <script src="popup.js"></script> </body> </html>
popup.jsx
import { createRoot } from "react" import Popup from "./core/popup" const root = document.getElementById("root") createRoot(root).render(<Popup />)

如果需要添加 TypeScript、LESS 或 SCSS 支持,还需要配置 Webpack、Parcel 或 ESBuild,以及额外的插件和加载器。

使用 Plasmo 框架,整个过程变得极其简单。只需在源代码目录中添加 popup.tsxoptions.tsx 文件,并导出一个默认的 React 组件:

popup.tsx
import Popup from "./core/popup" export default Popup

Plasmo 会自动处理剩余的所有工作。

框架内置支持 CSS、SCSS、LESS、CSS 模块和 PostCSS 插件。例如,要使用 SCSS,只需在 React 组件中导入 SCSS 文件:

popup.tsx
import Popup from "./core/popup" import "./popup.scss" export default Popup

您可以使用相同的方式为选项页、新标签页、沙盒页面和任何其他自定义页面挂载 React 组件。

自定义页面

在传统扩展项目中,创建自定义页面需要额外的 HTML 模板和 JavaScript 代码:

tabs/custom.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Custom Page</title> </head> <body> <div id="root"></div> <script src="./custom.js"></script> </body> </html>
tabs/custom.js
import { createRoot } from "react" import CustomPage from "./core/custom-page" const root = document.getElementById("root") createRoot(CustomPage).render(<PopupApp />)

使用 Plasmo,您可以通过内置的标签页功能轻松创建自定义页面。在源代码目录中添加 tabs 文件夹,并在其中使用 .tsx 文件创建自定义页面:

tabs/custom.tsx
import Hello from "./core/hello" export default Hello

该页面将在 chrome-extension://<extension-id>/tabs/custom.html 地址下可用。

内容脚本

在传统扩展项目中,您需要在 manifest.json 文件中指定内容脚本,并用 JavaScript 编写它们:

manifest.json
{ "content_scripts": [ { "matches": ["https://*/*", "http://*/*"], "all_frames": true, "css": ["content.css"], "run_at": "document_start" } ] }
content.js
console.log("Hello from content script!")

使用 Plasmo,您可以在名为 content.ts 的文件中指定内容脚本及其配置,或者在 contents 目录中组织多个脚本。

content.ts 文件的内容如下:

content.ts
import type { PlasmoCSConfig } from "plasmo" export const config: PlasmoCSConfig = { matches: ["https://*/*", "http://*/*"], all_frames: true, css: ["~content.css"] } console.log("Hello from content script!")

不再需要在 manifest.jsoncontent.js 文件之间来回切换。额外的优势是配置是完全类型化的,可以从您的 IDE 获得有价值的自动完成功能。

要添加多个内容脚本,请创建名为 contents 的目录并重复上述步骤。您可以在此目录中自由命名脚本文件,它们都将作为独立的内容脚本添加,每个脚本都可以有自己的配置。

例如,假设您想添加一个将页面背景颜色改为绿色的内容脚本。您可以在 contents 目录中创建名为 emerald-splash.ts 的文件:

contents/emerald-splash.ts
document.body.style.backgroundColor = "green"

由于内容脚本文件没有导出配置,Plasmo 将使用默认配置:

{ "matches": ["<all_urls>"] }

内容脚本 UI

如果您需要将 React 组件注入到网页中,传统扩展项目通常包含大量样板代码,涉及创建 Shadow DOM、查找正确的挂载元素、使用 MutationObservers 等。

Plasmo 抽象了所有这些复杂性,让您可以专注于构建组件本身。

例如,要将一个简单的按钮 React 组件注入到网页中,只需在 contents 目录中创建名为 press-me.tsx 的文件:

contents/press-me.tsx
export default function PressMeCSUI() { return <button>Press me</button> }

Plasmo 会自动将此组件注入到页面中,并将其挂载到页面的根元素。

如果需要将组件注入到特定元素中,可以通过从文件中导出 getInlineAnchor 函数来实现:

contents/press-me.tsx
import type { PlasmoGetInlineAnchor } from "plasmo" export const getInlineAnchor: PlasmoGetInlineAnchor = async () => document.querySelector("#pricing")

通过返回一个 Element,Plasmo 会将组件挂载到该元素旁边。您可以完全自定义挂载行为、组件的渲染方式等。

此功能称为内容脚本 UI。要深入了解其 API 和工作原理,请查看关于其生命周期的技术文档。

您还可以指定组件相对于目标元素的插入位置:

contents/press-me.tsx
import type { PlasmoGetInlineAnchor } from "plasmo" export const getInlineAnchor: PlasmoGetInlineAnchor = async () => ({ element: document.querySelector("#pricing"), insertPosition: "afterend" })

后台服务工作者

在传统项目中,创建后台服务工作者需要在 manifest.json 文件中指定 background 属性,并用 JavaScript 编写服务工作者代码:

manifest.json
{ "background": { "service_worker": "background.js" } }
background.js
console.log("Hello from BGSW!")

在 Plasmo 中,您通过创建 background.ts 文件来指定后台服务工作者:

background.ts
console.log("Hello from BGSW!")

您可以将任何针对标准服务工作者运行时的模块导入到 background.ts 中。例如,添加 bip39 模块:

background.ts
import { generateMnemonic } from "bip39" console.log( "把握当下,让此刻成为最珍贵的时光。此刻永不再来。" ) console.log(generateMnemonic())

Plasmo 会自动打包 background.ts 文件,并将其作为后台服务工作者添加到 manifest.json 中。

环境变量

如果您当前正在使用环境变量,可以在 Plasmo 中继续使用相同的模式。

Plasmo 框架开箱即用地支持环境变量,无需额外配置。

退出策略

Plasmo 框架的设计理念是移除最常见的配置和样板代码,让开发人员能够在更高的抽象层工作 - 专注于他们选择的 UI 库/框架,如 React、Vue 和 Svelte。这是创建更强大、更美观扩展的有效途径。

退出 Plasmo 就像从 package.json 文件中删除 plasmo 依赖项并将您的组件迁移到自定义设置中一样简单。这是因为 Plasmo 生成的所有胶水代码都在框架编译器和打包器层注入,使您的功能代码极具可移植性。

您也可以根据需要灵活使用 Plasmo。所有 chrome API 都可用,您可以直接在功能代码中使用它们。例如,您可以直接使用 chrome.runtime.messaging API,而不是使用消息传递 API。内容脚本和扩展页面也是如此。

最后更新于