@modern-js/prod-server 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/js/modern/constants.js +4 -0
- package/dist/js/modern/libs/render/modern/index.js +3 -1
- package/dist/js/modern/server/index.js +47 -57
- package/dist/js/modern/server/modern-server-split.js +42 -33
- package/dist/js/modern/server/modern-server.js +55 -48
- package/dist/js/modern/type.js +1 -1
- package/dist/js/node/constants.js +7 -2
- package/dist/js/node/libs/render/modern/index.js +3 -1
- package/dist/js/node/server/index.js +45 -57
- package/dist/js/node/server/modern-server-split.js +40 -37
- package/dist/js/node/server/modern-server.js +55 -48
- package/dist/js/node/type.js +1 -3
- package/dist/types/constants.d.ts +5 -1
- package/dist/types/server/index.d.ts +5 -9
- package/dist/types/server/modern-server-split.d.ts +2 -26
- package/dist/types/server/modern-server.d.ts +16 -14
- package/dist/types/type.d.ts +16 -2
- package/package.json +4 -4
- package/src/constants.ts +5 -0
- package/src/libs/render/index.ts +1 -0
- package/src/libs/render/modern/index.ts +1 -1
- package/src/server/index.ts +51 -71
- package/src/server/modern-server-split.ts +42 -46
- package/src/server/modern-server.ts +61 -53
- package/src/type.ts +41 -1
- package/tests/fixtures/pure/test-dist/bundles/main.js +5 -0
- package/tests/fixtures/pure/test-dist/html/main/index.html +36 -0
- package/tests/fixtures/pure/test-dist/route.json +31 -0
- package/tests/fixtures/ssr/bundle-error.js +3 -0
- package/tests/fixtures/ssr/tpl.html +11 -0
- package/tests/render.test.ts +106 -2
- package/tests/server.test.ts +192 -5
- package/tests/spr.test.ts +38 -0
package/src/type.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
|
+
import { IncomingMessage, Server, ServerResponse } from 'http';
|
|
2
3
|
import { serverManager } from '@modern-js/server-core';
|
|
3
4
|
import type { NormalizedConfig } from '@modern-js/core';
|
|
4
5
|
import type { Metrics, Logger, NextFunction } from '@modern-js/types/server';
|
|
@@ -36,6 +37,7 @@ export type ModernServerOptions = {
|
|
|
36
37
|
ssr?: string;
|
|
37
38
|
api?: string;
|
|
38
39
|
};
|
|
40
|
+
runMode?: string;
|
|
39
41
|
[propName: string]: any;
|
|
40
42
|
};
|
|
41
43
|
|
|
@@ -56,6 +58,44 @@ export type Then<T> = T extends PromiseLike<infer U> ? U : T;
|
|
|
56
58
|
|
|
57
59
|
export type ServerHookRunner = Then<ReturnType<typeof serverManager.init>>;
|
|
58
60
|
|
|
59
|
-
export type
|
|
61
|
+
export type BuildOptions = { routes?: ModernRouteInterface[] };
|
|
60
62
|
|
|
61
63
|
export type { Metrics, Logger, NextFunction };
|
|
64
|
+
|
|
65
|
+
export type HookNames =
|
|
66
|
+
| 'beforeMatch'
|
|
67
|
+
| 'afterMatch'
|
|
68
|
+
| 'beforeRender'
|
|
69
|
+
| 'afterRender';
|
|
70
|
+
|
|
71
|
+
export interface ModernServerInterface {
|
|
72
|
+
pwd: string;
|
|
73
|
+
|
|
74
|
+
distDir: string;
|
|
75
|
+
|
|
76
|
+
onInit: (runner: ServerHookRunner) => Promise<void>;
|
|
77
|
+
|
|
78
|
+
onClose: () => Promise<void>;
|
|
79
|
+
|
|
80
|
+
onRepack: (options: BuildOptions) => void;
|
|
81
|
+
|
|
82
|
+
onListening: (app: Server) => void;
|
|
83
|
+
|
|
84
|
+
getRequestHandler: () => (
|
|
85
|
+
req: IncomingMessage,
|
|
86
|
+
res: ServerResponse,
|
|
87
|
+
next?: () => void,
|
|
88
|
+
) => void;
|
|
89
|
+
|
|
90
|
+
createHTTPServer: (
|
|
91
|
+
handler: (
|
|
92
|
+
req: IncomingMessage,
|
|
93
|
+
res: ServerResponse,
|
|
94
|
+
next?: () => void,
|
|
95
|
+
) => void,
|
|
96
|
+
) => Promise<Server>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type ServerConstructor = (
|
|
100
|
+
options: ModernServerOptions,
|
|
101
|
+
) => ModernServerInterface;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
|
|
6
|
+
<meta charset="utf-8">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no, viewport-fit=cover, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
8
|
+
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
9
|
+
<meta name="renderer" content="webkit">
|
|
10
|
+
<meta name="layoutmode" content="standard">
|
|
11
|
+
<meta name="imagemode" content="force">
|
|
12
|
+
<meta name="wap-font-scale" content="no">
|
|
13
|
+
<meta name="format-detection" content="telephone=no">
|
|
14
|
+
<title></title>
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
<script>
|
|
19
|
+
window.__assetPrefix__ = '';
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<script defer src="/static/js/runtime-main.js"></script><script defer src="/static/js/vendors-node_modules_pnpm_babel_runtime_7_16_7_node_modules_babel_runtime_regenerator_index_j-7f9278.js"></script><script defer src="/static/js/main.js"></script></head>
|
|
23
|
+
|
|
24
|
+
<body>
|
|
25
|
+
<!--<?- chunksMap.css ?>-->
|
|
26
|
+
<noscript>
|
|
27
|
+
We're sorry but react app doesn't work properly without JavaScript enabled. Please enable it to continue.
|
|
28
|
+
</noscript>
|
|
29
|
+
<div id="root"><!--<?- html ?>--></div>
|
|
30
|
+
|
|
31
|
+
<!--<?- chunksMap.js ?>-->
|
|
32
|
+
<!--<?- SSRDataScript ?>-->
|
|
33
|
+
|
|
34
|
+
</body>
|
|
35
|
+
|
|
36
|
+
</html>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"routes": [
|
|
3
|
+
{
|
|
4
|
+
"urlPath": "/",
|
|
5
|
+
"entryName": "main",
|
|
6
|
+
"entryPath": "html/main/index.html",
|
|
7
|
+
"isSPA": true,
|
|
8
|
+
"isSSR": true,
|
|
9
|
+
"enableModernMode": false,
|
|
10
|
+
"bundle": "bundles/main.js"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"urlPath": "/500",
|
|
14
|
+
"entryName": "500",
|
|
15
|
+
"entryPath": "html/main/index.html",
|
|
16
|
+
"isSPA": true,
|
|
17
|
+
"isSSR": true,
|
|
18
|
+
"enableModernMode": false,
|
|
19
|
+
"bundle": "bundles/main.js"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"urlPath": "/404",
|
|
23
|
+
"entryName": "500",
|
|
24
|
+
"entryPath": "html/main/index.html",
|
|
25
|
+
"isSPA": true,
|
|
26
|
+
"isSSR": true,
|
|
27
|
+
"enableModernMode": false,
|
|
28
|
+
"bundle": "bundles/main.js"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<html lang="en">
|
|
2
|
+
<head>
|
|
3
|
+
<meta charset="UTF-8">
|
|
4
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Document</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div>csr</div>
|
|
10
|
+
</body>
|
|
11
|
+
</html>
|
package/tests/render.test.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import {
|
|
2
|
+
import { createRenderHandler } from '../src/libs/render';
|
|
3
|
+
import { render as renderSSR } from '../src/libs/render/ssr';
|
|
3
4
|
import { handleDirectory } from '../src/libs/render/static';
|
|
4
5
|
import { LruReader } from '../src/libs/render/reader';
|
|
6
|
+
import { supportModern } from '../src/libs/render/modern';
|
|
5
7
|
|
|
6
8
|
describe('test render function', () => {
|
|
7
9
|
test('should return content correctly ', async () => {
|
|
8
|
-
const renderResult = await
|
|
10
|
+
const renderResult = await renderSSR(
|
|
9
11
|
{
|
|
10
12
|
params: {},
|
|
11
13
|
pathname: '/foo',
|
|
@@ -99,4 +101,106 @@ describe('test render function', () => {
|
|
|
99
101
|
expect(res2).not.toBeNull();
|
|
100
102
|
expect(res2?.content.toString()).toMatch('modern');
|
|
101
103
|
});
|
|
104
|
+
|
|
105
|
+
test('should entry render fn work correctly', async () => {
|
|
106
|
+
const render = createRenderHandler({
|
|
107
|
+
distDir: path.join(__dirname, 'fixtures', 'ssr'),
|
|
108
|
+
staticGenerate: false,
|
|
109
|
+
});
|
|
110
|
+
const renderResult = await render({
|
|
111
|
+
ctx: {
|
|
112
|
+
params: {},
|
|
113
|
+
pathname: '/foo',
|
|
114
|
+
host: 'localhost:8080',
|
|
115
|
+
query: {},
|
|
116
|
+
url: 'localhost:8080/foo',
|
|
117
|
+
cookieMap: {},
|
|
118
|
+
headers: {},
|
|
119
|
+
resHasHandled: () => false,
|
|
120
|
+
} as any,
|
|
121
|
+
route: {
|
|
122
|
+
urlPath: '/foo',
|
|
123
|
+
bundle: 'bundle.js',
|
|
124
|
+
entryPath: 'tpl.html',
|
|
125
|
+
entryName: 'foo',
|
|
126
|
+
isSSR: true,
|
|
127
|
+
isSPA: true,
|
|
128
|
+
} as any,
|
|
129
|
+
runner: {
|
|
130
|
+
extendSSRContext: () => {
|
|
131
|
+
// empty
|
|
132
|
+
},
|
|
133
|
+
} as any,
|
|
134
|
+
});
|
|
135
|
+
expect(renderResult!.content).toMatch('Modern.js');
|
|
136
|
+
expect(renderResult!.contentType).toMatch('text/html; charset=utf-8');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('should entry render fn fallback work correctly', async () => {
|
|
140
|
+
const render = createRenderHandler({
|
|
141
|
+
distDir: path.join(__dirname, 'fixtures', 'ssr'),
|
|
142
|
+
staticGenerate: false,
|
|
143
|
+
});
|
|
144
|
+
const renderResult = await render({
|
|
145
|
+
ctx: {
|
|
146
|
+
params: {},
|
|
147
|
+
pathname: '/foo',
|
|
148
|
+
host: 'localhost:8080',
|
|
149
|
+
query: {},
|
|
150
|
+
url: 'localhost:8080/foo',
|
|
151
|
+
cookieMap: {},
|
|
152
|
+
headers: {},
|
|
153
|
+
res: {
|
|
154
|
+
setHeader: () => false,
|
|
155
|
+
},
|
|
156
|
+
error: () => false,
|
|
157
|
+
resHasHandled: () => false,
|
|
158
|
+
} as any,
|
|
159
|
+
route: {
|
|
160
|
+
urlPath: '/foo',
|
|
161
|
+
bundle: 'bundle-error.js',
|
|
162
|
+
entryPath: 'tpl.html',
|
|
163
|
+
entryName: 'foo',
|
|
164
|
+
isSSR: true,
|
|
165
|
+
isSPA: true,
|
|
166
|
+
} as any,
|
|
167
|
+
runner: {
|
|
168
|
+
extendSSRContext: () => {
|
|
169
|
+
// empty
|
|
170
|
+
},
|
|
171
|
+
} as any,
|
|
172
|
+
});
|
|
173
|
+
expect(renderResult!.content.toString()).toMatch('csr');
|
|
174
|
+
expect(renderResult!.contentType).toMatch('text/html; charset=utf-8');
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe('test modern render', () => {
|
|
179
|
+
test('should return true if has target query', () => {
|
|
180
|
+
const res = supportModern({ query: { modern_es6: true } } as any);
|
|
181
|
+
expect(res).toBeTruthy();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('should return false if no ua', () => {
|
|
185
|
+
const res = supportModern({ headers: {} } as any);
|
|
186
|
+
expect(res).toBeFalsy();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('should return false if ua is not string', () => {
|
|
190
|
+
const res = supportModern({ headers: { 'user-agent': true } } as any);
|
|
191
|
+
expect(res).toBeFalsy();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test('should return false if ua no browser version', () => {
|
|
195
|
+
const res = supportModern({ headers: { 'user-agent': 'mock' } } as any);
|
|
196
|
+
expect(res).toBeFalsy();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('should return false if ua no match name', () => {
|
|
200
|
+
const ua =
|
|
201
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36';
|
|
202
|
+
|
|
203
|
+
const res = supportModern({ headers: { 'user-agent': ua } } as any);
|
|
204
|
+
expect(res).toBeTruthy();
|
|
205
|
+
});
|
|
102
206
|
});
|
package/tests/server.test.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import { EventEmitter, Readable } from 'stream';
|
|
2
3
|
import { defaultsConfig, NormalizedConfig } from '@modern-js/core';
|
|
3
4
|
import { ModernServerContext, NextFunction } from '@modern-js/types';
|
|
4
|
-
import
|
|
5
|
+
import httpMocks from 'node-mocks-http';
|
|
6
|
+
import portfinder from 'portfinder';
|
|
7
|
+
import createServer, { RUN_MODE, Server } from '../src';
|
|
5
8
|
import { ModernServer } from '../src/server/modern-server';
|
|
9
|
+
import { createContext } from '../src/libs/context';
|
|
6
10
|
|
|
11
|
+
const appDirectory = path.join(__dirname, './fixtures/pure');
|
|
7
12
|
describe('test server', () => {
|
|
8
13
|
test('should throw error when ', resolve => {
|
|
9
14
|
try {
|
|
@@ -19,14 +24,17 @@ describe('test server', () => {
|
|
|
19
24
|
test('shoule get modern server instance', async () => {
|
|
20
25
|
const server = await createServer({
|
|
21
26
|
config: defaultsConfig as NormalizedConfig,
|
|
22
|
-
pwd:
|
|
27
|
+
pwd: appDirectory,
|
|
23
28
|
});
|
|
29
|
+
const port = await portfinder.getPortPromise();
|
|
24
30
|
expect(server instanceof Server).toBe(true);
|
|
31
|
+
|
|
32
|
+
server.listen(port, () => {
|
|
33
|
+
server.close();
|
|
34
|
+
});
|
|
25
35
|
});
|
|
26
36
|
|
|
27
37
|
describe('shoule get production modern server instance', () => {
|
|
28
|
-
const appDirectory = path.join(__dirname, './fixtures/pure');
|
|
29
|
-
|
|
30
38
|
test('should init server correctly', async () => {
|
|
31
39
|
const server = await createServer({
|
|
32
40
|
config: defaultsConfig as NormalizedConfig,
|
|
@@ -89,13 +97,192 @@ describe('test server', () => {
|
|
|
89
97
|
|
|
90
98
|
test('should get request handler correctly', async () => {
|
|
91
99
|
const server = await createServer({
|
|
92
|
-
config:
|
|
100
|
+
config: {
|
|
101
|
+
...(defaultsConfig as NormalizedConfig),
|
|
102
|
+
output: {
|
|
103
|
+
path: 'test-dist',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
93
106
|
pwd: appDirectory,
|
|
94
107
|
});
|
|
95
108
|
|
|
96
109
|
const modernServer: ModernServer = (server as any).server;
|
|
97
110
|
const handler = modernServer.getRequestHandler();
|
|
98
111
|
expect(typeof handler === 'function').toBeTruthy();
|
|
112
|
+
|
|
113
|
+
const req = httpMocks.createRequest({
|
|
114
|
+
url: '/',
|
|
115
|
+
headers: {
|
|
116
|
+
host: 'modernjs.com',
|
|
117
|
+
},
|
|
118
|
+
eventEmitter: Readable,
|
|
119
|
+
method: 'GET',
|
|
120
|
+
});
|
|
121
|
+
const res = httpMocks.createResponse({ eventEmitter: EventEmitter });
|
|
122
|
+
handler(req, res, () => {
|
|
123
|
+
// empty
|
|
124
|
+
});
|
|
125
|
+
const html = await new Promise((resolve, _reject) => {
|
|
126
|
+
res.on('finish', () => {
|
|
127
|
+
resolve(res._getData());
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(html).toMatch('<div>Modern.js</div>');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('should error handler correctly with custom entry', async () => {
|
|
135
|
+
const server = await createServer({
|
|
136
|
+
config: {
|
|
137
|
+
...(defaultsConfig as NormalizedConfig),
|
|
138
|
+
output: {
|
|
139
|
+
path: 'test-dist',
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
pwd: appDirectory,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const modernServer: ModernServer = (server as any).server;
|
|
146
|
+
const req = httpMocks.createRequest({
|
|
147
|
+
url: '/',
|
|
148
|
+
headers: {
|
|
149
|
+
host: 'modernjs.com',
|
|
150
|
+
},
|
|
151
|
+
eventEmitter: Readable,
|
|
152
|
+
method: 'GET',
|
|
153
|
+
});
|
|
154
|
+
const res = httpMocks.createResponse({ eventEmitter: EventEmitter });
|
|
155
|
+
const ctx = createContext(req, res);
|
|
156
|
+
ctx.error = () => {
|
|
157
|
+
// empty
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
(modernServer as any).onError(ctx, new Error('test error'));
|
|
162
|
+
}, 100);
|
|
163
|
+
const html = await new Promise((resolve, _reject) => {
|
|
164
|
+
res.on('finish', () => {
|
|
165
|
+
resolve(res._getData());
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
expect(html).toMatch('<div>Modern.js</div>');
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('should error handler correctly with fallback doc', async () => {
|
|
172
|
+
const server = await createServer({
|
|
173
|
+
config: {
|
|
174
|
+
...(defaultsConfig as NormalizedConfig),
|
|
175
|
+
output: {
|
|
176
|
+
path: 'test-dist',
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
pwd: appDirectory,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const modernServer: ModernServer = (server as any).server;
|
|
183
|
+
const req = httpMocks.createRequest({
|
|
184
|
+
url: '/',
|
|
185
|
+
headers: {
|
|
186
|
+
host: 'modernjs.com',
|
|
187
|
+
},
|
|
188
|
+
eventEmitter: Readable,
|
|
189
|
+
method: 'GET',
|
|
190
|
+
});
|
|
191
|
+
const res = httpMocks.createResponse({ eventEmitter: EventEmitter });
|
|
192
|
+
const ctx = createContext(req, res);
|
|
193
|
+
ctx.error = () => {
|
|
194
|
+
// empty
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
setTimeout(() => {
|
|
198
|
+
(modernServer as any).renderErrorPage(ctx, 404);
|
|
199
|
+
}, 100);
|
|
200
|
+
const html = await new Promise((resolve, _reject) => {
|
|
201
|
+
res.on('finish', () => {
|
|
202
|
+
resolve(res._getData());
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
expect(html).toMatch('This page could not be found.');
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe('should split server work correctly', () => {
|
|
210
|
+
test('should init api server correctly', async () => {
|
|
211
|
+
const server = await createServer({
|
|
212
|
+
config: defaultsConfig as NormalizedConfig,
|
|
213
|
+
pwd: appDirectory,
|
|
214
|
+
apiOnly: true,
|
|
215
|
+
runMode: RUN_MODE.FULL,
|
|
216
|
+
});
|
|
217
|
+
const modernServer = (server as any).server;
|
|
218
|
+
modernServer.emitRouteHook('reset', {});
|
|
219
|
+
expect(modernServer.prepareWebHandler()).toBeNull();
|
|
220
|
+
await server.close();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test('should init web server correctly', async () => {
|
|
224
|
+
const server = await createServer({
|
|
225
|
+
config: defaultsConfig as NormalizedConfig,
|
|
226
|
+
pwd: appDirectory,
|
|
227
|
+
ssrOnly: true,
|
|
228
|
+
runMode: RUN_MODE.FULL,
|
|
229
|
+
});
|
|
230
|
+
const modernServer = (server as any).server;
|
|
231
|
+
modernServer.emitRouteHook('reset', {});
|
|
232
|
+
expect(modernServer.prepareAPIHandler()).toBeNull();
|
|
233
|
+
await server.close();
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('should init ssr server correctly', async () => {
|
|
237
|
+
const server = await createServer({
|
|
238
|
+
config: defaultsConfig as NormalizedConfig,
|
|
239
|
+
pwd: appDirectory,
|
|
240
|
+
webOnly: true,
|
|
241
|
+
});
|
|
242
|
+
const modernServer = (server as any).server;
|
|
243
|
+
const req = httpMocks.createRequest({
|
|
244
|
+
url: '/',
|
|
245
|
+
eventEmitter: Readable,
|
|
246
|
+
method: 'GET',
|
|
247
|
+
});
|
|
248
|
+
const res = httpMocks.createResponse({ eventEmitter: EventEmitter });
|
|
249
|
+
const ctx = createContext(req, res);
|
|
250
|
+
ctx.resHasHandled = () => true;
|
|
251
|
+
ctx.error = () => {
|
|
252
|
+
// empty
|
|
253
|
+
};
|
|
254
|
+
expect(await modernServer.warmupSSRBundle()).toBeNull();
|
|
255
|
+
expect(await modernServer.handleAPI(ctx, {})).toBeUndefined();
|
|
256
|
+
expect(await modernServer.handleWeb(ctx, {})).toBeNull();
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test('should init web server with proxy correctly', async () => {
|
|
260
|
+
const server = await createServer({
|
|
261
|
+
config: defaultsConfig as NormalizedConfig,
|
|
262
|
+
pwd: appDirectory,
|
|
263
|
+
webOnly: true,
|
|
264
|
+
proxyTarget: {
|
|
265
|
+
api: '/',
|
|
266
|
+
ssr: '/',
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
const modernServer = (server as any).server;
|
|
270
|
+
const req = httpMocks.createRequest({
|
|
271
|
+
url: '/',
|
|
272
|
+
eventEmitter: Readable,
|
|
273
|
+
method: 'GET',
|
|
274
|
+
});
|
|
275
|
+
const res = httpMocks.createResponse({ eventEmitter: EventEmitter });
|
|
276
|
+
const ctx = createContext(req, res);
|
|
277
|
+
ctx.resHasHandled = () => true;
|
|
278
|
+
ctx.error = () => {
|
|
279
|
+
// empty
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
expect(await modernServer.warmupSSRBundle()).toBeNull();
|
|
283
|
+
expect(await modernServer.handleAPI(ctx, {})).toBeNull();
|
|
284
|
+
expect(await modernServer.handleWeb(ctx, { isSSR: true })).toBeNull();
|
|
285
|
+
await server.close();
|
|
99
286
|
});
|
|
100
287
|
});
|
|
101
288
|
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import renderCreator from '../src/libs/render/cache';
|
|
2
|
+
|
|
3
|
+
const createCacheConfig = (config: any = {}) => ({
|
|
4
|
+
excludes: null,
|
|
5
|
+
includes: null,
|
|
6
|
+
interval: 10,
|
|
7
|
+
staleLimit: false,
|
|
8
|
+
level: 0,
|
|
9
|
+
fallback: false,
|
|
10
|
+
matches: null,
|
|
11
|
+
...config,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe('test serverless pre-render', () => {
|
|
15
|
+
it('should return render function after invoke', async () => {
|
|
16
|
+
const renderfn = async () => 'hello modern';
|
|
17
|
+
const context = {
|
|
18
|
+
entry: '',
|
|
19
|
+
pathname: '',
|
|
20
|
+
query: {},
|
|
21
|
+
headers: {},
|
|
22
|
+
res: {
|
|
23
|
+
setHeader: () => false,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const doRender = renderCreator(renderfn, context as any);
|
|
27
|
+
|
|
28
|
+
const res = await doRender({
|
|
29
|
+
cacheConfig: createCacheConfig(),
|
|
30
|
+
} as any);
|
|
31
|
+
expect(res).toBe(await renderfn());
|
|
32
|
+
|
|
33
|
+
const res1 = await doRender({
|
|
34
|
+
cacheConfig: createCacheConfig(),
|
|
35
|
+
} as any);
|
|
36
|
+
expect(res1).toBe(await renderfn());
|
|
37
|
+
});
|
|
38
|
+
});
|