记录---前端部署后自动提醒用户更新
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
前言
前端项目经常碰到更新部署了,但是更新过的功能并没有及时的展示,还需要刷新一下页面,才能看到最新的内容。如果是远程给客户进行的部署,还要口头告知客户需要刷新,体验不友好。
技术涉及
vue、webpack、js等。
问题思考
想要解决整个问题的关键点在于,检测部署文件的变化。部署文件的变化,前后端都可以做,或者配合一起来完成。纯前端实现的话,就是需要前端自己打包文件的变更进行一个变动检测,如果当前文件与上次部署文件发生变化,那么就得提醒需要刷新,或者自动刷新。前端文件变化,主要在打包后的js、css、以及html的文件变化。而后端的话,主要是记录更新日志记录,检测到版本更新日志变化,那么就得告知前端个进行更新,这里主要通过接口的形式告知版本信息,前端根据接口信息进行更新。
实现方案
方案一:生成git提交的hash信息json文件,请求本地json文件获取更新信息
在项目中一直使用插件git-revision-webpack-plugin,记录前端项目的git提交信息,以便于运维人员进行版本比对和维护。
安装依赖
1 | npm install git-revision-webpack-plugin --save-dev |
webpack主要打包配置中引入git-revision-webpack-plugin插件
1 2 3 | 引入GitRevisionPlugin const GitRevisionPlugin = require( 'git-revision-webpack-plugin' ) const gitRevisionPlugin = new GitRevisionPlugin() |
webpack插件配置plugins以及生成version.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | plugins: [ // 配插件 new GitRevisionPlugin(), // 在dist或者自定义的打包输出目录下生成包含 hash 的json { apply: (compiler) => { compiler.plugin( 'emit' , (compilation, callback) => { // 获取 Git 版本和哈希 const version = gitRevisionPlugin.version(); const hashCommit = gitRevisionPlugin.commithash(); const versionInfo = { version, hashcommit, }; // 将 version.json 文件添加到 compilation.assets 中 compilation.assets[ 'version.json' ] = { source : () => JSON.stringify(versionInfo, null, 2), // 文件内容 size: () => JSON.stringify(versionInfo).length, // 文件大小 }; // 确保回调函数被调用,通知 Webpack 继续处理 callback(); }); }, }, ] |
在这里要注意两点:一是apply中compiler的写法,比如在高版本中使用compiler.hooks.emit
。emit参数的意思是生成打包文件时,当然还有其他一些周期性参数,可以查看webpack官方文档。二是js将对象versionInfo转成json文件。
version.json文件内容
1 2 3 4 | { "version" : "Afmos3.00.1-alpha-176-ge10504cc" , "hashcommit" : "e10504cc8e9dd629685713f1d2a57322ab5b48c5" } |
打包成功后截图示例
写一个mixins来监听版本文件变化
利用vue的mixins混淆功能,创建一个自定义的hashVersion.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | export const hashVersionMixins = { data () { return { current_hash: localStorage.getItem( 'location_hash' ) || '' , new_hash: '' } }, created () { this.checkVersion() }, methods: { async checkVersion () { try { const res = await this.$http.get( '/version.json?date=' + Date.now()) this.new_hash = res.data.hashcommit if (this.new_hash !== this.current_hash) { localStorage.setItem( 'location_hash' , this.new_hash) this.$notify({ title: 'Afmos系统提醒' , message: '有新版本更新啦~请刷新页面查看最新内容' , type : 'success' }) } } catch (error) { console.error( '获取版本信息失败:' , error) } } } } |
在这里只做了一个弹框信息提醒,当然也可以根据实际需求进行直接刷新或者定时器之后再刷新。
1 2 3 | setTimeout(() => { window.location.reload(); }, 5000); // 5秒后自动刷新页面 |
1 2 3 4 5 | import { hashVersionMixins } from '@/mixins/hashVersion' export default { mixins:[hashVersionMixins], } |
方案一更新提醒截图
优缺点:
- 全部在前端做工作量多了一些,但是对自己也是一种学习和进步。
- 后端可能需要配置静态文件指定路径,比如在python环境中指定了静态文件static,此时前端的version.json与index同级,会拿不到文件,要再次将文件移到前端的static下。或者在webpack打包配置中,直接写入到static中。
- 只更新了后端部分,前端文件不更新的话,hash值也没有改变。
方案二:记录更新日志,通过接口返回更新版本号
每个项目进行更新,都会有更新记录,比如每次更新,会把本次更新的内容记录到readme中,方便其他人员查看。在发布部署时也需要记录当前更新的内容。在这就可以做一个版本号管理和更新记录。再暴露出一个方法,进行查询记录。
前端通过接口获取版本号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <script> import { softVersion } from '@/request/api/information' export default { data () { version_num:localStorage.getItem( 'version_num' ) || '' } } methods:{ async getVersion() { const res = await softVersion({}) if (res.result) { const new_version = res.data[0].version_num if (new_version !== this.version_num) { localStorage.setItem( 'version_num' , this.new_version) this.$notify({ title: 'Afmos系统提醒' , message: '有新版本更新啦~请刷新页面查看最新内容' , type : 'success' }) } } else { this.$message.error(res.msg); } } } < /script > |
优缺点:
- 无论前后端更新都能及时的获取到更新的版本和信息
- 工作量问题,以及方案的实施需要多方人员配合。毕竟有的人呀,只要是没有领导说明和写在需求里面的,那就是不知道,不清楚,我不做,压根不会去给自己增加额外的工作量。
方案三:比对前端打包后的index.html中js中文件名hash值
Webpack 配置确保生成带 hash 的文件
确保 Webpack 配置中开启了带有内容hash值的文件名输出,这样在每次打包时,如果文件内容发生变化,生成的js文件名会带上新的hash值。
1 2 3 4 5 6 7 | module.exports = { output: { filename: '[name].[contenthash].js' , // 确保文件名带有 hash path: path.resolve(__dirname, 'dist' ), }, // 其他配置... }; |
构建前端 hash 值提取功能
首先,需要在打包后提取出 index.html
中的 JS 文件 hash 值。通常,Vue 项目通过 Webpack 打包时,生成的 JS 文件名会带有 hash 值(例如:app.123abc456.js
)。我们可以通过正则表达式从 index.html
中提取这些 hash 值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 假设是通过 AJAX 请求或 fetch 方式来获取 index.html function extractHashFromHtml(htmlContent) { const scriptRegex = /<script\s+[^>]*src= "([^" ]+\.js)" /g ; const hashes = []; let match; while ((match = scriptRegex. exec (htmlContent)) !== null) { const scriptSrc = match[1]; const hashMatch = scriptSrc.match(/(\w+)\.js$/); if (hashMatch) { hashes.push(hashMatch[1]); } } return hashes; } |
保存和比较 hash 值
每次加载应用时,将当前页面的 hash 值与之前保存的 hash 值进行比对。如果 hash 值发生变化,则表明前端文件已更新,可以提示用户刷新页面。你可以将 hash 值存储在 localStorage
中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function checkForUpdates() { fetch( '/index.html' , { cache: 'no-store' }) // 确保获取的是最新的 index.html . then (response => response.text()) . then (htmlContent => { const newHashes = extractHashFromHtml(htmlContent); const oldHashes = JSON.parse(localStorage.getItem( 'appHashes' )) || []; // 比较 hash 值 if (JSON.stringify(newHashes) !== JSON.stringify(oldHashes)) { // 如果有变化,提示用户 alert( '新版本已经发布,请刷新页面以获取最新内容!' ); // 更新存储的 hash 值 localStorage.setItem( 'appHashes' , JSON.stringify(newHashes)); } }) .catch(error => console.error( 'Error fetching index.html:' , error)); } // 页面加载时检查更新 window.addEventListener( 'load' , checkForUpdates); |
总结
这里涉及到了webpack的配置和node的一些内容。webpack依赖node的环境,所以在webpcak的配置中就能使用node中自带的fs以及path,在指定的地方输出或者生成我们需要的内容信息。
本文转载于:https://juejin.cn/post/7428793777984208896
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
__EOF__
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 从 Windows Forms 到微服务的经验教训
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
2023-02-13 记录--数组去重的五种方法