优化 404 页面请求逻辑
All checks were successful
Node.js CI / build-and-test (push) Successful in 37s

This commit is contained in:
2025-05-02 22:54:47 +08:00
parent 2f6b3524c4
commit b9c163fd06
5 changed files with 45 additions and 17 deletions

View File

@ -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

View File

@ -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__)

View File

@ -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 }
}

View File

@ -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 }
}

View File

@ -41,7 +41,8 @@ export function createSSRRouter() {
component: () => import('./views/fallback/NotFound.vue'),
meta: {
title: "页面未找到",
hidden: true
hidden: true,
code: 404
}
}
]})