Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component caching - wrong type returned in a set method #13175

Closed
AnJ-Github opened this issue Mar 14, 2024 · 1 comment
Closed

Component caching - wrong type returned in a set method #13175

AnJ-Github opened this issue Mar 14, 2024 · 1 comment

Comments

@AnJ-Github
Copy link

AnJ-Github commented Mar 14, 2024

Vue version

2.6.14

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-6m9sxj?file=server.js

Steps to reproduce

  1. Implement server side rendering in Vue
  2. Implement component caching in Vue
  3. Observe what is passed to set method inside createRenderer 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?

@sodatea sodatea transferred this issue from vuejs/core Mar 14, 2024
@AnJ-Github AnJ-Github closed this as not planned Won't fix, can't repro, duplicate, stale Mar 15, 2024
@AnJ-Github
Copy link
Author

Closed as duplicate of #7595

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant