How to use SSR with Vue 3

寵の児 提交于 2020-12-03 04:25:50

问题


I have a working Vue 2 app with server side rendering. Now I'm trying to upgrade to Vue 3 but stuck on the SSR part cuz the vue-server-renderer package throws the following error:

Vue packages version mismatch: - vue@3.0.0 - vue-server-renderer@2.6.12 This may cause things to work incorrectly. Make sure to use the same version for both.

But there is no version 3.0.0 for vue-server-renderer...

With googling I found this issue on the vue-next repository: https://github.com/vuejs/vue-next/issues/1327

But for me it is still unclear how to achieve SSR with version 3 of vue. Is it already possible? Is there an example how to use SSR with Vue 3?


回答1:


Vue-server-renderer can only be used with vue version 2. One of the big changes with version 3 is that it now has SSR support baked in.

So instead of using the vue-2.0 server-renderer you now just have to use vue's createSSRApp. On the server, to render the thus created app to a string that you can send to the browser you'd use renderToString method which you can import from @vue/server-renderer (note that you have to install this package seperately).

As a super basic (without bundler or anything) example this would look sth like this:

const express = require('express');
const { createSSRApp } = require('vue');
const { renderToString } = require('@vue/server-renderer');

const app = express();

const example= {
  template: `
    <div>
      Hello World
    </div>`,
};

function renderVueApp(req, res) {
  const vueApp = createSSRApp(example);

  (async () => {
    const html = await renderToString(vueApp);

    res.send(`
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <script src="https://unpkg.com/vue@next"></script>
          <title>About blank</title>
        </head>
        <body>
          <div id="app">${html}</div>
          <script>
            const example = { template: '<div>Hello World</div>}; 
            Vue.createSSRApp(example).mount('#app', true);
          </script>
        </body>
      </html>
    `);
  })();
}

app.get('/', renderVueApp);

const port = process.env.PORT || 8080;
app.listen(port, () =>
  console.log(`Server started at localhost:${port}. Press ctrl+c to quit.`)
);

In the front-end you let vue take over the markup from the server, i.e. you create and mount the app in hydration mode.

The bundle renderer you referenced in your question is more or less just extracted from the vue-2.0 server-renderer. In order to use it, you will have to use the client-plugin and server-plugin from the vue-2.0 server-renderer package and plug them into your webpack process to get the server-bundle and the client manifest.

Note that with this setup, the bundle renderer will only inject entry/initial scripts with rel="preload". Right now, the 'new' vue-loader won't inject any component registration logic into components (like the 'old' vue loader does). Still, vue-bundle-renderer can and will inject async chunks with rel="preload", as long as they are referenced in ssrContext._registeredComponents. So if you need this feature in your app, you will have to write up that logic yourself.

Of course, this is one way to do it. I'm sure there plenty more roads that lead to the same destination.

I wrote up a vue3 version of the vue2 hackernews clone, which uses all the described/ mentioned things.

You can find it here: https://github.com/raukaute/vue-hackernews-3.0



来源:https://stackoverflow.com/questions/64239478/how-to-use-ssr-with-vue-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!