Vite 服务
本项目是结合 vite ssr
实现的,所以在 src
目录下有个 vite.server.ts
文件。
vite.server分为以下几项:
createViteServer 方法
此方法是为开发模式创建的,当处于开发环境时,此方法会启用vite server并返回。
ts
let viteServer: vite.ViteDevServer;
export async function createViteServer(app: Application) {
viteServer = !viteServer
? await vite.createServer({
root: 'web',
logLevel: 'error',
server: {
middlewareMode: true,
},
})
: viteServer;
app.use(koaConnect(viteServer.middlewares));
return viteServer;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
renderDev 方法
此方法是为开发模式创建的,当处于开发环境时,此方法会render html。
ts
/**
* 开发模式 render
* @param isStream 是否流式传输
* @param ctx Context
* @param viteServer vite 服务
*/
export async function renderDev(
isStream: boolean,
ctx: Context,
viteServer: vite.ViteDevServer
) {
try {
let template = fs.readFileSync(resolve('../web/index.html'), 'utf-8');
template = await viteServer.transformIndexHtml(ctx.originalUrl, template);
const { render } = await viteServer.ssrLoadModule('/entry-server.tsx');
let didError = false;
const [stream, meta, state] = await render(ctx.originalUrl, {
...(isStream === true
? {
onShellReady() {
/**
* 所有Suspense边界之上的内容都准备好了。
*/
renderOnReady(ctx, template, didError, stream, meta, state);
// ctx.res.end();
},
}
: {
onAllReady() {
/**
* 如果您不想要流式传输,请使用它而不是 onShellReady。
* 这将在整个页面内容准备好后触发。
* 您可以将其用于爬虫或静态生成。
*/
renderOnReady(ctx, template, didError, stream, meta, state);
ctx.res.end();
},
}),
onShellError(err: any) {
/**
* 在我们完成 shell 之前发生了一些错误,所以我们发出了一个替代 shell。
*/
ctx.res.statusCode = 500;
ctx.res.write('<!doctype html><body>Loading...</body></html>');
ctx.res.end();
console.error(err);
},
onError(err: any) {
didError = true;
console.error(err);
},
});
} catch (e) {
viteServer && viteServer.ssrFixStacktrace(e);
console.log(e.stack);
ctx.throw(500, e.stack);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
renderProd 方法
此方法是为生产模式创建的,当处于生产环境时,此方法会render html。
ts
/**
* 生成模式 render
* @param isStream 是否流式传输
* @param ctx Context
*/
export async function renderProd(isStream: boolean, ctx: Context) {
try {
let didError = false;
const [stream, meta, state] = await prodRender(ctx.originalUrl, {
...(isStream === true
? {
onShellReady() {
/**
* 所有Suspense边界之上的内容都准备好了。
*/
renderOnReady(ctx, template, didError, stream, meta, state);
// ctx.res.end();
},
}
: {
onAllReady() {
/**
* 如果您不想要流式传输,请使用它而不是 onShellReady。
* 这将在整个页面内容准备好后触发。
* 您可以将其用于爬虫或静态生成。
*/
renderOnReady(ctx, template, didError, stream, meta, state);
ctx.res.end();
},
}),
onShellError(err: any) {
/**
* 在我们完成 shell 之前发生了一些错误,所以我们发出了一个替代 shell。
*/
ctx.res.statusCode = 500;
ctx.res.write('<!doctype html><body>Loading...</body></html>');
ctx.res.end();
console.error(err);
},
onError(err: any) {
didError = true;
console.error(err);
},
});
} catch (e) {
ctx.throw(500, e.stack);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48