I have a VueJS app. Whenever I run npm run build
it creates a new set of dist/*
files, however, when I load them on the server (after deleting the
I serve a Nuxt app alongside a very lightweight Express app that handles server-side authentication and other things. My solution is to let Express store the current git hash in a cookie when a user logs in. This value is then placed in a Vuex store along with the current time (and other info about the current user).
On a route change, a router middleware checks how long it's been since we last compared the store' hash with the actual one. If it's been more than a minute, we request the current Hash from Express and force a server-side render for the current route if the value has changed.
Here's the relevant code:
server/index.js
const getRevision = function() {
return require('child_process')
.execSync('git rev-parse --short HEAD')
.toString()
.trim()
}
app.get(
'/login',
async function(req, res, next) {
// (log in the user)
const revision = getRevision()
res.cookie('x-revision', revision)
return res.redirect('/')
}
)
app.get(
'/revision',
function(req, res) {
const revision = getRevision()
return res.send(revision)
}
)
store/index.js
export const actions = {
nuxtServerInit({ dispatch }) {
const revisionHash = this.$cookies.get('x-revision')
dispatch('auth/storeRevision', revisionHash)
}
}
store/auth.js
export const state = () => ({
revision: { hash: null, checkedAt: null }
})
export const mutations = {
setRevision(store, hash) {
store.revision = { hash: hash, checkedAt: Date.now() }
}
}
export const actions = {
storeRevision({ commit }, revisionHash) {
commit('setRevision', revisionHash)
},
touchRevision({ commit, state }) {
commit('setRevision', state.revision.hash)
}
}
middleware/checkRevision.js
export default async function({ store, route, app, redirect }) {
const currentRevision = store.state.auth.revision
const revisionAge = Date.now() - currentRevision.checkedAt
if (revisionAge > 1000 * 60) {
// more than a minute old
const revisionHash = await app.$axios.$get(
`${process.env.baseUrl}/revision`
)
if (revisionHash === currentRevision.hash) {
// no update available, so bump checkedAt to now
store.dispatch('auth/touchRevision')
} else {
// need to render server-side to get update
return redirect(`${process.env.baseUrl}/${route.fullPath}`)
}
}
return undefined
}