作者:世卍界创意驿站肀 | 来源:互联网 | 2023-05-19 04:09
前言写了个vite插件,用于构建ChromeExtensionMV3我的项目。我的项目已放在github,详情请查看:vite-plugin-crx-mv3如果对您有帮忙,star反对一下,谢谢~性能Chro
前言
写了个vite插件,用于构建Chrome Extension MV3我的项目。我的项目已放在github,详情请查看: vite-plugin-crx-mv3
如果对您有帮忙,star反对一下,谢谢~
性能
- Chrome扩大页面和注入脚本反对应用vue、react等等;
- Content_scripts的css配置项反对.scss或.less文件;js配置项反对.js(x)或.ts(x)文件;
- background.service_worker配置项反对.js或.ts文件;
- 在开发环境,批改content_scripts和background.service_worker之后,content_scripts注入的页面和Chrome扩大程序会主动重载;
应用
装置
# pnpm
pnpm add vite-plugin-crx-mv3 -D
# npm
npm install vite-plugin-crx-mv3 -D
# yarn
yarn add vite-plugin-crx-mv3 -D
vite配置
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' //如果是应用vue开发的,引入相干的插件
import crx from 'vite-plugin-crx-mv3'
export default defineConfig({
plugins: [
vue(),
crx({
manifest: './src/manifest.json'
}),
],
})
demo:https://github.com/Jervis2049…
实现的整体思路
先回顾一下,一个根本的Chrome插件我的项目个别有哪些内容:
目录构造
├─assets //动态资源目录,寄存icon,css等等
├─content.js //content_scripts,注入到页面的脚本
├─background.js //service_worker, 这是个运行在后盾的脚本
├─popup.html //popup弹框
├─menifest.json //清单文件
menifest.json
{
"name": "chrome-extension-demo",
"description": "A Chrome extension demo.",
"version": "1.0.0",
"icons": {
"16": "assets/icons/icon16.png",
"48": "assets/icons/icon48.png",
"128": "assets/icons/icon128.png"
},
"action": {
"default_title": "Hello World",
"default_popup": "popup.html"
},
"content_scripts": [{
"matches": [ "" ],
"js": ["content.js"]
}],
"background": {
"service_worker": "background.js"
},
"manifest_version": 3
}
这其中version
, manifest_version
,name
为必填项。
好了,当初咱们都分明我的项目须要有什么了。这个vite插件就是以manifest.json作为一个入口文件,解析出外面的内容,比方service_worker
、content_scripts
、popup.html
等等的门路。再通过这些失去的内容,利用构建工具打包出咱们想要的最终的文件。因而,配合上这个vite插件,本来只能配置原生js,css后缀的manifest.json反对了配置.ts(x)、.scss、.less这样格局的文件了,因为这些都会在插件外部作解析的。这样,content_scripts也实现了应用vue、react等等这样的技术栈开发了。
例如,配置了tsx文件:
...
"content_scripts": [{
"matches": [""],
"js": ["content.tsx"],
}]
...
打包后是这样。产生的css文件会主动写入到配置:
...
"content_scripts": [{
"matches": [ "" ],
"js": ["content.js"],
"css": ["content.hashxxxx.css"],
}]
...
主动刷新性能
画了一个简略的流程图
先从开始的vite build --watch
说起,为什么开发环境也要build呢?还是得解释一下,防止刚入门的小伙伴不了解。
开发步骤是这样的,首先关上chrome://extensions/
, 右上角勾选“开发者模式”,而后点击“加载已解压的扩大程序”,加载我的项目。
然而,应用构建工具搭建的我的项目,都是初始文件,并没打包,这样是不能加载进去。平时咱们开发其它我的项目的时候,npm run dev
运行后,并不会产生实体文件的,而是在内存里。所以在开发Chrome插件我的项目时就须要build,生成dist目录,再点击“加载已解压的扩大程序”加载这个dist目录。vite还提供了watch这个参数,批改文件后,会从新构建。如果你是用webpack
搭建,达到雷同的成果,须要把devServer.writeToDisk
设置为true,writeToDisk意为写入到磁盘。
到了这步,只管watch到文件批改,会从新打包。然而Chrome插件并不会感知到文件已发生变化。content_scripts和service_worker是不会自动更新的。通常都须要手动到后盾刷新一下。这很不不便,于是实现了批改文件,主动重载的性能。Chrome提供了chrome.runtime.reload
办法,能够利用这个做文章。
首先咱们须要晓得,content_scripts、service_worker、popup这三者是能够相互通信的。插件利用了content_scripts和service_worker之间的消息传递,从而达到刷新的目标。
//content_scripts发送音讯
chrome.runtime.sendMessage({ msg: 'RELOAD' }, () => {
window.location.reload() //service_worker回传音讯给content_scripts的回调
})
//service_worker接管音讯
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.msg == 'RELOAD') {
chrome.runtime.reload() //重载Chrome插件
sendResponse() //回传音讯给content_scripts
}
})
content_scripts是注入到页面的脚本,所以Chrome插件重载之后,才调window.location.reload()
让页面刷新。
vite-plugin-crx-mv3插件,在开发环境会把上述代码别离写入到content-dev.js和background-dev.js(如果用户没配置service_worker才会生成backgound-dev.js。如果配了,就把chrome.runtime.onMessage.addListener那段代码,在transform钩子阶段插入到原有的background.js)。同时也会写入到manifest.json配置文件。
...
"content_scripts": [{
"matches": [""], //设置为,这样所有页面都会加载到
"js": ["content-dev.js"],
}]
"background": {
"service_worker": "background-dev.js"
},
...
到这步曾经筹备得差不多了。咱们的最终目标是,批改文件后,从新打包产出新的文件,而后Chrome插件能够主动刷新。vite build --watch
曾经实现一部分了。主动刷新的性能是应用websocket帮助实现的,批改文件每次从新打包后,发送socket音讯给客户端,客户端再接管音讯。在vite插件的writeBundle阶段操作(其实是rollup的钩子),在这阶段示意曾经构建实现,文件写入实现。
writeBundle(){
//发送音讯给客户端(content-dev.js)
//content-dev.js外面接管到音讯后,就走下面和service_worker通信的流程了。
}
写在最初
这个vite插件根本满足本人现阶段的开发需要,其实开发Chrome插件的教训并不是很多,可能有些场景还没笼罩,请多多包涵。如果应用过程有什么问题,能够告知我。创作不易,如果能帮到您,能够star反对一下~