Chrome插件学习笔记(三)

参考文章:

  • https://blog.csdn.net/guoqiankunmiss/article/details/135847091
  • https://blog.csdn.net/guoqiankunmiss/article/details/135974364

1、项目搭建

在前两篇文章中使用的原生js去操作dom,很费劲并且效果并不是很好,于是决定使用vue3来开发浏览器插件

1.1、创建项目

npm create vite@latest

1.2、依赖安装

# @types/node、@types/ws:用来补充类型信息
# chokidar:用来监听文件变化
# chrome-types:chrome相关的类型提示
# rollup-plugin-copy:用于复制manifest.json
# ws:用于创建WebSocket
npm install -D @types/node @types/ws chokidar chrome-types rollup-plugin-copy ws

1.3、vite.config.ts

import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import * as path from "node:path";
import copy from "rollup-plugin-copy";// https://vite.dev/config/
export default defineConfig({server: {port: 5500,},plugins: [vue(),copy({targets: [{src: 'src/manifest.json',dest: path.resolve(__dirname, 'dist')}],hook: 'writeBundle'}),],build: {outDir: path.resolve(__dirname, 'dist'),rollupOptions: {input: {side_panel: path.resolve(__dirname, 'src/index.html'),content_script: path.resolve(__dirname, 'src/content_script/content_script.ts'),service_worker: path.resolve(__dirname, 'src/service_worker/service_worker.ts'),},output: {assetFileNames: 'assets/[name]-[hash].[ext]',chunkFileNames: 'js/[name]-[hash].js',entryFileNames: (chunkInfo) => {const facadeModuleId = chunkInfo.facadeModuleId!const baseName = path.basename(facadeModuleId, path.extname(facadeModuleId))const saveArr = ['content_script', 'service_worker']return `[name]/${saveArr.includes(baseName) ? baseName : chunkInfo.name}.js`;},name: '[name].js'}}}
})

1.4、manifest.json

{"name": "Assistant","description": "A tool for quick conversations with AI","version": "0.0.1","manifest_version": 3,"permissions": ["sidePanel"],"host_permissions": ["*://*/*"],"action": {"default_title": "Click to switch side panel"},"side_panel": {"default_path": "src/index.html"},"background": {"service_worker": "service_worker/service_worker.js","type": "module"},"content_scripts": [{"js": ["content_script/content_script.js"],"matches": ["*://*/*"],"all_frames": true,"run_at": "document_end","match_about_blank": true}]
}

1.5、vite-env.d.ts

/// <reference types="vite/client" />
/// <reference types="chrome-types/index" />

1.6、service_worker.ts

console.log("service_worker");chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: true})

1.7、content_script.ts

console.log("content_script");

1.8、index.html

index.html需要移动到src目录下

1.9、目录结构

在这里插入图片描述

1.10、测试

在这里插入图片描述

2、热部署

热部署的方式很多,如利用额外的插件(可参考文章https://cm-mng.bilibili.co/agent/#/mlogin),这里使用的是socket通信来实现的热部署

2.1、.env.development

VITE_ENV_MODE=development

2.2、 .env.production

VITE_ENV_MODE=production

2.3、file_watcher.ts

import {WebSocketServer} from "ws";
import chokidar from "chokidar";
import path from "node:path";export function file_watcher(wss: WebSocketServer) {wss.on('connection', (ws) => {console.log('Client connected');// 监听src文件夹下的所有文件,并排出node_modules下所有文件const watcher = chokidar.watch(path.join(__dirname, 'src'), {ignored: [/(^|[\/\\])\../, /node_modules/]});// 只有文件变化才会通知,如果设置成all将会通知add、change、addDir等事件watcher.on('change', (event, path) => {ws.send(JSON.stringify({type: 'reload', event, path}));});ws.on('close', () => {console.log('Client disconnected');watcher.close();});});
}

2.4、vite.config.ts

import {defineConfig, loadEnv} from 'vite'
import vue from '@vitejs/plugin-vue'
import * as path from "node:path";
import copy from "rollup-plugin-copy";
import {WebSocketServer} from "ws";
import {file_watcher} from "./file_watcher.ts";// https://vite.dev/config/
export default defineConfig((configEnv) => {// 这里取的环境变量是.env.xxxxx中的变量,根据加载的环境变量判断是否启动socket服务端,用于通知浏览器插件重新加载let env = loadEnv(configEnv.mode, process.cwd(), '');if (env.VITE_ENV_MODE === 'development') {file_watcher(new WebSocketServer({port: 5501}));}return {server: {port: 5500,},plugins: [vue(),copy({targets: [{src: 'src/manifest.json',dest: path.resolve(__dirname, 'dist')}],hook: 'writeBundle'}),],build: {outDir: path.resolve(__dirname, 'dist'),rollupOptions: {input: {side_panel: path.resolve(__dirname, 'src/index.html'),content_script: path.resolve(__dirname, 'src/content_script/content_script.ts'),service_worker: path.resolve(__dirname, 'src/service_worker/service_worker.ts'),},output: {assetFileNames: 'assets/[name]-[hash].[ext]',chunkFileNames: 'js/[name]-[hash].js',entryFileNames: (chunkInfo) => {const facadeModuleId = chunkInfo.facadeModuleId!const baseName = path.basename(facadeModuleId, path.extname(facadeModuleId))const saveArr = ['content_script', 'service_worker']return `[name]/${saveArr.includes(baseName) ? baseName : chunkInfo.name}.js`;},name: '[name].js'}}}}
})

2.5、hot_reload.ts

let timeout: numberexport function hot_reload(socket: WebSocket) {if (timeout) {clearTimeout(timeout);}socket.onopen = () => {console.log('Connected to dev server')}socket.onmessage = (event) => {const message = JSON.parse(event.data)if (message.type === 'reload') {setTimeout(() => {chrome.runtime.reload()}, 1000)}}socket.onclose = (event) => {console.log(`Socket closed: ${event.reason}`);// 断开连接后5秒后尝试再次连接timeout = setTimeout(() => {hot_reload(new WebSocket(`ws://localhost:5501/`))}, 5000);};socket.onerror = (error) => {console.error('Socket error:', error);};
}

2.6、service_worker.ts

import {hot_reload} from "../hot_reload.ts";console.log("service_worker");chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: true})// 如果是开发环境才尝试链接socket服务端
if (import.meta.env.VITE_ENV_MODE === 'development') {console.log('开发环境');hot_reload(new WebSocket(`ws://localhost:5501/`))
} else {console.log('生产环境');
}

2.7、package.json

注意这里的scripts需要修改下,开发的时候使用命令npm run watch,修改代码后插件会自动重新加载

{"name": "assistant","private": true,"version": "0.0.0","type": "module","scripts": {"dev": "vite","watch": "vite build --watch --mode development","build": "vue-tsc -b && vite build","preview": "vite preview"},"dependencies": {"@types/node": "^24.1.0","@types/ws": "^8.18.1","chokidar": "^4.0.3","chrome-types": "^0.1.363","rollup-plugin-copy": "^3.5.0","vue": "^3.5.17","ws": "^8.18.3"},"devDependencies": {"@vitejs/plugin-vue": "^6.0.0","@vue/tsconfig": "^0.7.0","typescript": "~5.8.3","vite": "^7.0.4","vue-tsc": "^2.2.12"}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/90538.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/90538.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/90538.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android系统中的4KB内存页简介

deepseek回答&#xff1a; Android系统中的4KB内存页是虚拟内存管理的最小单位&#xff0c;其主要用途如下&#xff1a; 一、核心功能 虚拟地址映射 应用程序访问内存时&#xff0c;系统将虚拟地址按4KB页框映射到物理内存或磁盘空间&#xff0c;实现进程间的内存隔离和安全访…

【Chrome】下载chromedriver的地址

下载chromedriver的地址低版本的最新版本的低版本的 http://chromedriver.storage.googleapis.com/index.html 最新版本的 https://googlechromelabs.github.io/chrome-for-testing/#stable

ISP算法——从颜色恒常性到白平衡

前面文章&#xff0c;介绍了人眼感知的物体颜色取决于光源的光谱组成与物体表面的光谱反射特性之间的相互作用。人类视觉的颜色感知是生物机制与认知智能协同作用的结果&#xff0c;人眼视网膜上的视锥细胞检测光的颜色&#xff0c;视杆细胞分析光的亮度&#xff0c;再共同转化…

工业缺陷检测的计算机视觉方法总结

工业缺陷检测的计算机视觉方法总结 传统方法 特征提取方式&#xff1a; 颜色&#xff1a;基于HSV/RGB空间分析&#xff0c;如颜色直方图、颜色矩等纹理&#xff1a;采用LBP、Haar、Gabor滤波器等算子提取纹理模式形状&#xff1a;基于Hu矩、Zernike矩等数学描述符刻画几何特性尺…

js实现宫格布局图片放大交互动画

可直接运行代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>五图交互布局</title><style>* {box-sizing: border-box;margin: 0;padding: 0;}.gallery {display: grid;grid-template-c…

easyexcel流式导出

EasyExcel 支持流式导出&#xff0c;这是它的一个重要特性。流式导出可以有效解决大数据量导出时的内存溢出问题。流式导出的优势内存友好 &#xff1a;不会一次性将所有数据加载到内存中适合大数据量 &#xff1a;可以处理百万级甚至更多的数据性能稳定 &#xff1a;内存占用相…

广州 VR 安全用电技术:工作原理、特性及优势探析​

&#xff08;一&#xff09;沉浸式学习体验​ 在广州&#xff0c;VR 用电安全培训技术给用电安全培训带来变革。借助头戴式显示设备等硬件&#xff0c;结合 3D 建模和实时渲染技术&#xff0c;打造广州特色用电场景。员工戴上 VR 设备进入虚拟电力场景&#xff0c;能看到电气设…

2.Linux 网络配置

Linux: 网络配置 版本为centos7 网卡配置文件&#xff1a; /etc/sysconfig/network-scripts/ifcfg-ens33 [rootkami /]# cat /etc/sysconfig/network-scripts/ifcfg-ens33 TYPEEthernet /类型&#xff1a;以太网 PROXY_METHODnone BROWSER_ONLYno BOOTPROTOnone /网络配…

FPGA Verilog 入门语法指南

FPGA Verilog 入门语法指南 📋 目录 Verilog与C语言对比 基础关键字 数据类型 运算符 控制结构 数值表示 阻塞与非阻塞赋值 模块结构 预处理指令

【鸿蒙HarmonyOS Next App实战开发】视频提取音频

在多媒体处理场景中&#xff0c;经常需要从视频文件中提取纯净的音频轨道。本文将介绍如何在HarmonyOS应用中实现这一功能&#xff0c;核心代码基于ohos/mp4parser库的FFmpeg能力。 功能概述 我们实现了一个完整的视频音频提取页面&#xff0c;包含以下功能&#xff1a; 通过…

OpenHands:Manus 最强开源平替——本地部署与实战指南

文章目录⚙️ 一、OpenHands 核心优势&#xff1a;为何是 Manus 最佳平替&#xff1f;&#x1f9e0; 二、核心架构解析&#xff1a;多智能体如何协同工作&#xff1f;&#x1f6e0;️ 三、本地化部署指南&#xff1a;Docke部署Docker 极速部署&#xff08;推荐&#xff09;&…

用 AI 做数据分析:从“数字”里挖“规律”

数据整理干净后&#xff0c;就得分析了——算平均值、看差异、找关系&#xff0c;这些都能靠 AI 搞定。这节以“大学生在线学习满意度”数据为例&#xff0c;教你用 AI 做描述性统计、假设检验、相关性分析&#xff0c;一步步从数据里挖规律&#xff0c;超详细&#xff5e; 1. …

小程序安卓ApK转aab文件详情教程MacM4环境

根据Google Play的政策要求&#xff0c;自 2021 年 8 月起&#xff0c;Google Play 将开始要求新应用使用 Android App Bundle&#xff08;以下简称aab&#xff09; 进行发布。该格式将取代 APK 作为标准发布格式。 想了解更多关于aab的介绍可以直接阅读android官方文档&#x…

率先通过自动制冰性能认证,容声冰箱推动行业品质升级

日前&#xff0c;容声冰箱“电冰箱自动制冰性能认证”由中国家用电器研究院测试并通过&#xff0c;该认证为行业首次。这标志着中国家电行业在冰箱自动制冰功能的技术规范与品质保障领域树立了全新里程碑&#xff0c;也将洁净、高效的制冰体验带入中国家庭日常生活。目前&#…

大模型-batch之continuous batching

一、ORCA1.1 ORCA 概览看下Continuous Batching 技术的开山之作ORCA,这个其实是融合的思路。ORCA&#xff1a;把调度粒度从请求级别调整为迭代级别&#xff0c;并结合选择性批处理&#xff08;selective batching&#xff09;来进行优化。Sarathi[2] &#xff1a;利用Chunked P…

主要分布在背侧海马体(dHPC)CA1区域(dCA1)的时空联合细胞对NLP中的深层语义分析的积极影响和启示

时空联合细胞&#xff08;Spatiotemporal Conjunctive Cells&#xff09;主要分布在背侧海马体CA1区&#xff08;dCA1&#xff09;&#xff0c;其核心功能是​​同步编码空间位置、时间信息和行为意图​​&#xff0c;形成动态的情景记忆表征。这种神经机制为自然语言处理&…

操作系统:系统程序(System Programs)

目录 常见的系统程序类型 1️⃣ 文件管理&#xff08;File Management&#xff09; 2️⃣ 状态信息&#xff08;Status Information&#xff09; 3️⃣ 编译器和程序开发&#xff08;Program Language Support&#xff09; 4️⃣ 程序执行控制类&#xff08;Program Load…

【知识图谱】Neo4j Desktop桌面版中国区被禁(无法打开)问题解决方法

【知识图谱】Neo4j Desktop桌面版进程运行无法打开,UI 界面无法显示问题解决办法 前言 1.问题形式 2.原因分析 3.解决方法 3.1 方法一,断网 3.2 方法二,手动设置代理 4.启动Neo4j Desktop 前言 Neo4j Desktop桌面版安装教程参考链接: https://zskp1012.blog.csdn.net/artic…

安装acunetix软件之后改www.ddosi.org.bat文件

安装环境&#xff1a;windows11 通过网盘分享的文件&#xff1a;Acunetix_15.2.221208162_www.ddosi.org.zip 链接: https://pan.baidu.com/s/1FPFFr583FFFj6hxWB-Ygng?pwdjpim 提取码: jpim 下载后文件是&#xff1a; 解压之后&#xff0c;如下图&#xff1a; 安装步骤如…

pycharm安装教程-PyCharm2023安装详细步骤【MAC版】【安装包自取】

pycharm安装教程-PyCharm2025安装详细步骤【MAC版】安装安装包获取&#xff08;文章末尾&#xff09;今天来给大家分享 Mac 系统安装 PyCharm&#xff0c;附带安装包资源安装&#xff0c; PyCharm 相关就不叙述了&#xff0c;直接开始安装&#xff01; 安装 2024版本、2025年…