This commit is contained in:
26
server.js
26
server.js
@ -16,6 +16,11 @@ const templateHtml = isProduction
|
||||
const app = express()
|
||||
app.use(cookieParser());
|
||||
|
||||
const MESSAGE = {
|
||||
404: 'Not Found',
|
||||
0: 'Unknown'
|
||||
}
|
||||
|
||||
// Add Vite or respective production middlewares
|
||||
/** @type {import('vite').ViteDevServer | undefined} */
|
||||
let vite
|
||||
@ -42,19 +47,30 @@ app.use('*all', async (req, res) => {
|
||||
/** @type {string} */
|
||||
let template
|
||||
/** @type {import('./src/entry-server.js').render} */
|
||||
let render
|
||||
let render, getRoute
|
||||
if (!isProduction) {
|
||||
// Always read fresh template in development
|
||||
template = await fs.readFile('./index.html', 'utf-8')
|
||||
template = await vite.transformIndexHtml(url, template)
|
||||
render = (await vite.ssrLoadModule('/src/entry-server.js')).render
|
||||
const module = await vite.ssrLoadModule('/src/entry-server.js')
|
||||
render = module.render
|
||||
getRoute = module.getRoute
|
||||
} else {
|
||||
template = templateHtml
|
||||
render = (await import('./dist/server/entry-server.js')).render
|
||||
const module = await import('./dist/server/entry-server.js')
|
||||
render = module.render
|
||||
getRoute = module.getRoute
|
||||
}
|
||||
const { stream, piniaState } = await render(url, req.cookies, req.headers.host)
|
||||
const { router, code } = await getRoute(url)
|
||||
if (code != 200 && !req.accepts('html')) {
|
||||
res.status(code).set({ 'Content-Type': 'text/plain' })
|
||||
res.write(MESSAGE[code] || MESSAGE[0])
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
const { stream, piniaState } = await render(router, req.cookies, req.headers.host)
|
||||
const [htmlStart, htmlEnd] = template.split('<!--app-html-->')
|
||||
res.status(200).set({ 'Content-Type': 'text/html' })
|
||||
res.status(code).set({ 'Content-Type': 'text/html' })
|
||||
res.write(htmlStart)
|
||||
for await (const chunk of stream) {
|
||||
if (res.closed) break
|
||||
|
@ -1,8 +1,13 @@
|
||||
import { decompress } from 'compress-json'
|
||||
import './main.css'
|
||||
import { createApp } from './main'
|
||||
|
||||
const { app, pinia, router } = createApp()
|
||||
import { createApp } from './main'
|
||||
import { createSSRRouter } from './router.js'
|
||||
|
||||
const { app, pinia } = createApp()
|
||||
const router = createSSRRouter()
|
||||
|
||||
app.use(router)
|
||||
|
||||
if (window.__PINIA_STATE__) {
|
||||
pinia.state.value = decompress(window.__PINIA_STATE__)
|
||||
|
@ -1,19 +1,28 @@
|
||||
import { renderToWebStream, renderToString } from 'vue/server-renderer'
|
||||
import { createApp } from './main'
|
||||
|
||||
export async function render(_url, cookies, host) {
|
||||
const { app, pinia, router } = createApp()
|
||||
import { createSSRRouter } from './router.js'
|
||||
|
||||
export async function getRoute(_url) {
|
||||
const router = createSSRRouter()
|
||||
await router.push(_url)
|
||||
await router.isReady()
|
||||
const route = router.currentRoute.value.matched[0]
|
||||
const code = route.meta.code || 200
|
||||
return { router, code }
|
||||
}
|
||||
|
||||
export async function render(router, cookies, host) {
|
||||
const { app, pinia } = createApp()
|
||||
|
||||
app.use(router)
|
||||
const ctx = {
|
||||
cookies,
|
||||
host,
|
||||
initialState: {}
|
||||
}
|
||||
// await new Promise((resolve) => setTimeout(resolve, 0))
|
||||
const stream = renderToWebStream(app, ctx)
|
||||
const initialState = ctx.initialStat
|
||||
const piniaState = pinia.state.value
|
||||
return { stream, initialState, piniaState }
|
||||
return { stream, piniaState }
|
||||
}
|
||||
|
||||
|
@ -2,19 +2,16 @@ import { createSSRApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import { createSSRRouter } from './router.js'
|
||||
|
||||
import ClientOnly from './ssr/ClientOnly.vue'
|
||||
import Hr from './ui/BetterHr.vue'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
const router = createSSRRouter()
|
||||
const pinia = createPinia()
|
||||
app.use(pinia)
|
||||
app.use(router)
|
||||
app
|
||||
.component('ClientOnly', ClientOnly)
|
||||
.component('Hr', Hr)
|
||||
return { app, pinia, router }
|
||||
return { app, pinia }
|
||||
}
|
||||
|
@ -41,7 +41,8 @@ export function createSSRRouter() {
|
||||
component: () => import('./views/fallback/NotFound.vue'),
|
||||
meta: {
|
||||
title: "页面未找到",
|
||||
hidden: true
|
||||
hidden: true,
|
||||
code: 404
|
||||
}
|
||||
}
|
||||
]})
|
||||
|
Reference in New Issue
Block a user