2023金秋版:基于Vite4+React的Chrome插件开发教程

在这里插入图片描述
在这里插入图片描述

Chrome浏览器插件(Chrome Extension,简称CRX)大家已经非常熟悉了。目前的Chrome Extension开发应该按照Manifest V3的规范。按照谷歌官方的通知,2023年6月开始,将不允许发布Manifest V2的Chrome Extension,预计到2024年将全面下架Manifest V2的Chrome Extension。Manifest V2即将退出历史舞台,因此,本系列教程将不再提及Manifest V2,全部为Manifest V3(简称MV3)内容。

我最近一次发表的关于Chrome插件开发教程是在2023年2月6日《2023新春版:React+Antd开发Chrome插件教程(Manifest V3)》,那个版本是基于React官方的Create-React-App(简称CRA)进行架构设计。但是在React官方网站更新后,就没有再提到Create-React-App了,反而推荐使用其他社区的脚手架工具,其中就提到了Vite。而Create-React-App也一直停留在5.0.1版本,从2022年4月13日至今没有更新,看样子也被官方抛弃了。当然Create-React-App仍然具有它的使用价值。

很多前端开发的小伙伴早就转向Vite了,因此本系列教程的2023金秋版应运而生,详细讲解如何基于Vite开发Chrome插件。希望能够帮助各位省去摸索的时间,少走弯路,快速完成项目开发。

先睹为快

先看下目录了解本教程都有哪些内容。强烈建议按照以下章节一步一步边学边做,可以快速掌握整个项目的原理和细节,在以后遇到新问题的时候,可以知道从哪个环节入手。

章节目录

1 初始化项目
• 1.1 使用Vite新建项目
• 1.2 安装并运行项目
• 1.3 精简项目
2 Vite基础配置
• 2.1 配置国内镜像源
• 2.2 支持Sass/Scss/Less/Stylus
• 2.3 设置dev环境的Server端口号
• 2.4 设置dev环境自动打开浏览器
• 2.5 设置路径别名
3 Chrome Extension基础
• 3.1 Manifest V3概述
• 3.2 Manifest V3 主要新特性
• 3.3 Chrome Extension的组成
• 3.4 规划build生成的目录结构
• 3.5 配置manifest.json
4 项目目录结构设计
5 针对Chrome Extension的Vite配置
• 5.1 设置全局配置
• 5.2 设置popup的build配置
• 5.3 设置content script的build配置
• 5.4 设置background script的build配置
• 5.5 通过补充脚本合并三个build
6 设置公用样式及集成Ant Design
• 6.1 关于样式命名规范
• 6.2 设置全局公用样式
• 6.3 集成Ant Design
• 6.4 设置Antd为中文语言
7 Popup开发
• 7.1 引入popup页面
• 7.2 构建popup的Login页面
• 7.3 构建popup的Home页面
• 7.4 构建popup的Account页面
• 7.5 配置popup页面路由
• 7.6 构建Nav导航组件
• 7.7 构建Entry二级路由框架页面
• 7.8 调整popup入口页面,打通全部路由
• 7.9 完善Login页面的登录跳转
• 7.10 设置popup页面尺寸
8 build项目并载入插件
9 background script开发
• 9.1 设置允许运行popup的页面规则
• 9.2 为什么插件图标在禁用页面不变成灰色
10 content script开发
• 10.1 向目标页面注入悬浮球
• 10.2 在content script中使用Antd
11 在开发环境中调试content script
12 API请求
• 12.1 background pages不支持XMLHttpRequest(axios)
• 12.2 使用mock.js和mockjs-fetch模拟请求
• 12.3 封装API及fetch业务逻辑
• 12.4 委托background script完成API请求
• 12.5 实现popup的Login页面API请求
• 12.6 设置开发环境的反向代理请求
• 12.7 实现content script的API请求
• 12.8 关键知识点小结
13 其他说明
• 13.1 permission权限配置
• 13.2 以<script>方式向目标页面插入js
• 13.3 Service Worker调试
• 13.4 popup页面调试
• 13.5 批量升级全部项目npm依赖包
14 项目Git源码
结束语

本Demo主要依赖包版本

Node.js 18.17.1

vite 4.4.9

react 18.2.0

react-dom 18.2.0

react-router-dom 6.15.0

antd 5.8.3

mockjs 1.1.0

mockjs-fetch 2.2.0

less 4.2.0

sass 1.65.1

stylus 0.59.0

为什么没有使用CRXJS

关于Vite开发Chrome Extension,CRXJS这个Vite Plugin在技术社区中被提及较多。

本教程没有选用CRXJS,主要基于以下原因:

  1. 截至编写本文时,CRXJS官网只更新到了对Vite3的说明,而且CRXJS的2.0版本长期处在Beta阶段,更新频率也不高。
  2. 项目的核心功能尽可能选用“大官方”的原厂产品,有保障。尽可能在官方架构的基础上自己改造,把命运掌握在自己手上,发现问题自己想办法解决,也能更深入掌握核心技术。
  3. 依赖的外部产品越多,学习成本和维护成本也越高。

当然,如果你想了解CRXJS,可以自行查阅它的官网,本教程不使用CRXJS。

CRXJS官网

https://crxjs.dev/vite-plugin

1 初始化项目

1.1 使用Vite新建项目

※注:Vite需要Node.js版本14.18+,16+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。

先进入想要创建项目的目录,在这个目录下执行安装命令。

如果使用npm,执行:

npm create vite@latest

如果使用yarn,执行:

yarn create vite

执行后,会要求填写项目名称,这里我填写的是vite-react-crx,可根据情况自定。

Project name: vite-react-crx

然后,会要求选择框架,选择React:

 Select a framework:
    Vanilla
    Vue
❯   React
    Preact
    Lit
    Svelte
    Solid
    Qwik
    Others

最后,选择开发语言,本教程选择JavaScript:

 Select a variant:
    TypeScript
    TypeScript + SWC
>   JavaScript
    JavaScript + SWC

回答以上“灵魂三问”后,即可完成Vite项目创建。

如果没有安装yarn,可执行以下命令全局安装:

npm install --global yarn

yarn中文网站: yarn.bootcss.com/

1.2 安装并运行项目

进入项目目录,运行命令进行项目依赖包的安装。

cd vite-react-crx
yarn  或者 npm install

稍等片刻,安装完成后,执行以下命令运行项目:

yarn dev 或者 npm run dev

是不是感觉编译的速度非常快,几乎没有感知就完成了。

与Create-React-App不同,Vite默认是不会自动启动浏览器打开项目页面的。

需要手动打开以下地址访问项目:

http://localhost:5173/

在这里插入图片描述

Vite默认开启的端口是5173,后续章节会讲解怎么修改端口号。

1.3 精简项目

接下来,删除用不到的文件,最简化项目。

   ├─ /node_modules
   ├─ /public
-  |  └─ vite.svg
   ├─ /src
-  |  ├─ /assets
-  |  |  └─ react.svg
-  |  ├─ App.css
   |  ├─ App.jsx
-  |  ├─ index.css
   |  └─ main.jsx
   ├─ .eslintrc.cjs
   ├─ .gitignore
   ├─ index.html
   ├─ package.json
   ├─ README.md
   ├─ vite.config.js
   └─ yarn.lock

现在目录结构如下,清爽许多:

├─ /node_modules
├─ /public
├─ /src
|  ├─ App.jsx
|  └─ main.jsx
├─ .eslintrc.cjs
├─ .gitignore
├─ index.html
├─ package.json
├─ README.md
├─ vite.config.js
└─ yarn.lock

以上文件删除后,页面会报错。这是因为相应的文件引用已不存在。需要继续修改代码,先让项目正常运行起来。

逐个修改以下文件,最终精简代码依次如下:

src/App.jsx:

function App() {
    return <div className="App">Vite-React-CRX</div>
}

export default App

src/main.jsx:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'

ReactDOM.createRoot(document.getElementById('root')).render(<App />)

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite React CRX</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

在上述index.html代码中,修改了网站图标,因此需要自行准备一个图标文件favicon.ico,存放在/public目录下。当然,也可以使用svg格式。

   ├─ /node_modules
   ├─ /public
+  |  └─ favicon.ico
   ├─ /src
   |  ├─ App.jsx
   |  └─ main.jsx
   ├─ .eslintrc.cjs
   ├─ .gitignore
   ├─ index.html
   ├─ package.json
   ├─ vite.config.js
   └─ yarn.lock

这里你可能会问,为什么在index.html中的<link>中引入图标的路径是"/favicon.ico",而favicon.ico明明是放在/public目录下,却不是"/public/favicon.ico"呢?

按照Vite官方说明:引入public中的资源永远应该使用根绝对路径,并且,public中的资源不应该被JavaScript文件引用。

public目录Vite官方说明:

https://cn.vitejs.dev/guide/assets.html#the-public-directory

执行yarn dev,运行效果如下:
在这里插入图片描述

2 Vite基础配置

2.1 配置国内镜像源

npm和yarn默认是从国外源站拉取依赖包的,为提高下载速度和稳定性,建议配置为国内镜像源。

设置yarn registry国内镜像:

yarn config set registry https://registry.npmmirror.com

设置npm registry国内镜像:

npm config set registry https://registry.npmmirror.com

如果不清楚本地当前yarn或者npm的配置,可以执行以下命令查看:

yarn查看方法:

yarn config list

npm查看方法:

npm config list

※注:本教程主要使用yarn,后续不再复述对应的npm命令。

2.2 支持Sass/Scss/Less/Stylus

Vite本身提供了对.scss/.sass/.less/.styl/.stylus文件的内置支持。无需再安装特定的Vite插件,但必须安装相应的预处理器依赖。

支持Sass/Scss,执行以下命令安装:

yarn add -D sass

支持Less,执行以下命令安装:

yarn add -D less

支持Stylus,执行以下命令安装:

yarn add -D stylus

安装后,就可以直接使用以上对应的CSS预处理语言了,非常方便。

CSS预处理Vite官方说明:

https://cn.vitejs.dev/guide/features.html#css-pre-processors

2.3 设置dev环境的Server端口号

dev server默认端口是5173,如果想修改为其他端口(例如习惯使用Create-React-App的3000端口),可以进行以下设置。

修改vite.config.js:

    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'

    // https://vitejs.dev/config/
    export default defineConfig({
+       server: {
+           // 指定dev sever的端口号,默认为5173
+           port: 3000,
+       },
        plugins: [react()],
    })

※注:与基于webpack的Create-React-App不同,Vite修改项目配置后,不需要重启项目即可生效。

2.4 设置dev环境自动打开浏览器

使用Create-React-App创建的工程,在启动的时候会自动打开浏览器运行当前项目。但是基于Vite创建的工程默认情况并不会自动打开浏览器。如果想要保持Create-React-App的习惯,自动打开浏览器,可进行以下设置。

修改vite.config.js:

    // https://vitejs.dev/config/
    export default defineConfig({
        server: {
            // 指定dev sever的端口号
            port: 3000,
+           // 自动打开浏览器运行以下页面
+           open: '/',
        },
        ...(略)
    })

open的"/“值,表示的是打开"localhost:3000/”。

如果想直接打开其他页面,例如"localhost:3000/#/home",open的值则设置为"/#/home"即可。

※注:open的值修改后,虽然已经生效,但不会直接触发打开浏览器的行为。这个行为只发生在通过命令启动项目的时候,也就是执行yarn dev的时候。

2.5 设置路径别名

为了避免使用相对路径的麻烦,可以设置路径别名。

修改vite.config.js:

    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
+   import path from 'path'

    // https://vitejs.dev/config/
    export default defineConfig({
        server: {
            ...(略)
        },
+       resolve: {
+           alias: {
+               '@': path.resolve(__dirname, 'src'),
+           },
+       },
        ...(略)
    })

这个配置里使用了path,不要忘记在代码头部要import path from 'path'哦。

这样在js代码开头的import路径中,直接使用@表示“src根目录”,不用去自己去数有多少个"…/"了。

例如,src/main.jsx:

// 表示该文件当前路径下的App.jsx(相对路径)
import App from './App'
// 表示src/App.jsx,等价于上面的文件地址(绝对路径)
import App from '@/App'

3 Chrome Extension基础

本次教程基于目前最新的Chrome Extension Manifest V3进行。

3.1 Manifest V3概述

Manifest V3(简称MV3) 是2020年11月9日发布的,时隔MV2已经有很多年了。使用MV3的Chrome插件将有更好的隐私、安全和性能,还能使用很多新的Web技术。具体如下:

(1)隐私

新版插件可以在不需要特殊权限的情况下正常运行,当运行到需要某个权限时再请求用户使用许可。

(2)安全

对插件访问外部资源做了限制,禁止引入外部js,但图片、视频等静态外部资源不受影响。

(3)性能

确保插件可以在各种设备良好运行,即使在安装了很多插件的情况下,也能流畅运行。

(4)开发

降低开发门槛,减少开发障碍,更快更好地开发插件。

(5)能力

持续提升插件的能力、丰富功能,充分发挥更大的价值作用。

3.2 Manifest V3 主要新特性

(1)Service Workers取代background pages

使用Service Workers,可以对资源进行缓存,从而实现离线访问。

(2)网络请求调整
新增了一个declarativeNetRequestAPI,允许插件修改及阻断网络请求。

(3)远程资源访问限制
禁止访问外部的JavaScript及Wasm文件,但图片、音视频文件不受影响。

(4)Promises使用
可以愉快地使用promise了,包括async/await。

除此之外,还有一些其他的变化。未来,MV3还会引入更多的新特性。

了解更多可参阅官网说明:

https://developer.chrome.com/docs/extensions/mv3/intro/mv3-overview/

3.3 Chrome Extension的组成

主要由以下部分组成:

  1. manifest.json (插件配置文件)
  2. popup (点击插件图标弹出的页面)
  3. content script (插入到目标页面中执行的js)
  4. background script (在Chrome后台Service Workers中运行的程序)

【manifest.json】

manifest.json必须放在插件项目根目录,里面包含了插件的各种配置信息,其中也包括了popup、content script、background script等文件的存放路径。

【popup】

作为一个独立的弹出页面,有自己的html、css、js,可以按照常规项目来开发。

【content script】

content script是注入到目标页面中执行的js脚本,可以获取目标页面的Dom并进行修改。但是,content script的JavaScript与目标页面是互相隔离的。也就是说,content script与目标页面的JavaScript不会出现互相污染的问题,同时,也不能调用对方的方法。

注意,以上只是js作用域的隔离,通过content script向目标页面加入的DOM是可以应用目标页面的css,从而造成css互相污染。

【background script】

background script 常驻在浏览器后台Service Workers运行,没有实际页面。一般把全局的、需要一直运行的代码放在这里。重要的是,background script的权限非常高,除了可以调用几乎所有Chrome Extension API外,还可以发起跨域请求。

3.4 规划build生成的目录结构

在了解Chrome Extension的基本组成后,需要按照Chrome Extension官方开发文档以及manifest.json的要求,按以下结构build最终的目录。

├─ /assets             <--popup的静态资源目录
|  ├─ index-xxxx.css   <--popup的样式文件
|  ├─ index-xxxx.js    <--popup script
|  └─ xxxx.png         <--popup的图片等文件(示例)
├─ /images             <--公共图片资源目录
|  └─ app.png          <--插件的图标文件
├─ background.js       <--background script
├─ content.js          <--content script
├─ content.css         <--content script的css文件
├─ favicon.ico         <--这个没有也行,用不到
├─ index.html          <--popup入口页面
├─ insert.js           <--插入到目标页面执行的js(非必须,视业务需求而定)
└─ manifest.json       <--插件的配置文件

接下来就是如何实现build出这样的目录结构。

3.5 配置manifest.json

在开发Chrome Extension之前,要先配置好manifest.json。

新建public/manifest.json(请删除其中的注释代码):

{
  "name": "Chrome插件V3",
  "version": "1.0",
  "description": "基于Vite的chrome插件V3 Demo",
  // Chrome Extension 版本号,3表示MV3
  "manifest_version": 3,
  // background script配置(根目录为最终build生成的插件包目录)
  "background": {
    "service_worker": "background.js"
  },
  // content script配置
  "content_scripts": [
    {
      // 应用于哪些页面地址(可以使用正则,<all_urls>表示匹配所有地址)
      "matches": ["<all_urls>"],
      // 注入到目标页面的css,注意不要污染目标页面的样式
      "css": ["content.css"],
      // 注入到目标页面js,这个js是在沙盒里运行,与目标页面是隔离的,没有污染问题。
      "js": ["content.js"],
      // 代码注入的时机,可选document_start、document_end、document_idle(默认)
      "run_at": "document_end"
    }
  ],
  // 申请chrome extension API权限
  "permissions": ["storage","declarativeContent"],
  // 插件涉及的外部请求地址,暂未发现影响跨域请求,猜测是用于上架商店时方便审核人员查阅
  "host_permissions":[],
  // 如果向目标页面插入图片或者js,需要在这里授权插件本地资源(以下仅为示例)。
  "web_accessible_resources": [
    {
      "resources": [ "/images/app.png" ],
      "matches": ["<all_urls>"]
    },
    {
      "resources": [ "insert.js" ],
      "matches": ["<all_urls>"]
    }
  ],
  // popup页面配置
  "action": {
    // popup页面的路径(根目录为最终build生成的插件包目录)
    "default_popup": "index.html",
    // 浏览器插件按钮的图标
    "default_icon": {
      "16": "/images/app.png",
      "32": "/images/app.png",
      "48": "/images/app.png",
      "128": "/images/app.png"
    },
    // 浏览器插件按钮hover显示的文字
    "default_title": "React CRX MV3"
  },
  // 插件图标,图省事的话,所有尺寸都用一个图也行
  "icons": {
    "16": "/images/app.png",
    "32": "/images/app.png",
    "48": "/images/app.png",
    "128": "/images/app.png"
  }
}

manifest的配置项还有很多,可前往官网查阅。

manifest:https://developer.chrome.com/docs/extensions/mv3/manifest/

manifest_version:https://developer.chrome.com/docs/extensions/mv3/manifest/manifest_version/

content script:https://developer.chrome.com/docs/extensions/mv3/content_scripts/

permissions:https://developer.chrome.com/docs/extensions/mv3/declare_permissions/

4 项目目录结构设计

本文将按照以下目录结构进行开发:

├─ /node_modules
├─ /public
|  ├─ /images            <--图片目录
|  |  └─ app.png         <--插件图标
|  ├─ favicon.ico        <--这个没有也行,用不到
|  ├─ insert.js          <--插入到目标页面执行的js(非必须,视业务需求而定)
|  └─ manifest.json      <--插件的配置文件
├─ /src
|  ├─ /api               <-- api目录
|  |  └─ index.jsx       <-- api库
|  ├─ /background        <--background script开发目录
|  |  └─ index.jsx       <--background script主文件
|  ├─ /common            <-- 全局公用目录
|  |  ├─ /fonts          <-- 字体文件目录
|  |  ├─ /images         <-- 图片文件目录
|  |  ├─ /js             <-- 公用js文件目录
|  |  └─ /styles         <-- 公用样式文件目录
|  ├─ /content           <--content script开发目录
|  |  ├─ /components     <--content 组件目录
|  |  ├─ /images         <--content 图片目录
|  |  ├─ content.styl    <--content 样式
|  |  └─ index.jsx       <--content script主文件
|  ├─ /popup             <--popup开发目录
|  |  ├─ /components     <--popup 组件目录
|  |  ├─ /pages          <--popup 页面目录
|  |  ├─ /router         <--popup 路由配置目录
|  |  |  └─ index.jsx    <--popup 路由配置文件
|  |  ├─ index.jsx       <--popup 主文件
|  |  └─ popup.styl      <--popup 样式文件
|  ├─ main.jsx           <-- 项目主文件,也是popup入口文件
|  └─ mock.jsx           <-- mock数据文件
├─ .eslintrc.cjs         <-- ESLint配置文件
├─.gitignore
├─ build.js              <-- 补充的build脚本文件
├─ globalConfig.js       <-- 全局配置文件
├─ index.html            <-- popup页面入口
├─ package.json
├─ vite.popup.config.js       <-- popup的Vite配置文件
├─ vite.content.config.js     <-- content的Vite配置文件
├─ vite.background.config.js  <-- background的Vite配置文件
└─ yarn.lock

这种目录结构设计,将background script、content script、popup分别建立独立的目录,并且设置了api、common等公用目录,边界更加清晰,便于维护。

【说明】

  1. 由于content script是在目标页面上执行,并不是独立的页面,因此不能使用router,也无需pages目录。
  2. popup是独立的页面,可以按照常规React项目设定相应的目录。

这里需要注意的是,基于Vite脚手架的工程在src目录里并没有使用js文件,而是以jsx文件进行开发。默认情况下,js文件是不能正常加载的,可以通过修改Vite配置来兼容js文件,但不推荐也没必要这么做。除此之外,在src目录之外则可以直接使用js文件。

另外,以上项目结构已经没有src/App.jsx了,现在先不用删除,随着后续章节的讲解再删除。

接下来,就按照上面的目录结构设计开始构建项目。

5 针对Chrome Extension的Vite配置

按照Chrome Extension的规范要求,build出popup项目、content script、background script。

5.1 设置全局配置

在项目根目录下新建globalConfig.js:

// Chrome Extension 最终build目录
export const CRX_OUTDIR = 'build'
// 临时build content script的目录
export const CRX_CONTENT_OUTDIR = '_build_content' 
// 临时build background script的目录
export const CRX_BACKGROUND_OUTDIR = '_build_background'

build目录是最终的成品。_build_content目录和_build_background目录只是过程产物,它俩在build结束后,会合并到build目录中,然后自动删除_build_content目录和_build_background目录。

为什么要这么做?

首先,popup项目是一个包括html、css、js等文件的完整小型网站,按照Vite的默认配置即可直接build生成。但是content script、background script是没有html的,build配置不一样,因此需要单独进行build。

其次,content script、background script如果引入了共同的js模块(例如都import了自定义的api库文件),会被Vite将这些共同的js模块抽离成公共js文件。

举个例子,content script中引入了A、B模块,background script中引入了B、C模块。

我们期待打包成两个文件:

  • content.js (A+B)
  • background.js (B+C)

但实际上会打包成三个文件:

  • content.js (A)
  • background.js ©
  • B.js (B)

而CRX的content script和background script不能再import或require其他文件。所以,只能将content script和background script分别通过不同的Vite配置文件进行打包,并生成在不同的目录下。

5.2 设置popup的build配置

将原vite.config.js更名为vite.popup.config.js。

修改vite.popup.config.js:
❤️❤️❤️------试读结束------❤️❤️❤️

后续精彩章节

• 5.3 设置content script的build配置
• 5.4 设置background script的build配置
• 5.5 通过补充脚本合并三个build
6 设置公用样式及集成Ant Design
• 6.1 关于样式命名规范
• 6.2 设置全局公用样式
• 6.3 集成Ant Design
• 6.4 设置Antd为中文语言
7 Popup开发
• 7.1 引入popup页面
• 7.2 构建popup的Login页面
• 7.3 构建popup的Home页面
• 7.4 构建popup的Account页面
• 7.5 配置popup页面路由
• 7.6 构建Nav导航组件
• 7.7 构建Entry二级路由框架页面
• 7.8 调整popup入口页面,打通全部路由
• 7.9 完善Login页面的登录跳转
• 7.10 设置popup页面尺寸
8 build项目并载入插件
9 background script开发
• 9.1 设置允许运行popup的页面规则
• 9.2 为什么插件图标在禁用页面不变成灰色
10 content script开发
• 10.1 向目标页面注入悬浮球
• 10.2 在content script中使用Antd
11 在开发环境中调试content script
12 API请求
• 12.1 background pages不支持XMLHttpRequest(axios)
• 12.2 使用mock.js和mockjs-fetch模拟请求
• 12.3 封装API及fetch业务逻辑
• 12.4 委托background script完成API请求
• 12.5 实现popup的Login页面API请求
• 12.6 设置开发环境的反向代理请求
• 12.7 实现content script的API请求
• 12.8 关键知识点小结
13 其他说明
• 13.1 permission权限配置
• 13.2 以<script>方式向目标页面插入js
• 13.3 Service Worker调试
• 13.4 popup页面调试
• 13.5 批量升级全部项目npm依赖包
14 项目Git源码
结束语

阅读完整版

📖 完整教程可订阅我的公众号【卧梅又闻花】

《2023金秋版:基于Vite4+React的Chrome插件开发教程》

14 项目Git源码

本项目已上传至Gitee和GitHub,方便各位下载。

Gitee:

https://gitee.com/betaq/vite-react-crx-2023autumn

GitHub:

https://github.com/Yuezi32/vite-react-crx-2023autumn

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr兔子先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值