实现原理
- 生成版本信息 JSON 文件
- 使用 Node.js 脚本获取
package.json
中的版本信息,并保存为versionInfo.json
文件,存放在构建打包目录下(如public
目录)。
- 使用 Node.js 脚本获取
- 监听页面显示和隐藏
- 监听
visibilitychange
事件。当页面显示时,请求dist
根目录下的versionInfo.json
文件,对比当前版本与历史版本是否一致。如果不一致,则刷新浏览器。
- 监听
- 环境变量配置
- Vite 打包项目使用
.env
文件与import.meta.env
保存当前打包变量。Webpack 项目则使用definePlugin
插件与process.env
。
- Vite 打包项目使用
Node.js 脚本实现
import { execSync } from 'child_process'; // 子进程 execSync 执行命令
import fs from 'fs';
import dotenv from 'dotenv'; // 加载 .env 文件中的环境变量
import dayjs from 'dayjs';const versionInfoPath = 'versionInfo.json'; // 版本信息路径
const pagePath = 'package.json';
const publicPath = 'public'; // 存放于 public 目录
const autoPush = false; // 是否自动提交 Git
const isVite = true; // 是否使用 Vite 构建let pageInfo = {};
let versionInfoObj = {}; // 存储版本信息// 读取现有版本信息
if (fs.existsSync(versionInfoPath)) {versionInfoObj = JSON.parse(fs.readFileSync(versionInfoPath).toString());
}// 读取 package.json 中的版本号
if (fs.existsSync(pagePath)) {pageInfo = JSON.parse(fs.readFileSync(pagePath).toString());
}// 判断版本是否已存在
if (pageInfo && versionInfoObj.version === pageInfo.version) {console.warn('警告: 当前版本信息已存在!\n');
} else {versionInfoObj = {version: pageInfo.version,name: pageInfo.name,date: dayjs().format('YYYY-MM-DD HH:mm:ss'),};fs.writeFileSync(versionInfoPath, JSON.stringify(versionInfoObj, null, 2));console.log(`执行成功: 文件地址为 ${process.cwd()}/${versionInfoPath}\n`);
}// 将 versionInfo 文件移至 public 目录
if (fs.existsSync(publicPath)) {fs.writeFileSync(`${process.cwd()}/${publicPath}/${versionInfoPath}`, fs.readFileSync(versionInfoPath));
}// 更新 .env 文件中的 VITE_GIT_INFO 变量
if (isVite) {const envPath = `${process.cwd()}/.env`;const envContent = fs.readFileSync(envPath, { encoding: 'utf-8' });const envVariables = dotenv.parse(envContent);envVariables.VITE_GIT_INFO = JSON.stringify(versionInfoObj);const updatedEnvContent = Object.entries(envVariables).map(([key, value]) => `${key}=${value}`).join('\n');fs.writeFileSync(envPath, updatedEnvContent, { encoding: 'utf-8' });console.log('.env 文件已更新');
}
配置脚本命令
在 package.json
中添加以下脚本:
"scripts": {"build:git": "npm run get-git && vite build","get-git": "node scripts/useNodeGetGitInfo.js"
}
监听 visibilitychange
事件
在项目入口 JS 文件中,添加以下代码以自动刷新页面:
const gitInfo = import.meta.env.VITE_GIT_INFO;
const gitInfoObj = gitInfo && JSON.parse(gitInfo);if (document.visibilityState === 'hidden') return;fetch(`/versionInfo.json?v=${Date.now()}`).then(res => res.json()).then(data => {if (data.version !== gitInfoObj.version) {location.reload();}});