一个超棒的基于 React & TypeScript & webpack 的 chrome 扩展开发模板
manifest v3 版本 👉 manifest-v3
- 🔥 支持修改
content scripts代码自动重载扩展和刷新注入了content scripts的页面,再也不用修改了content scripts后手动刷新扩展和页面了。 - 🌴
options和popup页面支持react hot reload&react devtools,充分享受现代前端工程化的便捷,让你从开发SPA无缝切换到 chrome 扩展开发。 - 🛡️ 整个模板包括
webpack配置都是用TypeScript编写的,使用TypeScript配置webpack减少查阅文档和手残的概率。 - 💄 支持 css/less/sass,使用
mini-css-extract-plugin将 CSS 分离成 content CSS Script。 - ⚒️ 集成了社区很多的优秀的
webpack,eslint和babel插件,优化开发,构建和打包分析体验,还配置了husky,format-imports,stylelint,travis和audit-ci构建工具。 - 🌈 默认集成了
jquery,lodash,antd等常用工具库,并对它们的打包��行了优化
# 克隆这个模板
git clone https://github.com/tjx666/awesome-chrome-extension-boilerplate.git
# 安装依赖,推荐使用 pnpm
pnpm🔔 请确保你对 chrome 扩展开发已经有基本的了解,入门推荐:Chrome 插件(扩展)开发全攻略。如果你对项目的配置有疑问。
使用 src/manifest.ts 编写 manifest.json,它其实是一个 node 脚本,因此你可以使用 server 下面的所有模块,可以使用环境变量处理不同开发环境的配置。
注意:任何注入了 content scripts 的页面也必须被注入 js/all.js 和 css/all.css ,为了实现这一点,它俩的 matches 应该是其它所有 content scripts 的 matches 的父集。
示例的配置是:
"content_scripts": [
// 所有注入了 content scripts 的页面都注入了 js/all.js 和 css/all.css
{
"matches": ["https://github.com/*"],
"css": ["css/all.css"],
"js": ["js/all.js"]
},
// 注入到 github pull requests 页面
{
"matches": ["https://github.com/pulls"],
"css": ["css/pulls.css"],
"js": ["js/pulls.js"]
}
]public 下的文件会被打包到扩展的根目录,manifest 中用到的图标等资源可以直接放到 public 文件夹下面。模板在 public/icons 放了一些默认的图标,因此可以在 manifest 中这样引用图标:
// manifest.dev.json
{
"icons": {
"16": "icons/extension-icon-x16.png",
"32": "icons/extension-icon-x32.png",
"48": "icons/extension-icon-x48.png",
"128": "icons/extension-icon-x128.png"
}
}yarn start无论是开发环境还是生产环境都会在项目根目录生成 extension 文件夹,chrome 访问 chrome://extensions/ 也就是扩展管理页面,点击右上角的按钮开启开发者模式,选择加载已解压的扩展程序,再选择刚刚生成的 extension 文件夹即可加载扩展。
由于 chrome 的限制,官方的 chrome 扩展 react devtools 并不能审查 chrome-extension:// 协议的页面如 options,popup 页面。所以需要使用独立的 react devtools,使用下面的命令启动 devServer 的同时打开独立的 devtools 窗口:
npm run devtools你可以通过 open 参数配置在 webpack 初次编译成功打开某个 URL:
"scripts": {
"start": "cross-env-shell NODE_ENV=development ts-node --files -P ./server/tsconfig.json ./server --open=https://xxx.xxx.com",
},模板默认的代码实现的功能是修改 github 导航栏的颜色,模板使用了 normalize.css 和一些自定义样式对 CSS 进行样式重置。
如果你想开发 background 脚本,你可以在 src/background 文件夹编写你的代码。src/background/index.ts 是 background 脚本的入口,也是 webpack 的一个 entry,其它像 options 和 popup 页面也类似。你可以查看 webpack 的 entry 配置: src/server/utils/entry.ts 了解更多实现细节。
它俩的 webpack entry 分别是 src/options/index.tsx 和 src/popup/index.tsx。这两个页面很相似,都只是一个普通的 web 页面,因此你可以像开发一个 react SPA 一样开发它们。
这个模板使用了 react 的最新版本,因此你可以使用 react hooks 去开发函数组件,react hooks 的 eslint 规则也集成了。
模板使用 React Fast Refresh 支持 react 的热更新。
这个模板会扫描 src/contents 文件夹,将所有子文件夹中的 index.tsx 或 index.ts 作为 webpack entry。
content scripts 都放在 src/contents 目录下。默认有个 all.ts,也是个 webpack entry,它不能被删除,因为这个 webpack entry 被用于注入实现 chrome 扩展自动刷新功能的补丁。
���个 🌰:
当你要给 URL 是 https://www.example.com/discuss 页面开发 content script,你需要做下面两步:
-
添加
content scripts和页面 URL 之间的映射到manifest.dev.json和manifest.prod.json:{ "content_scripts": [ { "matches": ["https://www.example.com/discuss*"], "css": ["css/discuss.css"], "js": ["js/discuss.js"] } ] } -
创建一个和上面
content script路径对应的文件夹src/contents/discuss。src/discuss/index.tsx或者src/discuss/index.ts将会被视为一个 webpack entry。webpack会通过这个entry最终产出js/discuss.js这个chunk。mini-css-extract-plugin会将所有被discuss/index.ts导入的样式文件合并再分离到extension/css/discuss.css,这也是为什么上面的manifest中 content CSS script 可以使用css/discuss.css的原因
你可以在 server/configs/proxy.ts 中配置 dev server 的代理,所有向 dev server 发送的请求都会根据你配置的规则被代理转发,修改配置后需要重启 dev server 才会生效,更多细节请查看使用的中间件 http-proxy-middleware。
const proxyTable: ProxyTable = {
// 如果 devServer 启动地址是 http://127.0.0.1:3600
// 那么请求 http://127.0.0.1:3600/path_to_be_proxy 将会被 dev server 转发到 http://target.domain.com/path_to_be_proxy
'/path_to_be_proxy': { target: 'http://target.domain.com', changeOrigin: true },
};构建生产级别的包直接运行:
pnpm build如果你想分析打包情况:
pnpm build-analyzesrc/all 和 src/background 下的文件包含了实现修改 content script 自动重载扩展和刷新注入了 content script 页面的功能的代码。除非你不开发 content scripts,否则,不能删除它。
核心原理:使用 webpack 构建 chrome 扩展的热更新问题
欢迎贡献 PRs。

