使用nodejs脚本生成版本信息json文件 + 监听页面显示和隐藏会触发的visibilitychange
(页面显示和隐藏)事件(可以随意使用各种监听方式)
实现原理:
1、使用nodejs编写脚本,获取package.json版本信息,并保存为json文件,存放在构建打包的目录下(比如,public目录)
2、使用页面显示和隐藏会触发的visibilitychange
事件,监听页面的显示和隐藏操作,如果页面显示,则请求打包放在dist根目录下的版本信息json文件,对比当前打包版本的version
与历史版本信息json文件中version
是否一致,如果不一致,则触发浏览器刷新
3、vite打包项目使用.env
文件 + import.meta.env
保存当前打包变量(webpack打包项目可以使用definePlugin
插件 + process.env
保存变量)
1、使用nodejs编写获取package.json版本信息的脚本
import { execSync } from 'child_process' // 子进程 execSync 要运行的命令
import fs from 'fs'
import dotenv from 'dotenv' // .env文件中加载环境变量 然后将这些环境变量加载到process.env对象中
import dayjs from 'dayjs'
/** 定义模块和变量**/
const versionInfoPath = 'versionInfo.json' // versionInfo路径
const pagePath = 'package.json'
const publicPath = 'public' // 不能放到dist目录(该目录打包文件会被清空),要放到public目录,
const autoPush = false // 写入版本信息之后是否自动提交git上
const isVite = true // 是否是vite构建打包
let pageInfo = {}
let versionInfoObj = {} // 保存git版本信息
// 如果versionInfoPath存在,将先读取里边的版本信息
if (fs.existsSync(versionInfoPath)) {
versionInfoObj = JSON.parse(fs.readFileSync(versionInfoPath).toString())
}
// 获取package.pack 的版本号
if (fs.existsSync(pagePath)) {
pageInfo = JSON.parse(fs.readFileSync(pagePath).toString())
}
// 判断当前版本是否已经存在,存在则不再次生成
if (pageInfo && versionInfoObj.version === pageInfo.version) {
console.warn('\x1B[33m%s\x1b[0m', 'warning: 当前的git版本数据已经存在了!\n')
} else {
versionInfoObj = {
version: pageInfo.version,
name: pageInfo.name,
date: dayjs().format('YYYY-MM-DD HH:mm:ss'),
}
const saveInfoStr = JSON.stringify(versionInfoObj, null, 2)
fs.writeFileSync(versionInfoPath, saveInfoStr)
// 程序执行结束
console.log(
'\x1b[32m%s\x1b[0m',
`execute success: file address is ${process.cwd()}/${versionInfoPath}\n`,
)
}
// 将versionInfo文件移植到public文件中,以便构建工具能够正常打包到项目根目录
if (fs.existsSync(publicPath)) {
fs.writeFileSync(
`${process.cwd()}/${publicPath}/${versionInfoPath}`,
fs.readFileSync(versionInfoPath),
)
}
// 如果是vite构建打包,把git信息追加写入.env文件中
if (isVite) {
// const dotenv = require('dotenv')
const envPath = `${process.cwd()}/.env`
// 读取 .env 文件内容
const envContent = fs.readFileSync(envPath, {
encoding: 'utf-8',
})
// 解析内容为键值对对象
const envVariables = dotenv.parse(envContent)
const versionInfoStr = JSON.stringify(versionInfoObj)
// 修改特定的环境变量
envVariables.VITE_GIT_INFO = versionInfoStr
// 将修改后的键值对转换为字符串
const updatedEnvContent = Object.entries(envVariables)
.map(([key, value]) => `${key}=${value}`)
.join('\n')
// 将修改后的内容写入 .env 文件
console.log(updatedEnvContent)
fs.writeFileSync(envPath, updatedEnvContent, { encoding: 'utf-8' })
console.log('\x1b[32m%s\x1b[0m', '.env 文件已更新')
}
2、配置执行获取git版本信息脚本命令
// package.json
"scripts": {
"build:git": "npm run get-git && vite build",
"get-git": "node scripts/useNodeGetGitInfo.js",
},
3、项目入口JS文件,监听visibilitychange
事件
// 检测新版本自动刷新浏览器更新版本内容
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) => {
return res.json()
})
.then((data) => {
// 版本不一致,可自动更新,或者提示弹框,让用户刷新,自行判断
if (data.version !== gitInfoObj.version) {
location.reload()
}
})