123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- import fs from 'fs'
- import path from 'path'
- import { fileURLToPath } from 'url'
- import express from 'express'
- import serverStatic from 'serve-static'
- import { createServer as createViteServer } from 'vite'
- import ssrManifest from './dist/client/.vite/ssr-manifest.json' assert { type: "json" }
- import * as PRODserver from './dist/server/entry-server.js'
- const isProd = process.env.NODE_ENV === 'production'
- const __dirname = path.dirname(fileURLToPath(import.meta.url))
- async function createServer() {
- const app = express()
-
-
-
- const vite = await createViteServer({
- server: { middlewareMode: 'ssr' },
- appType: 'custom'
- })
- if(!isProd){
-
-
-
-
-
-
- app.use(vite.middlewares)
- }else{
- app.use(serverStatic(path.resolve(__dirname,'dist/client'),{index:false}))
- }
-
- app.use('*', async(req, res) => {
- const url = req.originalUrl
- let template
- let render
- let html
- try {
- if(!isProd){
- console.log("开启开发服务端渲染")
-
- template = fs.readFileSync(
- path.resolve(__dirname, 'index.html'),
- 'utf-8',
- )
-
-
-
- template = await vite.transformIndexHtml(url, template)
-
-
-
- render = (await vite.ssrLoadModule('/src/entry-server.ts')).render
-
-
-
-
-
-
-
- }else{
- console.log("开启生产服务端渲染")
- template = fs.readFileSync(
- path.resolve(__dirname, 'dist/client/index.html'),
- 'utf-8',
- )
- render = PRODserver.render
- }
-
-
-
-
- if(!isProd){
- const { appHtml, state } = await render(url)
- const { title,keywords, description } = state.meta
-
- html = template
- .replace(`<!--ssr-outlet-->`, appHtml)
- .replace('\'<!--vuex-state-->\'', JSON.stringify(state))
- .replace('<title>',`<title>${title}`)
- .replace('<meta name="keywords" content="">',`<meta name="keywords" content="${keywords}">`)
- .replace('<meta name="description" content="">',`<meta name="description" content="${description}">`)
-
- }else{
- const manifest = ssrManifest
- const { appHtml, state,preloadLinks } = await render(url,manifest)
- const { title,keywords, description } = state.meta
- html = template
- .replace(`<!--preload-links-->`, preloadLinks)
- .replace(`<!--ssr-outlet-->`, appHtml)
- .replace('\'<!--vuex-state-->\'', JSON.stringify(state))
- .replace('<title>',`<title>${title}`)
- .replace('<meta name="keywords" content="">',`<meta name="keywords" content="${keywords}">`)
- .replace('<meta name="description" content="">',`<meta name="description" content="${description}">`)
- }
-
- res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
- } catch (e) {
-
-
-
-
-
- }
- })
- app.listen(5173, () => {
- console.log("node server.js",isProd ? `运行 生产环境` : `运行 开发环境`)
- })
- }
- createServer()
|