如何在 Vue 3 中使用 SSR

Nio*_*Nio 9 vue.js server-side-rendering

我有一个带有服务器端渲染的工作 Vue 2 应用程序。现在我正在尝试升级到 Vue 3 但卡在 SSR 部分因为 vue-server-renderer 包抛出以下错误:

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.
Run Code Online (Sandbox Code Playgroud)

但是 vue-server-renderer 没有 3.0.0 版本...

通过谷歌搜索,我在 vue-next 存储库中发现了这个问题:https : //github.com/vuejs/vue-next/issues/1327

但是对我来说,vue 3 版本如何实现 SSR 还是不太清楚。已经可以了吗?是否有如何在 Vue 3 中使用 SSR 的示例?

小智 19

Vue-server-renderer 只能与 vue 版本 2 一起使用。版本 3 的重大变化之一是它现在具有 SSR 支持。

因此,您现在只需使用 vue 的createSSRApp. 在服务器上,要将这样创建的应用程序呈现为一个字符串,您可以将其发送到您要使用的renderToString方法的浏览器,您可以从中导入@vue/server-renderer(请注意,您必须单独安装此软件包)。

作为一个超级基本的(没有捆绑器或任何东西)的例子,这看起来像这样:

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.`)
);
Run Code Online (Sandbox Code Playgroud)

在前端,您让 vue 从服务器接管标记,即您在 hydration 模式下创建和安装应用程序。

您在问题中引用的捆绑渲染器或多或少只是从 vue-2.0 服务器渲染器中提取的。为了使用它,你必须使用 vue-2.0 server-renderer 包中的 client-plugin 和 server-plugin 并将它们插入你的 webpack 进程以获取服务器包和客户端清单。

请注意,使用此设置,包渲染器只会注入带有 rel="preload" 的入口/初始脚本。现在,“新的”vue-loader 不会将任何组件注册逻辑注入到组件中(就像“旧的”vue 加载器那样)。尽管如此,vue-bundle-renderer 可以并且将使用 rel="preload" 注入异步块,只要它们在ssrContext._registeredComponents. 因此,如果您的应用程序需要此功能,则必须自己编写该逻辑。

当然,这是一种方法。我相信有更多的道路通向同一个目的地。

我写了一个 vue3 版本的 vue2 黑客新闻克隆,它使用了所有描述/提到的东西。

你可以在这里找到它:https : //github.com/raukaute/vue-hackernews-3.0