Component caching - wrong type returned in a `set` method
AnJ-Github opened this issue · 1 comments
Vue version
2.6.14
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-6m9sxj?file=server.js
Steps to reproduce
- Implement server side rendering in Vue
- Implement component caching in Vue
- Observe what is passed to
set
method insidecreateRenderer
cache
What is expected?
According to vue documentation set
method should receive second argument as a string:
type RenderCache = {
get: (key: string, cb?: Function) => string | void;
set: (key: string, val: string) => void;
has?: (key: string, cb?: Function) => boolean | void;
};
So val
should have type string
What is actually happening?
Method set
receives an object with this structure:
{
html: '<some loong rendered html>',
components: Set(8) {
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook],
[Function: hook]
}
}
System Info
No response
Any additional comments?
I was trying to implement Redis for component caching. But due to the type of data passed to set
method it is impossible to parse it as a string and store it in a cache. Redis is just removing components
property:
{
html: '<some loong rendered html>',
components: {}
}
And it break vue-server-renderer
, because it expects components to be there:
// 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); }); // this breaks, because components are parsed to an empty object
write(res.html, next);
} else {
renderComponentWithCache(node, isRoot, key, context);
}
});
Vue docs are suggesting that this should be possible, by even giving an example:
const renderer = createRenderer({
cache: {
get: (key, cb) => {
redisClient.get(key, (err, res) => {
// handle error if any
cb(res)
})
},
set: (key, val) => {
redisClient.set(key, val) // but this does not work, as `val` is an object with Set and functions instead of a string, and it can not be stored in Redis
}
}
})
I implemented it like this, but it does not work. I also couldn't find any example of working component caching with Redis. Is this even possible?
Closed as duplicate of #7595