常用的基于vue/react的服务端渲染方案,如下:
- 使用next.js/nuxt.js的服务端渲染方案
- 使用node+vue-server-renderer实现vue项目的服务端渲染
- 使用node+React renderToStaticMarkup实现react项目的服务端渲染
- 传统网站通过模板引擎来实现ssr(比如ejs, jade, pug等)
- 使用rendertron实现SPA项目的服务端渲染
文档:
Vue SSR 基础示例
pnpm install vue
example.js
// 此文件运行在 Node.js 服务器上 import { createSSRApp } from "vue"; // Vue 的服务端渲染 API 位于 `vue/server-renderer` 路径下 import { renderToString } from "vue/server-renderer"; const app = createSSRApp({ data: () => ({ count: 1 }), template: `<button @click="count++">{{ count }}</button>`, }); renderToString(app).then((html) => { console.log(html); });
运行
$ node example.js <button>1</button>
Vue SSR + Express 示例
项目结构
$ tree -I node_modules . ├── app.js ├── client.js ├── index.html ├── package.json └── server.js
package.json
{ "type": "module", "dependencies": { "express": "^4.18.1", "twig": "^1.15.4", "vue": "^3.2.40", "vue-server-renderer": "^2.7.10" } }
服务端 server.js
// server.js import express from "express"; import Twig from "twig"; import { renderToString } from "vue/server-renderer"; import { createApp } from "./app.js"; const server = express(); // 设置模板引擎 server.engine("html", Twig.renderFile); server.set("view engine", "html"); server.set("views", "./"); server.get("/", (req, res) => { const app = createApp(); renderToString(app).then((html) => { res.render("index.html", { html: html, }); }); }); // 托管客户端文件 server.use(express.static(".")); server.listen(3000, () => { console.log("server: http://localhost:3000"); });
app.js
// app.js (在服务器和客户端之间共享) import { createSSRApp } from "vue"; export function createApp() { return createSSRApp({ data() { return { count: 1, }; }, template: `<button @click="handleClick">+{{ count }}</button>`, methods: { handleClick() { this.count++; }, }, created() { // server client console.log("created"); }, mounted() { // client console.log("mounted"); }, }); }
客户端
// client.js import { createApp } from "./app.js"; createApp().mount("#app");
index.html
<!DOCTYPE html> <html> <head> <title>Vue SSR Example</title> <script type="importmap"> { "imports": { "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js" } } </script> <script type="module" src="/client.js"></script> </head> <body> <div id="app">{{html}}</div> </body> </html>
启动服务
$ node server.js
访问地址:http://localhost:3000/
渲染后返回的html
<!DOCTYPE html> <html> <head> <title>Vue SSR Example</title> <script type="importmap"> { "imports": { "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js" } } </script> <script type="module" src="/client.js"></script> </head> <body> <div id="app"><button>+1</button></div> </body> </html>
其他方案