Implementing Frontend Version Update Detection with Git Revision Plugin and Webpack
This article explains how to detect frontend deployment changes and prompt users to refresh by generating a git‑hash JSON file with git‑revision‑webpack‑plugin, creating Vue mixins for version checking, and comparing hashed filenames in the built index.html, covering three practical solutions with their pros and cons.
Introduction
Frontend projects often face the issue where updated features are not displayed immediately after deployment, requiring users to manually refresh the page, which leads to a poor experience, especially for remote clients.
Technologies Involved
Vue, Webpack, JavaScript, and related tooling.
Problem Analysis
The core of the problem is detecting changes in deployed files. Both frontend and backend can monitor version updates; the frontend can compare the current build's hash with the previous one and trigger a refresh or notification when they differ.
Solution 1: Generate a git‑hash JSON File
Use git-revision-webpack-plugin to embed the git commit hash and version into a version.json file during the Webpack build.
npm install git-revision-webpack-plugin --save-dev const GitRevisionPlugin = require('git-revision-webpack-plugin');
const gitRevisionPlugin = new GitRevisionPlugin(); plugins: [
new GitRevisionPlugin(),
{
apply: (compiler) => {
compiler.plugin('emit', (compilation, callback) => {
const version = gitRevisionPlugin.version();
const hashCommit = gitRevisionPlugin.commithash();
const versionInfo = { version, hashcommit };
compilation.assets['version.json'] = {
source: () => JSON.stringify(versionInfo, null, 2),
size: () => JSON.stringify(versionInfo).length,
};
callback();
});
},
},
];The generated version.json looks like:
{
"version": "Afmos3.00.1-alpha-176-ge10504cc",
"hashcommit": "e10504cc8e9dd629685713f1d2a57322ab5b48c5"
}In Vue, create a mixin hashVersion.js that fetches this file, compares the stored hash, and shows a notification when a new version is detected.
export const hashVersionMixins = {
data() {
return {
current_hash: localStorage.getItem('location_hash') || '',
new_hash: ''
};
},
created() {
this.checkVersion();
},
methods: {
async checkVersion() {
try {
const res = await this.$http.get('/version.json?date=' + Date.now());
this.new_hash = res.data.hashcommit;
if (this.new_hash !== this.current_hash) {
localStorage.setItem('location_hash', this.new_hash);
this.$notify({
title: 'Afmos System Reminder',
message: 'A new version is available, please refresh the page.',
type: 'success'
});
}
} catch (error) {
console.error('Failed to fetch version info:', error);
}
}
}
};Optionally, automatically reload after a delay:
setTimeout(() => {
window.location.reload();
}, 5000); // reload after 5 secondsInclude the mixin in the root App component:
import { hashVersionMixins } from '@/mixins/hashVersion';
export default {
mixins: [hashVersionMixins]
};Pros and Cons of Solution 1
All work is done on the frontend, increasing developer learning but adding some overhead.
Backend may need to serve static files correctly; otherwise the JSON file might not be reachable.
If only the backend changes without a new frontend build, the hash remains unchanged.
Solution 2: Record Update Log and Expose Version via API
Maintain a changelog (e.g., in README) and provide an endpoint that returns the latest version number. The frontend periodically requests this API and notifies the user when a newer version appears.
<script>
import { softVersion } from '@/request/api/information';
export default {
data() { return { version_num: localStorage.getItem('version_num') || '' }; },
methods: {
async getVersion() {
const res = await softVersion({});
if (res.result) {
const new_version = res.data[0].version_num;
if (new_version !== this.version_num) {
localStorage.setItem('version_num', new_version);
this.$notify({ title: 'Afmos System Reminder', message: 'A new version is available, please refresh.', type: 'success' });
}
} else {
this.$message.error(res.msg);
}
}
}
};
</script>Pros and Cons of Solution 2
Works for both frontend and backend updates, ensuring timely version awareness.
Requires coordination among multiple teams and explicit requirement documentation.
Solution 3: Compare Hashes of Built JS Files in index.html
Configure Webpack to emit files with content hashes (e.g., [name].[contenthash].js ). On page load, fetch the latest index.html , extract the JS filenames, compare their hashes with those stored in localStorage , and prompt a refresh if they differ.
module.exports = {
output: {
filename: '[name].[contenthash].js', // ensure hash in filename
path: path.resolve(__dirname, 'dist')
}
}; function extractHashFromHtml(htmlContent) {
const scriptRegex = /
]*src="([^"]+\.js)"/g;
const hashes = [];
let match;
while ((match = scriptRegex.exec(htmlContent)) !== null) {
const scriptSrc = match[1];
const hashMatch = scriptSrc.match(/(\w+)\.js$/);
if (hashMatch) {
hashes.push(hashMatch[1]);
}
}
return hashes;
}
function checkForUpdates() {
fetch('/index.html', { cache: 'no-store' })
.then(response => response.text())
.then(htmlContent => {
const newHashes = extractHashFromHtml(htmlContent);
const oldHashes = JSON.parse(localStorage.getItem('appHashes')) || [];
if (JSON.stringify(newHashes) !== JSON.stringify(oldHashes)) {
alert('A new version has been released, please refresh the page!');
localStorage.setItem('appHashes', JSON.stringify(newHashes));
}
})
.catch(error => console.error('Error fetching index.html:', error));
}
window.addEventListener('load', checkForUpdates);Conclusion
The article demonstrates three practical ways to detect frontend version changes using Webpack configuration, Node utilities, and Vue mixins, highlighting the trade‑offs between pure frontend solutions, API‑driven approaches, and hash‑comparison techniques.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.