Is it possible for Nuxt JS plugins to only run once?
Asked Answered
O

1

9

I have several VueX actions (that run on the server only) and are dispatched from nuxtServerInit. They make HTTP requests to external services, which is slowing down the TTFB.

I would like to implement a cache plugin that can store and retrieve values from Redis. The aim is to avoid making the HTTP requests in actions on every request.

I started out by adding a line to the nuxt.js config file.

{ src: '~/plugins/cache', ssr: true, mode: 'server' },

I then created the following in resources/plugins/cache.js

import redis from 'redis';

export default ({ app }, inject) => {
  console.log('Creating redis client');
  inject('cache', redis.createClient({
    //options removed for brevity
  }));
}

I run the app and can see 'Creating redis client' is printed to the console on every page refresh. Is it possible to create a plugin that is instantiated when the server is started and the same instance is used for every request? Or if that is not possible, what is the best way to implement the cache?

Onondaga answered 1/9, 2020 at 14:29 Comment(1)
why do you want to dispatch those actions on the server side?Gilmore
H
10

As you want to share a data/instance, plugin is not the right place to do that because plugins are created (called) every time new Vue instance is created, which on server means on every request...

So you need something instantiated only once per server...and that's Nuxt module

modules/cacheModule.js

export default function (_moduleOptions) {
  // any data you want to share between all requests
  const data = {
    message: `Hello from cache - ${new Date().toLocalTimeString()}`
  };

  this.nuxt.hook("vue-renderer:ssr:prepareContext", (ssrContext) => {
    ssrContext.$cache = data;
  });
}

And use it in server plugin or nuxtServerInit...

store/index.js

export const state = () => ({
  cache: {}
});

export const mutations = {
  setcache(state, payload) {
    state.cache = payload;
  }
};

export const actions = {
  nuxtServerInit({ commit }, context) {
    commit("setcache", context.ssrContext.$cache);
  }
};

Demo

Same technique can be used for applying cacheAdapterEnhancer from axios-extensions package on server/client (or both) Axios instance so you can keep your original code (fetching in nuxtServerInit) - more details here

Hump answered 31/10, 2020 at 13:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.