问题描述
我有一个可运行的 Vue 2 应用程序,带有服务器端渲染.现在我正在尝试升级到 Vue 3 但卡在 SSR 部分因为 vue-server-renderer 包抛出以下错误:
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: - [email protected] - [email protected] This may cause things to work incorrectly. Make sure to use the same version for both.
但是 vue-server-renderer 没有 3.0.0 版本...
But there is no version 3.0.0 for vue-server-renderer...
通过谷歌搜索,我在 vue-next 存储库中发现了这个问题:https://github.com/vuejs/vue-next/issues/1327
With googling I found this issue on the vue-next repository: https://github.com/vuejs/vue-next/issues/1327
但对我来说,vue 3 版本如何实现 SSR 还是不太清楚.已经可以了吗?有没有在 Vue 3 中使用 SSR 的例子?
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?
推荐答案
Vue-server-renderer 只能与 vue 版本 2 一起使用.版本 3 的重大变化之一是它现在支持 SSR.
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.
因此,您现在只需使用 vue 的 createSSRApp
,而不是使用 vue-2.0 服务器渲染器.在服务器上,要将如此创建的应用程序呈现为您可以发送到浏览器的字符串,您可以使用 renderToString
方法,您可以从 @vue/server-renderer
导入>(注意你必须单独安装这个包).
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.`)
);
在前端,您让 vue 从服务器接管标记,即您在 hydration 模式下创建和挂载应用程序.
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.
您在问题中引用的包渲染器或多或少只是从 vue-2.0 服务器渲染器中提取的.为了使用它,您必须使用 vue-2.0 server-renderer 包中的 client-plugin 和 server-plugin 并将它们插入您的 webpack 进程以获取 server-bundle 和客户端清单.
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.
请注意,使用此设置,包渲染器将仅注入 rel=preload"的入口/初始脚本.现在,新的"vue-loader 不会将任何组件注册逻辑注入到组件中(就像旧的"vue 加载器那样).尽管如此,vue-bundle-renderer 可以并且将使用 rel="preload" 注入异步块,只要它们在 ssrContext._registeredComponents
中被引用.因此,如果您的应用需要此功能,则必须自己编写该逻辑.
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.
我写了一个 vue3 版本的 vue2 黑客新闻克隆,它使用了所有描述/提到的东西.
I wrote up a vue3 version of the vue2 hackernews clone, which uses all the described/ mentioned things.
你可以在这里找到它:https://github.com/raukaute/vue-hackernews-3.0
这篇关于如何在 Vue 3 中使用 SSR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!