Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 784
Tom Avatar asked Sep 01 '20 14:09

Tom


People also ask

Is next js better than NUXT JS?

Next. js has a better customer reach than Nuxt. js, with being mentioned at more than 82 company stacks and 69 developer stacks.

Is Nuxt better than Vue?

Nuxt offers better SEO improvement with its server-side rendering feature, faster development with an auto-generic router, public share features, and management with great configuration options and meta tags methods, automatic code splitting with pre-rendered pages — all of this is impossible or extremely complex to ...

When should you use NUXT JS instead of Vue js?

You just create the directory and files, and Nuxt does all of the work. But the cons are that it is less controllable and manageable than a manually written one. With Vue. js you can easily add your own logic to the router, import services and have more control managing routes than with a manually generated router.


1 Answers

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

like image 190
Michal Levý Avatar answered Oct 21 '22 12:10

Michal Levý