前端代码更新后,如何通知客户进行刷新?思路其实很简单,只需要对比本地和服务端的版本信息
或者commitHash
等信息即可,如果本地和服务端的不同,则表示有代码更新,提示客户进行刷新即可。
话是这么说,但怎样搞呢?
1、本地生成一个version.json
的文件,包含version
、commitHash
等信息即可;
2、初始化加载时候,本地存储
需要对比的信息;
3、定时请求服务端 version 信息
,如果不同,则提示刷新;
思路是不是很简单,不瞎BB了,让我们实际梭一把;
1、生成一个version.json
文件的具体实现方法有好多,我这里使用的是在build
时候添加一个plugin
生成版本信息的响应文件。
// plugin/index.ts
class UpdateVersion {
static defaultOptions = {
outputFile: 'version.json'
}
constructor(options={}) {
this.options = { ...UpdateVersion.defaultOptions, ...options }
}
apply(compiler) {
const pluginName = UpdateVersion.name
const { webpack } = compiler
const { Compilation } = webpack
const { RawSource } = webpack.sources
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
compilation.hooks.processAssets.tap({ name: pluginName, stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE}, () => {
const content = JSON.stringify({
version: this.options.version,
commitHash: this.options.commitHash
})
console.log(content)
compilation.emitAsset( this.options.outputFile, new RawSource(content) );
})
})
}
}
module.exports = UpdateVersion
// craco.config.js
const { GitRevisionPlugin } = require('git-revision-webpack-plugin');
const version = require('./package.json').version
const UpdateVersion = require('./plugin/index.js')
const gitRevision = new GitRevisionPlugin()
module.exports = {
...,
webpack: {
...,
configure: (config, { env }) => {
...,
config.plugins.push(
new UpdateVersion({
version: version,
commitHash: gitRevision.commithash()
})
)
})
}
}
2、获取版本信息可以有多种方式,我这里使用web-worker
,不会影响主线程操作; dome
worker
默认支持 fetch
// worker.js 核心代码
fetch(`${location.origin}/version.json`, {
mode: "no-cors",
method: "GET",
headers: {
"Accept": "application/json"
}
}).then(res => res.json())
.then(res => {
const versionData = res
this.postMessage(JSON.stringify(versionData))
})
3、版本信息对比及提示
// index.tsx 核心代码
useEffect(() => {
const worker = workers() as Worker
worker.postMessage(JSON.stringify('version'))
worker.onmessage = ({ data }) => {
const resData = JSON.parse(data)
const version = resData.version
const localVersion = localStorage.getItem('version')
if (!localVersion) {
localStorage.setItem('version', version)
} else if (version !== localVersion) {
console.log('版本更新')
localStorage.setItem('version', version)
}
}
return () => {
localStorage.removeItem('version')
worker.terminate()
}
}, [])