chrome 插件开发中的热更新问题
原文链接:github.com/lzwaiwai/bl…
1. chrome插件开发时,热更新不完全生效发现问题
在编写 chrome 插件开发模板 的时候,遇到了 webpack 的 热更新不完全生效 的问题。
不生效情景:
当 chrome 插件的 manifest.json 中的 background, content_scripts 被配置为 js 的形式时(如下),这些脚本必须在文件目录中存在(注意:background 的 scripts 和 content_scripts 的 js 两个属性是不能使用远程链接的)。
{"background": {"persistent": false,"scripts": ["background.js"]},"content_scripts": [{"matches": ["http://*/*", "https://*/*"],"js": ["content.js"],"all_frames": true}],} 复制代码
生效情景: 当 chrome 插件的 manifest.json 中的 background, popup 被配置为 html(js 在 html 中被以 远程链接 的形式引入) 的形式时(如下),
{"browser_action": {"default_popup": "pages/popup.html"},"background": {"persistent": false,"page": "pages/background.html"},} 复制代码
<!DOCTYPE html><html><head><meta charset="utf-8"><script src="http://127.0.0.1:3000/js/background.js"></script></head></html> 复制代码
<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body><div id="chrome-popup-root"></div><script src="http://127.0.0.1:3000/js/popup"></script></body></html> 复制代码
分析原因:
在配置 webpack 的热更新的时候,我们都会在 entry 配置如下配置: webpack-hot-middleware/client?path=http://127.0.0.1:3000/__webpack_hmr&noInfo=false&reload=true&quiet=false
然后开发过程中,我们会在 network 中发现很多 http://127.0.0.1:3000/__webpack_hmr/xxx 这样的网络请求,这些请求就是用来获取对应脚本的修改部分,并触发其发生热更新,最后局部进行重新渲染。所以这样的热更新只能支持远程链接配置的形式。这就是 chrome 插件开发时的热更新不完全生效的原因。
2. 解决开发chrome 插件过程中修改代码后自动重载的问题
上面我们提到 manifest.json 中的 background 的 scripts 和 content_scripts 的 js 两个属性是不能使用远程链接的,所以 webpack 的热更新并不适合 js 脚本配置的 chrome 插件开发。
而开发过 chrome 插件的同学都知道,对于使用本地脚本配置的方式,在修改了脚本后,需要去应用扩展后台手动更新插件,否则插件不会更新。(这里推荐另一个插件,可以重载其他当前正在开发的 chrome 插件:github.com/arikw/chrom…)
所以,这里就衍生出了开发 chrome 插件过程中修改代码后能否自动重载的问题。
我们逆向思考:要重载插件,需要获得代码的修改时机;要获得代码的修改时机,需要了解 webpack 在每次修改编译后如何通知到客户端。
于是继续衍生出以下几个问题:
- 如何获取 webpack 每次触发修改编译后的钩子
- 如何在 webpack 钩子回调中及时通知浏览器代码已更新
- 浏览器接受到修改通知后,如何更新重载插件和页面
我们一个一个来解决
1. 如何获取 webpack 每次触发修改编译后的钩子
查阅 webpack 文档我们可以找到如下方法:
const compiler = webpack(webpackConfig)
compiler.hooks.done.tap('name', () => {// todo
})
复制代码
2. 如何在 webpack 钩子回调中及时通知浏览器代码已更新
首先请详细看一下这几篇文章和源码:《Server-Sent Events》、《Webpack 热更新实现原理分析》、《EventSource client for Node.js and Browser (polyfill)》
SSE 就是一种由服务端直接将信息推送给客户端的单向通道,相比 websocket 则会更加轻量。
客户端:
if ('EventSource' in window) {const source = new EventSource(`http://localhost:3000/sse`)source.addEventListener('open', (event) => {console.log('Auto Reload Listen: ', event);}, false);source.addEventListener('compiled', (event) => { // 自定义事件console.log('compiled: ', event);// todo}, false);source.addEventListener('error', (event) => {console.log('error: ', event);}, false);}
复制代码
服务端:
const SseStream = require('ssestream');const compiler = webpack(webpackConfig);app.use('/sse', webpackChromeExtensionsReloadMiddleware(compiler));function webpackChromeExtensionsReloadMiddleware(compiler, opts = {}) {opts.heartbeat = opts.heartbeat || 5 * 1000;const middleware = function(req, res, next) {res.header('Access-Control-Allow-Origin', '*');const sseStream = new SseStream(req) // 构造 sse 的请求sseStream.pipe(res)if (compiler.hooks) {compiler.hooks.done.tap('webpack-chrome-extensions-reload-middleware', () => {sseStream.write({ // 请求数据event: 'compiled',data: 'compiled'})})}res.on('close', () => {console.log('close connection')sseStream.unpipe(res)})next();};return middleware;
}
复制代码
3. 浏览器如何接受到修改通知,并更新重载插件和页面
在 2 中客户端的 todo 中,我们在这里的回调里就可以实时监听到代码的改动,这里我们只需要执行如下代码即可。
chrome.runtime.reload();
复制代码
以上机制已被我之前编写的 vue 和 react 版本的 chrome 插件开发模板 中用到,欢迎围观~
转载于:https://juejin.im/post/5c05fc94518825170d1ad95e
chrome 插件开发中的热更新问题相关推荐
- 初学者学习 - Unity中的热更新 - Lua和C#通信
菜鸟学习 - Unity中的热更新 - Lua和C#通信 孙广东 2015-4-6 热更新我是个菜鸟,感谢网上的各位的奉献,这次又当一回搬运工. 准备: 1.了解Lua的语法 推荐书籍<Lua程 ...
- 菜鸟学习 - Unity中的热更新 - Lua和C#通信
孙广东 2015-4-6 热更新我是个菜鸟,感谢网上的各位的奉献,这次又当一回搬运工. 准备: 1.了解Lua的语法 推荐书籍<Lua程序设计 第二版> 2.使用ULua插件进行通信 尽量 ...
- Unity中的热更新 - Lua和C#通信
准备: 1.了解Lua的语法 推荐书籍<Lua程序设计 第二版> 2.使用ULua插件进行通信 尽量早上真机.因为Bug问题特别多. 大杂烩: 更新LUa其实也是更新资源. Lua被看作一 ...
- Python在游戏中的热更新
介绍: 热更新,就是在服务器不重启的的情况下,对游戏增加新的功能或者修复出现bug 的代码.游戏更新迭代速度快,催生了热更技术的需求,在我经历过的游戏项目中,无论是服务端还是客户端,版本的更新都是围绕 ...
- android中的热更新
热更新的流程 1.线上检测到严重的crash 2.拉出一个bugfix分支并在分支上修复问题 3.jenkins构建和补丁生成. 4.app通过推送或者主动拉取补丁文件 5.将bufix代码合并到ma ...
- Unity中的热更新的基础知识,Xlua与ILRuntime基础知识
1.什么是热更新 热更新是指在不需要重新编译打包游戏的情况下,在线更新游戏中的一些非核心代码和资源,比如活动运营和打补丁.热更新分为资源热更新和代码热更新两种,代码热更新实际上也是把代码当成资源的一种 ...
- python程序更新实现_Python 软件热更新
Python 软件热更新 本篇文章涉及技术知识如下: Redis threading 多线程 PyQt5 importlib 热更新 场景 咱们在平时运行一些长时间都会一直运行的软件(如:某些云同步软 ...
- Lua------------------unity与lua的热更新
[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新完全解读 标签: 游戏开发游戏解决方案用户体验unity3d 2014-10-18 23:23 7680人阅读 ...
- CodePush热更新组件详细接入教程
CodePush热更新组件详细接入教程 什么是CodePush CodePush是一个微软开发的云服务器.通过它,开发者可以直接在用户的设备上部署手机应用更新.CodePush相当于一个中心仓库,开发 ...
- C# 实现 rtc_通过Xlua实现unity热更新的一个小例子
通过Xlua实现unity热更新的一个小例子 一.介绍 热更新是指在更新游戏资源或者逻辑的时候不需要开发者将游戏再打包.发布.玩家重新下载安装包,而是可以通过将需要更新的资源打包成AssetBun ...
最新文章
- Metasploit log命令技巧
- office 2013 安装问题
- PL/SQL 数据库连接工具的下载、安装与使用实例演示
- js中当等于最小值是让代码不执行_网页中JS函数自动执行常用三种方法
- Windows 配置Apache+CGI
- 华为手机记事本导出_深夜浅谈怎样用一部手机做电影解说?
- 第 10 章 桥接模式
- postMessage可太有用了
- 思维模型 吸引力法则/定律
- 一个字形容大数据_中国大学校训大数据:最短的2个字,最长的28个字,10大高频汉字...
- IOS平台开发实战培训
- Fortran NINT函数意思
- 实物短缺下的现货白银操作建议
- unity3D-游戏/AR/VR在线就业班 C#入门访问修饰符学习笔记
- error: (-215:Assertion failed) !_src0.empty() in function ‘cv:: 可能的诸多原因!!!
- 如何做好服务器的维护
- C++ 不快乐的函数 1
- Java HMAC-SHA1加密算法的实现
- uniapp onReachBottom 触底事件
- 2022MathorCup赛题B