• 基于node.js自动写入版本号解决前端vue或webpack项目因分包发版引起的报错问题


    场景

    本文所讲的解决方案的使用场景为常规vue项目,由于项目功能比较复杂导致主包功能过大,页面首次加载非常缓慢,后期对业务代码进行了分包处理,项目入口文件禁用了文件缓存,html/js文件都是动态更新的。

    问题

    但此后测试组很快就发现了下面的诡异的vue-router路由跳转失灵,或者按钮无法触发click事件等一系列诡异问题,控制台显示只是语法报错(Uncaught SyntaxError : Unexpected token <)问题,之所以说诡异是因为,一般都会先排业务代码和第三方库有没有问题,结果是并不存在,而且也不是100%可以复现。

    问题分析

    后来经同事跟进分析发现复现问题时与发版有关,基于此继续分析才发现是因为业务代码分包,发版之后服务端代码更新了,如果有人在发版前打开过页面,那么他就会碰到前面的问题,这主要是因为某些业务代码更新后,分包也会随之更新,而已经打开的页面使用的分包链接还是未发版的路径,出现代码块丢失所致。

    解决方案

    找到问题的原因,基本上就算解决了问题的一半,后面我同事给出的解决方案就是在项目的/public下定义一个包含版本信息的version.json文件:

    //----  路径:/public/version.json ----
    
    {"code":"0","version":"10.1.41"}
    
    • 1
    • 2
    • 3

    然后在路由拦截中每次调用前获取一次实时的版本信息,对比上一次版本和当前版本是否一致,不一致就缓存新版本新并重载当前页面,相当于强制刷新了,这样就解决了上面的问题(个人觉得这个方案不是最优的,应该有更好的办法,不过不是本文要讲的内容)。

    但这里有个麻烦的问题,就是版本号需要手动维护,显然这不符合程序员的风格,因此我就基于node.js对其做了优化,使得每次发版自动更新版本信息,这样就避免了发版时很容易遗忘改版本问题。因为是自动生成json,版本号也改成了日期时间,这样更简单明了。

    优化思路是,先读取/public/version.json文件,解析成对象,这样我们就获取到了版本信息,然后用moment.js获取当前日期时间(这里需要注意需要npm install moment --save安装moment包),更新版本信息并重新写入/public/version.json
    那么我们该在什么时候执行呢,当然是npm run build之前啦,需要修改package.json下的script配置:

    //---- 文件路径:/package.json ----
    
      "scripts": {
        "serve": "vue-cli-service serve",
        "dev": "vue-cli-service serve --mode development",
        "test": "vue-cli-service serve --mode test",
        "prod": "vue-cli-service serve --mode prod",
        "build": "node ./src/updateVersion.js && vue-cli-service build --mode prod",
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    //---- 文件路径:/src/updateVersion.js ----
    
    const moment = require('moment');
    const fs = require('fs');
    
    // 初始化数据
    const fileName = './public/version.json'
    const datetime = moment().format('YYYY-MM-DD HH:mm:ss')
    const defaultVersion = {code: '0', version: '1.0.0', updateTime: datetime}
    
    // 更新版本信息
    updateVersion()
    
    // 更新版本信息
    function updateVersion() {
    	console.log('-> 开始更新版本信息'.red, datetime);
    	
    	try {
    		const content = fs.readFileSync(fileName, 'utf-8');
    		let version = JSON.parse(content)
    		console.log(`-> 读取 version.json 成功!`);
    		version.updateTime = datetime
    		
    		// 更新版本信息
    		writeJson(version)
    		
    	} catch (err) {
    		console.log(`-> 读取 version.json 失败!`);
    		
    		// 写入默认版本信息
    		console.log(`-> 尝试写入默认数据!`);
    		writeJson(defaultVersion)
    	}
    	
    	// 辅助提示信息
    	console.log('... ...');
    	console.log('-------> Over <-------');
    }
    
    
    // 写入json文件
    function writeJson(version) {
    	try {
    		console.log(`-> 正在写入文件: `, fileName);
    		const write = fs.writeFileSync(fileName, JSON.stringify(version), {flag:'w+',encoding:'utf-8'});
    		console.log(`-> 写入 version.json 成功`);
    	} catch (err) {
    		console.log(`-> 写入 version.json 失败: `, err);
    		throw err;
    	}
    }
    
    
    
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
  • 相关阅读:
    upload-labs靶场详解
    基于Java毕业设计弹幕视频网站源码+系统+mysql+lw文档+部署软件
    【工具 & 技巧 & 笔试】PyCharm搜索快捷键大总结 | 【笔试题分享】2023美团算法策略方向题目 解析思路及实例代码(含时间复杂度分析)| 动态规划 求解:人在地图中行走 获得最大金币数量
    sql 注入(2), 文件读写 木马植入 远程控制
    软件测试面试常常遇到的6大“套路”!
    解读 | 自动驾驶系统中的多视点三维目标检测网络
    企业的固定资产管理怎么操作
    由粒子加速器产生的反中子形成的白洞
    JAVA ----- Map 集合
    剖析 Kubernetes 控制器:Deployment、ReplicaSet 和 StatefulSet 的功能与应用场景
  • 原文地址:https://blog.csdn.net/gaoshanliushui131/article/details/126047935