使用Vite搭建Chrome插件项目

前言

写了个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": [ "<all_urls>" ],
    "js": ["content.js"]
  }],
  "background": {
    "service_worker": "background.js"
  },
  "manifest_version": 3
}

这其中version, manifest_version,name为必填项。

好了,现在我们都清楚项目需要有什么了。这个vite插件就是以manifest.json作为一个入口文件,解析出里面的内容,比如service_workercontent_scriptspopup.html等等的路径。再通过这些得到的内容,利用构建工具打包出我们想要的最终的文件。因此,配合上这个vite插件,原本只能配置原生js,css后缀的manifest.json支持了配置.ts(x)、.scss、.less这样格式的文件了,因为这些都会在插件内部作解析的。这样,content_scripts也实现了使用vue、react等等这样的技术栈开发了。

例如,配置了tsx文件:

...
"content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.tsx"],
}]
 ...

打包后是这样。产生的css文件会自动写入到配置:

...
"content_scripts": [{
    "matches": [ "<all_urls>" ],
    "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": ["<all_urls>"], //设置为<all_urls>,这样所有页面都会加载到
    "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支持一下~

0 条评论
请不要发布违法违规有害信息,如发现请及时举报或反馈
还没有人评论呢,速度抢占沙发!
相关文章
  • 使用场景: 提一下vue2 用法>> 下面回到正题 vue3 用法 1  安装包: npm install @icon-park/vue-next --save 2  字节跳动图标库取图地址...

  • vue3 正式发布有两年多了,之前也做过一些学习和研究。vue3 发布后给某培训机构开发了一套vue3课程课件,自己也开源了一套基于vue3的后台管理系统(因为个人懒的原因,半年后才上传到gitHub...

  • 一、先实现一个简易版本 初始化 npm npm init -y // -y 能省去填写信息的步骤,一步到位 安装几个必要的依赖 npm install css-loader style-lo...

  • 1.有哪些生命周期: beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed 2.一...

  • 1.虚拟机下载 官网下载地址:https://www.kali.org/get-kali/#kali-virtual-machines 选择VMware版本下载,并解压 2.打开虚拟机 选择打开虚...

  • Vue3,webpack,vite 通用 适用于中大型项目中 1.安装vuex npm i vuex 2.创建仓库与文件结构(核心) 一,创建入口 在src目录下创建store文件夹,store...

  • 组件化是 Vue, React 等这些框架的一个核心思想,通过把页面拆成一个个高内聚、低耦合的组件,可以极大程度提高我们的代码复用度,同时也使得项目更加易于维护。所以,本文就来分析下组件的渲染流程。我...

  • 本文基于Vue 3.2.30版本源码进行分析为了增加可读性,会对源码进行删减、调整顺序、改变的操作,文中所有源码均可视作为伪代码由于ts版本代码携带参数过多,大部分伪代码会采取js的形式展示,而不是原...

  • 朋友是做财务的,由于工作时间不长,每次将数字转为大写人民币的时候,总是提心吊胆的,生怕弄错了。而且,如果是整数的话,还好,但是有小数的时候就比较费劲了,比如123.45,转成大写应该是壹佰贰拾叁元肆角...

  • 所有生命周期钩子的this上下文都是绑定至实例的。 beforeCreate:在实例初始化之后、进行数据帧听和事件/侦听器的配置之前同步调用。 created:实例创建完成,主要包括数据帧听、计算属...

  • 写在前面在前端中,主要涉及的基本上就是 DOM的相关操作 和 JS,我们都知道 DOM 操作是比较耗时的,那么在我们写前端相关代码的时候,如何减少不必要的 DOM 操作便成了前端优化的重要内容。虚拟D...

  • 模板tamplate经过parse,optimize,generate等一些列操作之后,把AST转为render function code进而生成虚拟VNode,模板编译阶段基本已经完成了,那么这一...

  • 前言在Vue组件库开发过程中,Vue组件之间的通信一直是一个重要的话题,虽然官方推出的 Vuex 状态管理方案可以很好的解决组件之间的通信问题,但是在组件库内部使用 Vuex 往往会比较重,本文将系统...

  • day021、列表的过滤和排序 设计数据​ 逻辑并不难,关键就看能不能想到用计算属性​ 一个数据根据另外的数据变化而产生,八九不离十要使用计算属性2、vue如何去监视数据变化而更新页面(点...

  • 官网: wangEditor  https://www.wangeditor.com/v5/ 为啥用这个富文本编辑器(我觉得官网写自己优势已经非常好了没有啥可补充的了) 文档特别的全和友好 安装 ...

  • 初识Vue 初识Vue hello,{{name.toUpperCase()}},{{address}...

  • 一款很容易上手配置的富文本编辑器,和 Element plus 一起使用效果非常好,还能自定义功能。关于 Element Tiptap EditorElement Tiptap Editor 是一个在...

  • 这一章就着重讲两个点:响应式系统如何收集依赖响应式系统如何更新视图 我们知道通过Object.defineProperty做了数据劫持,当数据改变的时候,get方法收集依赖,进而set方法调用dep....

  • 不废话上思路 外部el-table-column是基础table模板,里面template slot-scope 的主要作用就是获取table一行的数据信息; 其次要加一个对话框,在对话框里输入数值然...

  • 初衷: 在没有固定的项目模版之前;每次新建项目之后配置代码风格都需要来回粘贴;并且有时候粘贴了也不生效;故总结成文档;方便之后直接使用介绍ESLint 是JavaScript和JSX检查工具prett...