首页 > 其他分享 >使用 CRXJS、Vite、TypeScript、React、Zustand、Antd 开发 Chrome 浏览器插件——自带热加载,无需手动配置 vite.config.ts 文件

使用 CRXJS、Vite、TypeScript、React、Zustand、Antd 开发 Chrome 浏览器插件——自带热加载,无需手动配置 vite.config.ts 文件

时间:2024-03-29 15:59:36浏览次数:28  
标签:src 插件 TypeScript Zustand ts content Vite vite

一、CRXJS

一、什么是 CRXJS?

CRXJS Vite Plugin 是一款使用现代 Web 开发技术制作 Chrome 扩展的工具

二、CRXJS 的作用

CRXJS 支持热加载和静态资源导入,无需手动构建配置工具
CRXJS Vite 插件通过将 Vite 的精细功能与简单的配置策略相结合,简化了 Chrome 扩展开发者体验

二、使用 React 开发 Chrome 插件

一、创建 React 项目

1. 使用 Vite 创建 React 项目

npm create vite@latest # npm
yarn create vite			 # yarn
pnpm create vite			 # pnpm

选择 reactTS

CRXJS 中的 HMR 与@vite/plugin-react-swc. 用@vitejs/plugin-react。

react ts

进入项目,并进行 pnpm i 安装 node_modules

  cd crxjs-vite-react-chrome
  pnpm install

2. 安装 CRXJS Vite 插件

pnpm i @crxjs/vite-plugin@beta -D # 安装 CRXJS Vite 插件

3. 创建 Manifest.json 文件

{
  "manifest_version": 3,
  "name": "CRXJS React Vite Example",
  "version": "1.0.0",
  "action": {
    "default_popup": "index.html"
  }
}

4. 修改 Vite.config.ts 配置文件

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { crx } from '@crxjs/vite-plugin'
import manifest from './manifest.json'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    crx({ manifest }),
  ],
})

5. 运行 pnpm run dev 命令

可以看到多了个 dist 文件夹,这个就是构建好的插件安装包

.
├── README.md
├── dist
│   ├── assets
│   │   └── loading-page-1924caaa.js
│   ├── index.html
│   ├── manifest.json
│   ├── service-worker-loader.js
│   └── vite.svg
├── index.html
├── manifest.json
├── package.json
├── pnpm-lock.yaml
├── public
│   └── vite.svg
├── src
│   ├── App.css
│   ├── App.tsx
│   ├── assets
│   │   └── react.svg
│   ├── index.css
│   ├── main.tsx
│   └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

6. 安装插件

打开浏览器输入:chrome://extensions,点击【加载已解压的扩展程序】选择 dist 文件夹进行安装

插件页面

crxjs react ext

popup action 页面

popup action

7. HMR 热加载

7.1. Manifest.json 热加载

添加 description

"description": "this is my Crxjs&React Chrome ext",

无需刷新插件和插件页面

add desc

7.2. Popup 页面热加载

修改 popup 页面
我们选择 src/App.tsx 页面,加入这几个文案

test HMR

重新点击 popup action

test hmr

7.3. Content 页面热加载

content 页面配置在下一节

content.ts 页面代码

console.log('this is content page')
console.log('HMR')

当前页面无需手动刷新

content page

二、插件模块配置

1. Content 模块配置

1.1. Src 中新建 content 文件夹,content 文件夹中新建 content.ts 文件
src/content
└── content.ts

简单写入以下代码

console.log('this is content page')
1.2. 配置 manifest.json 文件

因为有 crxjs 给我们做处理了,所以在 content_scripts 中的 js 字段,直接根据 root 配置引入就行

"content_scripts": [
  {
    "js": [
      "src/content/content.ts"
    ],
    "matches": [
      "http://127.0.0.1:5500/*"
    ],
    "all_frames": true,
    "run_at": "document_end",
    "match_about_blank": true
  }
]
1.3. 保存,刷新 http://127.0.0.1:5500/* 页面

可以看到 content.ts 中的日志输出了

constent page

2. Background Service-worker 模块配置

2.1. src 中新建 background 文件夹,background 文件夹中新建 service-worker.ts 文件
src/background
└── service-worker.ts

简单写入以下代码

console.log('this is background service worker file')
2.2. 配置 manifest.json 文件

因为有 crxjs 给我们做处理了,所以在 background 中的 service_worker 字段,直接根据 root 配置引入就行

"background": {
  "service_worker": "src/background/service-worker.ts"
},
2.3. 保存,点击插件 Service Worker 模块

可以看到 service_worker.ts 中的日志输出了

service worker page

2.4. 可以看到有两行 client-worker 输出

这个不用管,如果这个报错也不用管,这个是 crxjs 的配置,以及热加载

crxjs set

3. Content 页面模块配置

3.1. 在 src/content 下面创建 content.tsx 文件
src/content
├── content.ts
└── content.tsx
3.2. 配置 manifest.json 文件
"content_scripts": [
  {
    "js": [
      "src/content/content.ts"
    ],
    "matches": [
      "http://127.0.0.1:5500/*"
    ],
    "all_frames": true,
    "run_at": "document_end",
    "match_about_blank": true
  },
  {
    "js": [
      "src/content/content.tsx"
    ],
    "matches": [
      "http://127.0.0.1:5500/*"
    ],
    "all_frames": true,
    "run_at": "document_end",
    "match_about_blank": true
  }
]
3.3. content 页面展示

content

3.4. 合并 content_script

因为 content.tscontent.tsx 的匹配模式一样,所用可以合并到一个 js 数组中

"content_scripts": [
  {
    "js": [
      "src/content/content.ts",
      "src/content/content.tsx"
    ],
    "matches": [
      "http://127.0.0.1:5500/*"
    ],
    "all_frames": true,
    "run_at": "document_end",
    "match_about_blank": true
  }
]

三、插件项目开发

1. Chrome TS 配置

1.1. 安装 chrome-types 模块
pnpm i chrome-types -D
1.2. Src/vite-env.d.ts 中增加配置
/// <reference types="chrome-types/index" />
1.3. App.tsx 中使用 chrome

app tsx

1.4. Service-worker.ts 中使用

service worker

1.5. Content.ts 中使用

content

2. 静态资源引入

2.1. Assets 文件夹下添加一张图片
src/assets
├── react.svg
└── vite_crxjs_react.jpg
2.2. App.tsx 中引入
import crxjsPho from './assets/vite_crxjs_react.jpg'
<img src={crxjsPho} width='300px' height='125px' />
2.3. 重新点击 popup action

add img

3. Ant Design 使用

3.1. 安装 Ant Design
pnpm i antd 
3.2. App.tsx 中引入并使用
import { useState } from 'react'
import { Button } from 'antd'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import crxjsPho from './assets/vite_crxjs_react.jpg'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        test HMR
        <Button type="primary">Primary Button</Button>
        <Button>Default Button</Button>
        <Button type="dashed">Dashed Button</Button>
        <Button type="text">Text Button</Button>
        <Button type="link">Link Button</Button>
        <img src={crxjsPho} width='300px' height='125px' />
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  )
}

export default App
3.3. 重新点击 popup action

popup

4. Zustand 使用

4.1. 安装 zustand
pnpm i zustand
4.2. Src 文件下新建 store 文件夹,内件 store.ts
src/store
└── store.ts
4.3. store.ts 中写入以下内容
import { create } from 'zustand';

interface ICountStoreState {
  count: number
  increment: (countNum: number) => void
  decrement: (countNum: number) => void
}

const useStore = create<ICountStoreState>((set) => ({
  count: 0,
  increment: (countNum: number) => set((state) => ({ count: state.count + countNum })),
  decrement: (countNum: number) => set((state) => ({ count: state.count - countNum })),
}));

export default useStore;
4.4 App.tsx 使用 store

加入以下代码

import useStore from './store/store'
function App() {
  const { numVal, increment, decrement } = useStore();

  return (
    <>
      <div>
        <div>
          <span>numVal is {numVal}</span>
          <Button onClick={() => increment(1)}>
            increment 1
          </Button>
          <Button onClick={() => decrement(1)}>
            decrement 1
          </Button>
        </div>
        ...
    </>
  )
}

export default App
4.5. 点击 popup,弹出页面

在这里插入图片描述

5. 使用 Less 预处理

5.1. 安装 Less
pnpm i less -D
5.2 在 src 中创建 styles 文件夹并创建 index.less
src/styles
└── index.less

Vite 会自动生成 index.css 文件
index.less 文件内容

.test-parent{
  background: red;
  padding: 10px;
  .test{
    background: green;
    padding: 10px;
  }
}
5.3. App.tsx 中使用

文件中加入以下代码

import './styles/index.less'

function App() {
  return (
    <>
      <div>
        <div className="test-parent">
          <div className="test">
            test less
          </div>
        </div>
        ...
      </div>
    </>
  )
}

export default App
5.4. 点击 popup,弹出页面

less style

四、问题反馈

1. Popup 页面点击不显示正常页面

1.1. 如果点击 popup 页面如下图所示,不展示正常的页面

error

1.2. 解决方法
  1. 点击插件【错误】按钮
    error
  2. 点击【全部清除】按钮
    在这里插入图片描述
  3. 点击刷新按钮
    reload
  4. 点击 popup 页面
    在这里插入图片描述

四、总结

标签:src,插件,TypeScript,Zustand,ts,content,Vite,vite
From: https://blog.csdn.net/guoqiankunmiss/article/details/137007691

相关文章

  • 你问我答!手把手教学,银河麒麟桌面操作系统编译安装BIMP插件过程详解
    (引言:银河麒麟应热心用户后台提问,推出银河麒麟桌面操作系统编译安装BIMP插件详解过程详解专题。如有其它问题和需求,欢迎后台留言咨询……)1.GIMP简介GIMP是GNU图像处理程序(GNUImageManipulationProgram)的缩写。包括几乎所有图象处理所需的功能,号称Linux下的PhotoS......
  • QT 自定义插件问题 error: LNK2001: 无法解析的外部符号
    为了重复利用已有的代码,我使用自定义插件进行开发。当每个插件独立开发时没有遇到问题,但是当插件B引用了插件A时就会在编译时报错error:LNK2001:无法解析的外部符号。例如,先定义一个插件ColorPicker,用于颜色选取。关键代码如下:classQDESIGNER_WIDGET_EXPORTColorPicker:......
  • 2024新版彩虹易支付系统源码/USDT源码/当面付/通道轮询/44支付插件/免签约支付系统
    ❖ 演示站点                                                                         ☰前台演示:  https://pa......
  • Mybatis是如何进行分页的?分页插件的原理是什么?
    Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执......
  • 如何优雅的查看方法耗时,不用写一行代码!这个插件支持的太多了
    前言没错,又是CoolRequest插件,这次引来一个重大更新,可以统计任意方法耗时,先上个图。另外,这是此次更新的功能。什么是CoolRequestCoolRequest是一个IDEA中的接口调试插件,除了可以发起基本的HTTP请求之外,还提供了强大的反射调用能力,可以绕过拦截器,这点广受网友的好评,当然伴......
  • Qt自定义插件写Excel表格
    网上找到一个开源的Qt插件,下载下来,生成头文件和库文件,可以不依赖电脑是否安装Excel软件,是否有Excel驱动,可以直接输出excel文档https://github.com/dbzhang800/QtXlsxWriter/tree/master/src/xlsx#include"CopyAllFileThread.h"#include<QFileInfo>#include"LocalDb.h"#inc......
  • 魔兽世界LUA插件开发
    魔兽世界LUA插件开发1.创建插件1.1创建插件文件夹打开WorldofWarcraft\Interface\AddOns文件下,在该文件夹下创建一个插件名文件夹用来存放插件,如Makubex1.2创建插件文件在该文件夹下创建俩个文件,一个是用来给魔兽世界引入的toc头文件,一个是你自己的lua脚本文件......
  • 各种 IntelliJ IDEA 酷炫插件推荐
    (2)BackgroundImagePlusidea背景修改插件,让你的idea与众不同,可以设置自己喜欢的图片作为code背景。安装成功之后重启,菜单栏的VIew标签>点击SetBackgroundImage(没安装插件是没有这个标签的),在弹框中路由选择到本地图片,点击OK即可。(3)Grepconsole自定义日志颜色,idea控......
  • 鸿蒙开发 TypeScript 基础语法
    文章的最下面有官网链接可以进行练习!变量声明TypeScript在JavaScript的基础上加入了静态类型检查功能,因此每一个变量都有固定的数据类型let:声明变量的关键字,const则代表常量示例代码://string:字符串,可以用单引号或双引号letmsg:string='helloworld'//number:数......
  • Vue学习笔记65--常用插件安装指令
    常用插件安装指令nanoid:用于生成唯一主键id第一步:npminstallnanoid第二步:import{nanoid}from'nanoid'第三步:id:nanoid(), //也可以指定生成字符串的长度,如nanoid(5)uuid:用于生成唯一主键id第一步:npminstalluuid第二步:import {v4 asuuidv4 } from ......