I’m trying to get component caching working in Vue 2 (with Nuxt 2).
Right now we have typical LRU implementation from nuxt-multi-cache but we wanted to transition to using Redis (so that it would be outside of the pod, and we could easily invalidate it). I have basic setup ready, components are saved in Redis and are being read by Vue. But it break at the moment of parsing the data returned by Redis.
In vue-server-renderer
there is this piece of code that receives Redis output:
// node_modules/vue-server-renderer/build.dev.js:8399:26
get(key, function (res) {
console.log({vsr_res_components: res?.components});
if (isDef(res)) {
if (isDef(registerComponent)) {
registerComponent(userContext);
}
res.components.forEach(function (register) { return register(userContext); });
write(res.html, next);
} else {
renderComponentWithCache(node, isRoot, key, context);
}
});
And it is breaking on this line:
res.components.forEach(function (register) { return register(userContext); });
saying that res.components.forEach is not a function
So my implementation looks something like this.
cache: {
get: (key, cb) => {
redisClient.get(key, (err, res) => {
console.log(res)
cb(res)
})
},
set: (key, val) => {
console.log(val)
redisClient.set(key, val)
}
}
Following this type declaration from Vue docs:
type RenderCache = {
get: (key: string, cb?: Function) => string | void;
set: (key: string, val: string) => void;
has?: (key: string, cb?: Function) => boolean | void;
};
After some investigation I figured that the issue is occurring when we are saving data to Redis. It parses it and removes parts of the data.
I console logged data we get inside set
method (the rendered component we get from Vue that should go into the cache for future use).
And I got this:
{
html: '<some loong rendered html>',
components: Set(8) {
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook]
}
}
So it seems that Vue broke its own type declaration, and instead of simple string we get some weird object with components, consisting of Set with functions.
And obviously this can not be parsed into string, so Redis client just removes it:
{
html: '<some loong rendered html>',
components: {}
}
But the question now stands – how do I overcome that? I could not find a way to save those into Redis, but there should be a way to achieve component caching with Redis. Even Vue docs are saying that it should be possible:
https://v2.ssr.vuejs.org/api/#cache.
But documentation and resources on it are really scarce. Especially that this Vue version is ending its life soon.
Please send help