VueJS/browser caching production builds

后端 未结 6 1600
抹茶落季
抹茶落季 2020-12-02 12:44

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

6条回答
  •  自闭症患者
    2020-12-02 12:46

    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
    }
    

提交回复
热议问题