当前位置: 首页 > news >正文

谷歌V3插件热更新

项目配置

vue-cli构建,vue3+webpage+谷歌插件V3

实现方法

SSE链接+本地的HMR服务

使用到的依赖

  • express(搭建本地 HTTP 服务,处理 SSE 连接)
  • cors(允许前端页面跨域访问本地 HMR 服务)
  • eventemitter3(实现服务端事件推送和监听)

代码实现

实现SSE

// sse.js 文件路径:最外层const express = require('express') // 引入 express,用于创建 HTTP 服务
const cors = require('cors') // 引入 cors,允许跨域请求
const EventEmitter = require('eventemitter3') // 引入 eventemitter3,用于事件管理和消息推送
const pkg = require('./package.json') // 引入 package.json,用于日志输出项目名// 工厂函数:创建 SSE 服务
exports.createSSE = (option) => {const { port, isWatch } = optionlet emitter = new EventEmitter(); // 创建事件管理器if (!isWatch) return { send: () => {}} // 非 watch 模式返回空 send 方法const app = express()app.use(cors()); // 启用跨域// 监听 /hmr 路径,建立 SSE 连接app.get('/hmr', (_, res) => {console.log(`\x1B[32m[${pkg.name}]\x1B[0m client connected.`);res.set({'Content-Type': 'text/event-stream', // SSE 必须的响应头'Cache-Control': 'no-cache','X-Accel-Buffering': 'no',});// 当有 hmr 事件时,向客户端推送消息emitter.on('hmr', (data) => {res.write(`data: ${JSON.stringify({ type: 'hmr', data })}\n\n`);})})// 启动服务,监听指定端口app.listen(Number(port), () => {console.log('启动成功')})// 返回 send 方法,触发 hmr 事件,推送消息给所有客户端return {send: (data) => emitter.emit('hmr', data)}
}

在vue.config.js中引入sse.js文件,创建SSE协议并自定义插件,在webpack的afterEmit钩子(即所有文件输出到磁盘后)用SSE向前端发送消息

// vue.config.jsconst { createSSE } = require('./sse')
const isWatch = process.argv.includes('--watch')
const sse = createSSE({ port: process.env.PORT, isWatch })chainWebpack: (config) => {config.plugin('custom-plugin').use({apply: (compiler)=>{compiler.hooks.afterEmit.tap('CustomPlugin',(state)=>see.send())}})
})

构建热更新处理函数

// hmr.js// 热更新处理函数,env 表示当前环境(background 或 contentScript)
async function onHMR (env) {// 仅在开发环境下启用if (process.env.NODE_ENV !== "development") return// 获取扩展的 manifest 信息const pgk = await fetch(chrome.runtime.getURL('manifest.json')).then(res => res.json())// 控制台输出连接建立提示console.log(`%c【${pgk.name}】已建立连接`,"color: white; background-color: green; padding: 2px 6px; border-radius: 2px; font-weight: bold;");// 连接本地 HMR 服务const source = new EventSource('http://localhost:3000/hmr');source.addEventListener('message', () => {// 如果是 background 环境,重载扩展if (env === 'background') {chrome.runtime.reload()}// 如果是 contentScript 环境,刷新页面if (env === 'contentScript') {location.reload();}});
}// 启动 background 环境的 HMR
onHMR('background')// 监听页面标签更新事件
chrome.tabs.onUpdated.addListener(async function (tabId, changeInfo, tab) {// 当页面加载完成且有 URL 时if (changeInfo.status === 'complete' && tab.url) {// 获取扩展的 manifest 信息const pgk = await fetch(chrome.runtime.getURL('manifest.json')).then(res => res.json())// 获取 content_scripts 的匹配规则const matches = pgk.content_scripts[0].matches// 判断当前标签页的 URL 是否匹配 content_scripts 规则const ismatch = matches.some(url => tab.url.includes(url.replace('*', '')))if (ismatch) {// 在匹配的标签页注入 HMR 脚本chrome.scripting.executeScript({target: { tabId },func: onHMR,args: ['contentScript']});}}
});

将热更新处理还是引入到background.js

// background.jsimport './hmr.js'

结语

在本地构建SSE协议,通过在webpage中注入自定义插件,在修改页面触发本地热更新重新打包后,向客户端发送SSE,客户端通过在页面嵌入js代码,启用监听SSE的message,如果是backgournd环境就chrome.runtime.reload()重载插件,如果是页面就location.reload()

其他

  1. 关于SSE
    严格地说,HTTP 协议无法做到服务器主动推送信息。但是,有一种变通方法,就是服务器向客户端声明,接下来要发送的是流信息(streaming)。
    也就是说,发送的不是一次性的数据包,而是一个数据流,会连续不断地发送过来。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。本质上,这种通信就是以流信息的方式,完成一次用时很长的下载。
    SSE 就是利用这种机制,使用流信息向浏览器推送信息。它基于 HTTP 协议,目前除了 IE/Edge,其他浏览器都支持。
  2. new EventSource(url)
    是浏览器提供的 Server-Sent Events (SSE) API,用于创建一个到服务器的单向实时连接。
http://www.dtcms.com/a/308975.html

相关文章:

  • 类与对象(上),咕咕咕
  • 【Node】nvm在windows系统无管理员权限切换node版本
  • 20250731在荣品的PRO-RK3566开发板的Android13下跑通敦泰的FT8206触控芯片
  • 【Java EE初阶 --- 网络原理】网络层---IP协议,数据链路层---以太网协议
  • OpenCV学习day2
  • YodA数据集的格式化(二)
  • MySQL 8.0 OCP 1Z0-908 题目解析(39)
  • 项目中如何追踪项目进度,避免项目延期如何追踪项目进度
  • 尚硅谷尚庭公寓学习笔记
  • 《P2910 [USACO08OPEN] Clear And Present Danger S》
  • JVM之【Java虚拟机概述】
  • uniapp中uview组件中u-input格式化后赋值踩坑
  • 网站技术攻坚与Bug围剿手记
  • nodejs——在Express中使用Session认证
  • 基于 AXI-Lite 实现可扩展的硬件函数 RPC 框架(附完整源码)
  • graph attention network
  • Sklearn 机器学习 文本数据 计数向量化加入停用词
  • Spring Boot 项目问题:Web server failed to start. Port 5566 was already in use.
  • Linux应用开发基础知识——Makefile初级教程(九)
  • 订单识别与发票识别结合的技术实现方案
  • 最新PS 2025安装包下载与安装教程(Adobe Photoshop 2025 )
  • Java客户端连接Redis
  • langchain--2--invoke、batch、stream、ainvoke、abatch、astream
  • 51c自动驾驶~合集12
  • Python脚本批量将usdz文件转为glb文件
  • 智能体通信协议
  • C++(模板,智能指针)
  • 什么是数据集成?和数据融合有什么区别?
  • Video_1920×1080i 1920_1080p
  • 7月31日作业