1、问题描述
前端项目打包到生产环境,用户在页面操作时会出现页面报错,无法加载动态资源的错误,但是刷新一下就可以了
2、原因
因为版本更新导致客户端与最新的版本不一致,存在资源未更新的情况,用户在使用的过程中停留在某个页面,没有刷新重新获取资源,就会导致报错
3、解决方法(纯前端,目前来说比较简单的解决方法)
解决思路:通过调用fs库的方法在打包时创建version.json保存版本号,同时在localStorage存储版本号信息,通过对比版本号是否一致强制刷新页面,获取最新的资源防止报错。
第一步:在根目录下创建build文件夹和build.js文件
第二步:在build.js中添加以下代码
// console.log("build---->文件开始执行!");import fs from "fs";import path from "path";function getRootPath(...dir) { return path.resolve(process.cwd(), ...dir);}const runBuild = async () => { try { const OUTPUT_DIR = "dist"; const VERSION = "version.json"; const versionJson = { version: "V_" + Math.floor(Math.random() * 10000) + Date.now(), }; fs.writeFileSync( getRootPath(`${OUTPUT_DIR}/${VERSION}`), JSON.stringify(versionJson) ); // console.log(`version file is build successfully!`); } catch (error) { // console.error("version build error:\n" + error); process.exit(1); }};runBuild();// console.log("build---->文件执行结束!");
第三步:src/router/index.ts 在路由中添加跳转前的判断
注意:添加import.meta.env.VITE_ENV === "PRODUCTION"判断是否为生产环境,开发环境不需要刷新获取资源,登录页也不需要,注意排除,否则会导致用户停留在登录页时,会造成重复登录
import axios from "axios";router.beforeEach((to, from, next) => { ... if (from.path !== "/" && import.meta.env.VITE_ENV === "PRODUCTION") { checkAppNewVersion(); } ...});// 监听页面打开显示document.addEventListener("visibilitychange", function () { if (!document.hidden) { if (import.meta.env.VITE_ENV === "PRODUCTION") { checkAppNewVersion(); } }});// 检查服务端是否已经更新,如果更新刷新页面async function checkAppNewVersion() { const url = `/version.json?t=${Date.now()}`; let res = null; try { res = await axios.get(url); } catch (err) { console.error("checkAppNewVersion error: ", err); } if (!res) return; const version = res.data.version; if (version && version !== localStorage.getItem("version")) { localStorage.setItem("version", version); window.location.reload(); } localStorage.setItem("version", version);}
第四步:package.json 配置打包时执行build.js文件
"type": "module", "scripts": { "dev": "-----", "build": "vite build && node ./build/build.js", "preview": "------" },
第五步:准备摸鱼