初始化项目
$ npm init vite@latest
添加客户端入口
改造main.js
// - import { createApp } from 'vue'// 引入 createSSRApp 替换 createAppimport { createSSRApp } from 'vue'import App from './App.vue'// - createApp(App).mount('#app')// 暴露统一方法createAppexport function createApp() { const app = createSSRApp(App) // 先不挂载dom,在客户端和服务端分别挂载 // - app.mount('#app') return { app }}
C++音视频开发学习资料:点击莬费领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
新建客户端入口文件 src/entry-client.js
import { createApp } from "./main";const { app } = createApp()app.mount('#app')
修改index.html引入文件
// <script type="module" src="/src/main.js"></script><script type="module" src="/src/entry-client.js"></script>
重新运行项目,确保一切正常
本地node开启ssr
设置开发服务器
const fs = require('fs')const path = require('path')const express = require('express')const { createServer: createViteServer } = require('vite')async function createServer() { const app = express() // 以中间件模式创建 Vite 应用,这将禁用 Vite 自身的 HTML 服务逻辑 // 并让上级服务器接管控制 // // 如果你想使用 Vite 自己的 HTML 服务逻辑(将 Vite 作为 // 一个开发中间件来使用),那么这里请用 'html' const vite = await createViteServer({ server: { middlewareMode: 'ssr' } }) // 使用 vite 的 Connect 实例作为中间件 app.use(vite.middlewares) app.use('*', async (req, res) => { const url = req.originalUrl try { // 1. 读取 index.html let template = fs.readFileSync( path.resolve(__dirname, 'index.html'), 'utf-8' ) // 2. 应用 Vite HTML 转换。这将会注入 Vite HMR 客户端, // 同时也会从 Vite 插件应用 HTML 转换。 // 例如:@vitejs/plugin-react-refresh 中的 global preambles template = await vite.transformIndexHtml(url, template) // 3. 加载服务器入口。vite.ssrLoadModule 将自动转换 // 你的 ESM 源码使之可以在 Node.js 中运行!无需打包 // 并提供类似 HMR 的根据情况随时失效。 const { render } = await vite.ssrLoadModule('/src/entry-server.js') // 4. 渲染应用的 HTML。这假设 entry-server.js 导出的 `render` // 函数调用了适当的 SSR 框架 API。 // 例如 ReactDOMServer.renderToString() const appHtml = await render(url) // 5. 注入渲染后的应用程序 HTML 到模板中。 const html = template.replace(`<!--ssr-outlet-->`, appHtml) // 6. 返回渲染后的 HTML。 res.status(200).set({ 'Content-Type': 'text/html' }).end(html) } catch (e) { // 如果捕获到了一个错误,让 Vite 来修复该堆栈,这样它就可以映射回 // 你的实际源码中。 vite.ssrFixStacktrace(e) console.error(e) res.status(500).end(e.message) } }) app.listen(3000, () => console.log('server is running at http://localhost:3000'))}createServer()
新建服务端入口文件 src/entry-server.js
import { createApp } from "./main"import { renderToString } from 'vue/server-renderer'export async function render(url) { const { app } = createApp() const html = renderToString(app) return html}
index.html添加占位符供服务端渲染时注入
// <div id="app"></div><div id="app"><!--ssr-outlet--></div>
安装express & 启动node
npm i express -Dnode server
C++音视频开发学习资料:点击莬费领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
预览 preview中已经可以看到返回的html源文件
打包运行线上环境
安装cross-env依赖,区分环境
npm i cross-env -D
添加启动、打包命令
// package.json "scripts": { "dev": "vite", // 开发环境 "start:ssr": "cross-env NODE_ENV=developemnt node server", // 线上环境 "prod:ssr": "cross-env NODE_ENV=production node server", "build": "vite build", "preview": "vite preview", // 打包客户端 "build:client": "vite build --outDir dist/client", // 打包服务端 "build:server": "vite build --outDir dist/server --ssr src/entry-server.js", "build:ssr": "npm run build:client && npm run build:server" },
server.js 改造
// 引入serve-staticconst serveStatic = require('serve-static')// 判断当前环境const isProd = process.env.NODE_ENV === 'production'// 根据当前环境使用vite或serve-static let vite = await createViteServer({ server: { middlewareMode: 'ssr' } }) if (isProd) { app.use(serveStatic(path.resolve(__dirname, 'dist/client'), { index: false })) } else { app.use(vite.middlewares) } if (isProd) { // 1. 读取 index.html template = fs.readFileSync( path.resolve(__dirname, 'dist/client/index.html'), 'utf-8' ) // 3. 加载服务器入口。vite.ssrLoadModule 将自动转换 // 你的 ESM 源码使之可以在 Node.js 中运行!无需打包 // 并提供类似 HMR 的根据情况随时失效。 render = require('./dist/server/entry-server.js').render } else { // 1. 读取 index.html template = fs.readFileSync( path.resolve(__dirname, 'index.html'), 'utf-8' ) // 2. 应用 Vite HTML 转换。这将会注入 Vite HMR 客户端, // 同时也会从 Vite 插件应用 HTML 转换。 // 例如:@vitejs/plugin-react-refresh 中的 global preambles template = await vite.transformIndexHtml(url, template) // 3. 加载服务器入口。vite.ssrLoadModule 将自动转换 // 你的 ESM 源码使之可以在 Node.js 中运行!无需打包 // 并提供类似 HMR 的根据情况随时失效。 render = (await vite.ssrLoadModule('/src/entry-server.js')).render }
server.js 完整代码
C++音视频开发学习资料:点击莬费领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
const fs = require('fs')const path = require('path')const express = require('express')const serveStatic = require('serve-static')const { createServer: createViteServer } = require('vite')const isProd = process.env.NODE_ENV === 'production'async function createServer() { const app = express() let vite = await createViteServer({ server: { middlewareMode: 'ssr' } }) if (isProd) { app.use(serveStatic(path.resolve(__dirname, 'dist/client'), { index: false })) } else { app.use(vite.middlewares) } app.use('*', async (req, res) => { const url = req.originalUrl let template let render try { if (isProd) { template = fs.readFileSync( path.resolve(__dirname, 'dist/client/index.html'), 'utf-8' ) render = require('./dist/server/entry-server.js').render } else { template = fs.readFileSync( path.resolve(__dirname, 'index.html'), 'utf-8' ) template = await vite.transformIndexHtml(url, template) render = (await vite.ssrLoadModule('/src/entry-server.js')).render } const appHtml = await render(url) const html = template.replace(`<!--ssr-outlet-->`, appHtml) res.status(200).set({ 'Content-Type': 'text/html' }).end(html) } catch (e) { vite.ssrFixStacktrace(e) console.error(e) res.status(500).end(e.message) } }) app.listen(3000, () => console.log(`server is running at ${isProd ? '线上' : '开发'}环境: http://localhost:3000`))}createServer()
如果你对音视频开发感兴趣,或者对本文的一些阐述有自己的看法,可以在下方的留言框,一起探讨。
版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除