koa2 vue3 一个端口 全栈开发 koa-connect viteServer.middlewares
https://github.com/pengchenggang/vite-koa-ssr/blob/main/server/index.ts
koa-connect 这个中间件很重要
import * as fs from 'fs'
import * as path from 'path'
import Koa from 'koa'
import connect from 'koa-connect'
import Router from '@koa/router'
import * as vite from 'vite'
const isTest = process.env.NODE_ENV === 'test' || !!process.env.VITE_TEST_BUILD
const distClient = path.join(process.cwd(), 'dist/app/client')
const distServer = path.join(process.cwd(), 'dist/app/server')
async function createServer(
root = process.cwd(),
isProd = process.env.NODE_ENV === 'production'
) {
const resolve = (p: string) => path.resolve(__dirname, p)
const indexProd = isProd
? fs.readFileSync(resolve(path.join(distClient, 'index.html')), 'utf-8')
: ''
const manifest = isProd ? require(`${distClient}/ssr-manifest.json`) : {}
const app = new Koa()
const router = new Router()
let viteServer: vite.ViteDevServer | null = null
if (!isProd) {
// cover express middleware to koa middleware
viteServer = await vite.createServer({
root,
logLevel: isTest ? 'error' : 'info',
server: {
middlewareMode: 'ssr',
watch: {
// During tests we edit the files too fast and sometimes chokidar
// misses change events, so enforce polling for consistency
usePolling: true,
interval: 100,
},
},
})
// use vite's connect instance as middleware
// use koa-connect covert express's middleware to koa's middleware
app.use(connect(viteServer.middlewares))
} else {
app.use(
require('koa-static')(resolve(distClient), {
index: false,
})
)
}
// inject routes.
router.all('/((?!api).*)', async (ctx, next) => {
try {
const url = ctx.originalUrl
let template, render
if (!isProd) {
// always read fresh template in dev
template = fs.readFileSync(
resolve(path.join(root, 'index.html')),
'utf-8'
)
template = await (viteServer as vite.ViteDevServer).transformIndexHtml(
url,
template
)
render = (
await (viteServer as vite.ViteDevServer).ssrLoadModule(
path.join(root, 'ssr', 'server.ts')
)
).render
} else {
template = indexProd
render = require(`${distServer}/server.js`).render
}
const [appHtml, preloadLinks] = await render(url, manifest, process.cwd())
const html = template
.replace(`<!--preload-links-->`, preloadLinks)
.replace(`<!--app-html-->`, appHtml)
ctx.status = 200
ctx.res.setHeader('Content-Type', 'text/html')
ctx.body = html
} catch (e) {
viteServer && viteServer.ssrFixStacktrace(e as Error)
// console.log(e.stack)
ctx.status = 500
ctx.body = (e as Error).stack
} finally {
next()
}
})
router.get('/api/(.*)', async (ctx, next) => {
ctx.status = 201
ctx.body = 'hello api'
console.log(ctx)
next()
})
app.use(router.routes())
app.use(router.allowedMethods())
return { app, vite }
}
if (!isTest) {
createServer().then(({ app }) => {
app.listen(3000, () => {
console.log('server running on http://0.0.0.0:3000')
})
})
}
exports.createServer = createServer
---------------------------------------------
生活的意义就是你自己知道你要做什么,明确目标。没有目标,后面都是瞎扯!
https://pengchenggang.gitee.io/navigator/
SMART原则:
目标必须是具体的(Specific)
目标必须是可以衡量的(Measurable)
目标必须是可以达到的(Attainable)
目标必须和其他目标具有相关性(Relevant)
目标必须具有明确的截止期限(Time-based)
生活的意义就是你自己知道你要做什么,明确目标。没有目标,后面都是瞎扯!
https://pengchenggang.gitee.io/navigator/
SMART原则:
目标必须是具体的(Specific)
目标必须是可以衡量的(Measurable)
目标必须是可以达到的(Attainable)
目标必须和其他目标具有相关性(Relevant)
目标必须具有明确的截止期限(Time-based)

浙公网安备 33010602011771号