@modern-js/prod-server 2.5.1-alpha.3 → 2.6.1-alpha.0
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 +14 -0
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/libs/context/context.js +13 -0
- package/dist/cjs/libs/hook-api/index.js +4 -0
- package/dist/cjs/libs/loadConfig.js +5 -0
- package/dist/cjs/libs/render/cache/__tests__/cache.fun.test.js +4 -0
- package/dist/cjs/libs/render/cache/page-caches/lru.js +4 -0
- package/dist/cjs/libs/render/cache/spr.js +5 -0
- package/dist/cjs/libs/render/cache/util.js +4 -0
- package/dist/cjs/libs/render/index.js +4 -0
- package/dist/cjs/libs/render/reader.js +9 -0
- package/dist/cjs/libs/render/ssr.js +16 -4
- package/dist/cjs/libs/render/static.js +4 -0
- package/dist/cjs/libs/route/index.js +4 -0
- package/dist/cjs/libs/route/matcher.js +4 -0
- package/dist/cjs/libs/{serve-file.js → serveFile.js} +29 -22
- package/dist/cjs/server/index.js +32 -2
- package/dist/cjs/server/{modern-server.js → modernServer.js} +26 -11
- package/dist/cjs/server/{modern-server-split.js → modernServerSplit.js} +8 -8
- package/dist/cjs/{worker-server.js → workerServer.js} +3 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/libs/context/context.js +15 -6
- package/dist/esm/libs/render/cache/spr.js +1 -0
- package/dist/esm/libs/render/ssr.js +5 -5
- package/dist/esm/libs/route/index.js +4 -0
- package/dist/esm/libs/route/matcher.js +4 -0
- package/dist/esm/libs/{serve-file.js → serveFile.js} +2 -1
- package/dist/esm/server/index.js +29 -4
- package/dist/esm/server/{modern-server.js → modernServer.js} +20 -8
- package/dist/esm/server/{modern-server-split.js → modernServerSplit.js} +1 -1
- package/dist/esm-node/index.js +1 -1
- package/dist/esm-node/libs/context/context.js +9 -0
- package/dist/esm-node/libs/loadConfig.js +1 -0
- package/dist/esm-node/libs/render/cache/spr.js +1 -0
- package/dist/esm-node/libs/render/reader.js +5 -0
- package/dist/esm-node/libs/render/ssr.js +12 -4
- package/dist/esm-node/libs/route/index.js +4 -0
- package/dist/esm-node/libs/route/matcher.js +4 -0
- package/dist/esm-node/libs/serveFile.js +50 -0
- package/dist/esm-node/server/index.js +27 -1
- package/dist/esm-node/server/{modern-server.js → modernServer.js} +17 -6
- package/dist/esm-node/server/{modern-server-split.js → modernServerSplit.js} +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/libs/context/context.d.ts +1 -1
- package/dist/types/libs/render/ssr.d.ts +1 -0
- package/dist/types/type.d.ts +1 -1
- package/dist/types/utils.d.ts +1 -1
- package/package.json +12 -12
- package/dist/esm-node/libs/serve-file.js +0 -47
- /package/dist/esm/{worker-server.js → workerServer.js} +0 -0
- /package/dist/esm-node/{worker-server.js → workerServer.js} +0 -0
- /package/dist/types/libs/{serve-file.d.ts → serveFile.d.ts} +0 -0
- /package/dist/types/server/{modern-server.d.ts → modernServer.d.ts} +0 -0
- /package/dist/types/server/{modern-server-split.d.ts → modernServerSplit.d.ts} +0 -0
- /package/dist/types/{worker-server.d.ts → workerServer.d.ts} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import serve from "serve-static";
|
|
2
|
+
import { isString, isRegExp } from "@modern-js/utils";
|
|
3
|
+
import { useLocalPrefix } from "../utils";
|
|
4
|
+
const removedPrefix = (req, prefix) => {
|
|
5
|
+
if (useLocalPrefix(prefix)) {
|
|
6
|
+
req.url = req.url.slice(prefix.length);
|
|
7
|
+
return () => {
|
|
8
|
+
req.url = prefix + req.url;
|
|
9
|
+
};
|
|
10
|
+
} else {
|
|
11
|
+
return () => {
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const faviconFallbackHandler = (context, next) => {
|
|
16
|
+
if (context.url === "/favicon.ico") {
|
|
17
|
+
context.res.statusCode = 204;
|
|
18
|
+
context.res.end();
|
|
19
|
+
} else {
|
|
20
|
+
next();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const createStaticFileHandler = (rules, output = {}) => (
|
|
24
|
+
// eslint-disable-next-line consistent-return
|
|
25
|
+
async (context, next) => {
|
|
26
|
+
const { url: requestUrl, req, res } = context;
|
|
27
|
+
const { assetPrefix = "/" } = output;
|
|
28
|
+
const hitRule = rules.find((item) => {
|
|
29
|
+
if (isString(item.path) && requestUrl.startsWith(item.path)) {
|
|
30
|
+
return true;
|
|
31
|
+
} else if (isRegExp(item.path) && item.path.test(requestUrl)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
});
|
|
36
|
+
if (hitRule) {
|
|
37
|
+
const resume = removedPrefix(req, assetPrefix);
|
|
38
|
+
serve(hitRule.target)(req, res, () => {
|
|
39
|
+
resume();
|
|
40
|
+
next();
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
return next();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
export {
|
|
48
|
+
createStaticFileHandler,
|
|
49
|
+
faviconFallbackHandler
|
|
50
|
+
};
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
requireConfig
|
|
22
22
|
} from "../libs/loadConfig";
|
|
23
23
|
import { debug } from "../utils";
|
|
24
|
-
import { createProdServer } from "./
|
|
24
|
+
import { createProdServer } from "./modernServerSplit";
|
|
25
25
|
class Server {
|
|
26
26
|
constructor(options) {
|
|
27
27
|
this.serverImpl = createProdServer;
|
|
@@ -32,6 +32,20 @@ class Server {
|
|
|
32
32
|
this.options = options;
|
|
33
33
|
this.serverConfig = {};
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* 初始化顺序
|
|
37
|
+
* - 读取 .env.{process.env.MODERN_ENV} 文件,加载环境变量
|
|
38
|
+
* - 获取 server runtime config
|
|
39
|
+
* - 设置 context
|
|
40
|
+
* - 创建 hooksRunner
|
|
41
|
+
* - 合并插件,内置插件和 serverConfig 中配置的插件
|
|
42
|
+
* - 执行 config hook
|
|
43
|
+
* - 获取最终的配置
|
|
44
|
+
* - 设置配置到 context
|
|
45
|
+
* - 初始化 server
|
|
46
|
+
* - 执行 prepare hook
|
|
47
|
+
* - 执行 server init
|
|
48
|
+
*/
|
|
35
49
|
async init() {
|
|
36
50
|
const { options } = this;
|
|
37
51
|
this.loadServerEnv(options);
|
|
@@ -46,6 +60,11 @@ class Server {
|
|
|
46
60
|
await this.server.onInit(this.runner, this.app);
|
|
47
61
|
return this;
|
|
48
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Execute config hooks
|
|
65
|
+
* @param runner
|
|
66
|
+
* @param options
|
|
67
|
+
*/
|
|
49
68
|
runConfigHook(runner, serverConfig) {
|
|
50
69
|
const newServerConfig = runner.config(serverConfig || {});
|
|
51
70
|
return newServerConfig;
|
|
@@ -63,6 +82,10 @@ class Server {
|
|
|
63
82
|
const serverConfig = requireConfig(serverConfigPath);
|
|
64
83
|
this.serverConfig = serverConfig;
|
|
65
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* merge cliConfig and serverConfig
|
|
88
|
+
*/
|
|
66
89
|
async initConfig(runner, options) {
|
|
67
90
|
const { pwd, config } = options;
|
|
68
91
|
const { serverConfig } = this;
|
|
@@ -86,6 +109,9 @@ class Server {
|
|
|
86
109
|
listener == null ? void 0 : listener();
|
|
87
110
|
};
|
|
88
111
|
if (typeof options === "object") {
|
|
112
|
+
if (process.env.PORT) {
|
|
113
|
+
Object.assign(options, { port: process.env.PORT });
|
|
114
|
+
}
|
|
89
115
|
this.app.listen(options, callback);
|
|
90
116
|
} else {
|
|
91
117
|
this.app.listen(process.env.PORT || options || 8080, callback);
|
|
@@ -8,7 +8,7 @@ import { createRenderHandler } from "../libs/render";
|
|
|
8
8
|
import {
|
|
9
9
|
createStaticFileHandler,
|
|
10
10
|
faviconFallbackHandler
|
|
11
|
-
} from "../libs/
|
|
11
|
+
} from "../libs/serveFile";
|
|
12
12
|
import {
|
|
13
13
|
createErrorDocument,
|
|
14
14
|
createMiddlewareCollecter,
|
|
@@ -33,7 +33,6 @@ import {
|
|
|
33
33
|
createAfterRenderContext,
|
|
34
34
|
createMiddlewareContext
|
|
35
35
|
} from "../libs/hook-api";
|
|
36
|
-
const API_DIR = "./api";
|
|
37
36
|
const SERVER_DIR = "./server";
|
|
38
37
|
class ModernServer {
|
|
39
38
|
constructor({
|
|
@@ -66,6 +65,7 @@ class ModernServer {
|
|
|
66
65
|
this.staticGenerate = staticGenerate || false;
|
|
67
66
|
this.runMode = runMode || RUN_MODE.FULL;
|
|
68
67
|
}
|
|
68
|
+
// server prepare
|
|
69
69
|
async onInit(runner, app) {
|
|
70
70
|
var _a, _b;
|
|
71
71
|
this.runner = runner;
|
|
@@ -113,6 +113,7 @@ class ModernServer {
|
|
|
113
113
|
this.addHandler(this.routeHandler.bind(this));
|
|
114
114
|
this.compose();
|
|
115
115
|
}
|
|
116
|
+
// server ready
|
|
116
117
|
onRepack(_) {
|
|
117
118
|
}
|
|
118
119
|
addBeforeRouteHandler() {
|
|
@@ -135,6 +136,7 @@ class ModernServer {
|
|
|
135
136
|
const onlyWeb = filepath.startsWith(serverPath);
|
|
136
137
|
this.prepareFrameHandler({ onlyWeb, onlyApi });
|
|
137
138
|
}
|
|
139
|
+
// exposed requestHandler
|
|
138
140
|
getRequestHandler() {
|
|
139
141
|
return this.requestHandler.bind(this);
|
|
140
142
|
}
|
|
@@ -156,6 +158,8 @@ class ModernServer {
|
|
|
156
158
|
async createHTTPServer(handler) {
|
|
157
159
|
return createServer(handler);
|
|
158
160
|
}
|
|
161
|
+
/* —————————————————————— function will be overwrite —————————————————————— */
|
|
162
|
+
// get routes info
|
|
159
163
|
getRoutes() {
|
|
160
164
|
if (this.presetRoutes) {
|
|
161
165
|
return this.presetRoutes;
|
|
@@ -167,9 +171,12 @@ class ModernServer {
|
|
|
167
171
|
}
|
|
168
172
|
return [];
|
|
169
173
|
}
|
|
174
|
+
// add promisify request handler to server
|
|
175
|
+
// handler should do not do more things after invoke next
|
|
170
176
|
addHandler(handler) {
|
|
171
177
|
this.handlers.push(handler);
|
|
172
178
|
}
|
|
179
|
+
// return 404 page
|
|
173
180
|
render404(context) {
|
|
174
181
|
context.error(ERROR_DIGEST.ENOTF, "404 Not Found");
|
|
175
182
|
this.renderErrorPage(context, 404);
|
|
@@ -187,19 +194,19 @@ class ModernServer {
|
|
|
187
194
|
);
|
|
188
195
|
this.beforeRouteHandler = handler;
|
|
189
196
|
}
|
|
197
|
+
// gather frame extension and get framework handler
|
|
190
198
|
async prepareFrameHandler(options) {
|
|
191
199
|
const { workDir, runner } = this;
|
|
192
200
|
const { onlyApi, onlyWeb } = options || {};
|
|
193
201
|
const { getMiddlewares, ...collector } = createMiddlewareCollecter();
|
|
194
202
|
await runner.gather(collector);
|
|
195
203
|
const { api: pluginAPIExt, web: pluginWebExt } = getMiddlewares();
|
|
196
|
-
const apiDir = path.join(workDir, API_DIR);
|
|
197
204
|
const serverDir = path.join(workDir, SERVER_DIR);
|
|
198
205
|
if (await fs.pathExists(path.join(serverDir)) && !onlyApi) {
|
|
199
206
|
const webExtension = mergeExtension(pluginWebExt);
|
|
200
207
|
this.frameWebHandler = await this.prepareWebHandler(webExtension);
|
|
201
208
|
}
|
|
202
|
-
if (
|
|
209
|
+
if (!onlyWeb) {
|
|
203
210
|
const apiExtension = mergeExtension(pluginAPIExt);
|
|
204
211
|
this.frameAPIHandler = await this.prepareAPIHandler(apiExtension);
|
|
205
212
|
}
|
|
@@ -257,6 +264,7 @@ class ModernServer {
|
|
|
257
264
|
async proxy() {
|
|
258
265
|
return null;
|
|
259
266
|
}
|
|
267
|
+
// warmup ssr function
|
|
260
268
|
warmupSSRBundle() {
|
|
261
269
|
const { distDir } = this;
|
|
262
270
|
const bundles = this.router.getBundles();
|
|
@@ -270,6 +278,8 @@ class ModernServer {
|
|
|
270
278
|
createContext(req, res, options = {}) {
|
|
271
279
|
return createContext(req, res, options);
|
|
272
280
|
}
|
|
281
|
+
/* —————————————————————— private function —————————————————————— */
|
|
282
|
+
// handler route.json, include api / csr / ssr
|
|
273
283
|
async routeHandler(context) {
|
|
274
284
|
const { res } = context;
|
|
275
285
|
const matched = this.router.match(context.path);
|
|
@@ -350,7 +360,7 @@ class ModernServer {
|
|
|
350
360
|
templateInjectableStream({
|
|
351
361
|
prependHead: route.entryName ? `<script>window._SERVER_DATA=${JSON.stringify(
|
|
352
362
|
context.serverData
|
|
353
|
-
)}
|
|
363
|
+
)}</script>` : void 0
|
|
354
364
|
})
|
|
355
365
|
).pipe(res);
|
|
356
366
|
return;
|
|
@@ -370,7 +380,7 @@ class ModernServer {
|
|
|
370
380
|
afterRenderContext.template.prependHead(
|
|
371
381
|
`<script>window._SERVER_DATA=${JSON.stringify(
|
|
372
382
|
context.serverData
|
|
373
|
-
)}
|
|
383
|
+
)}</script>`
|
|
374
384
|
);
|
|
375
385
|
response = afterRenderContext.template.get();
|
|
376
386
|
}
|
|
@@ -386,6 +396,7 @@ class ModernServer {
|
|
|
386
396
|
}
|
|
387
397
|
return false;
|
|
388
398
|
}
|
|
399
|
+
// compose handlers and create the final handler
|
|
389
400
|
compose() {
|
|
390
401
|
const { handlers } = this;
|
|
391
402
|
if (!Array.isArray(handlers)) {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { ModernServerOptions } from './type';
|
|
|
2
2
|
import { Server } from './server';
|
|
3
3
|
export { Server };
|
|
4
4
|
export type { ServerConfig } from '@modern-js/server-core';
|
|
5
|
-
export { ModernServer } from './server/
|
|
5
|
+
export { ModernServer } from './server/modernServer';
|
|
6
6
|
export { createProxyHandler } from './libs/proxy';
|
|
7
7
|
export * from './type';
|
|
8
8
|
export * from './constants';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/// <reference types="node" />
|
|
4
4
|
/// <reference types="node" />
|
|
5
5
|
/// <reference types="node/http" />
|
|
6
|
-
/// <reference types=".dts-temp/
|
|
6
|
+
/// <reference types=".dts-temp/i8fchs4liml2xhpvizgjb/src/type" />
|
|
7
7
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
8
8
|
import { URL } from 'url';
|
|
9
9
|
import qs from 'querystring';
|
package/dist/types/type.d.ts
CHANGED
package/dist/types/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node/http" />
|
|
3
|
-
/// <reference types=".dts-temp/
|
|
3
|
+
/// <reference types=".dts-temp/i8fchs4liml2xhpvizgjb/src/type" />
|
|
4
4
|
import { IncomingMessage } from 'http';
|
|
5
5
|
import type { OutputNormalizedConfig, HtmlNormalizedConfig } from '@modern-js/server-core';
|
|
6
6
|
export declare const debug: any;
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "2.
|
|
14
|
+
"version": "2.6.1-alpha.0",
|
|
15
15
|
"jsnext:source": "./src/index.ts",
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
17
|
"main": "./dist/cjs/index.js",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
},
|
|
28
28
|
"./worker": {
|
|
29
29
|
"node": {
|
|
30
|
-
"jsnext:source": "./src/
|
|
31
|
-
"import": "./dist/esm-node/
|
|
32
|
-
"require": "./dist/cjs/
|
|
30
|
+
"jsnext:source": "./src/workerServer.ts",
|
|
31
|
+
"import": "./dist/esm-node/workerServer.js",
|
|
32
|
+
"require": "./dist/cjs/workerServer.js"
|
|
33
33
|
},
|
|
34
|
-
"default": "./dist/esm/
|
|
34
|
+
"default": "./dist/esm/workerServer.js"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"typesVersions": {
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"./dist/types/index.d.ts"
|
|
41
41
|
],
|
|
42
42
|
"worker": [
|
|
43
|
-
"./dist/types/
|
|
43
|
+
"./dist/types/workerServer.d.ts"
|
|
44
44
|
]
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@modern-js/utils": "2.
|
|
49
|
-
"@modern-js/server-core": "2.
|
|
48
|
+
"@modern-js/utils": "2.6.0",
|
|
49
|
+
"@modern-js/server-core": "2.6.0",
|
|
50
50
|
"etag": "^1.8.1",
|
|
51
51
|
"fresh": "^0.5.2",
|
|
52
52
|
"cookie": "^0.4.2",
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"serve-static": "^1.14.1"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@modern-js/types": "2.
|
|
62
|
-
"@modern-js/server-core": "2.
|
|
63
|
-
"@scripts/jest-config": "2.
|
|
64
|
-
"@scripts/build": "2.
|
|
61
|
+
"@modern-js/types": "2.6.0",
|
|
62
|
+
"@modern-js/server-core": "2.6.0",
|
|
63
|
+
"@scripts/jest-config": "2.6.0",
|
|
64
|
+
"@scripts/build": "2.6.0",
|
|
65
65
|
"@types/cookie": "^0.4.1",
|
|
66
66
|
"@types/jest": "^27",
|
|
67
67
|
"@types/lru-cache": "^5.1.1",
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import serve from "serve-static";
|
|
2
|
-
import { isString, isRegExp } from "@modern-js/utils";
|
|
3
|
-
import { useLocalPrefix } from "../utils";
|
|
4
|
-
const removedPrefix = (req, prefix) => {
|
|
5
|
-
if (useLocalPrefix(prefix)) {
|
|
6
|
-
req.url = req.url.slice(prefix.length);
|
|
7
|
-
return () => {
|
|
8
|
-
req.url = prefix + req.url;
|
|
9
|
-
};
|
|
10
|
-
} else {
|
|
11
|
-
return () => {
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
const faviconFallbackHandler = (context, next) => {
|
|
16
|
-
if (context.url === "/favicon.ico") {
|
|
17
|
-
context.res.statusCode = 204;
|
|
18
|
-
context.res.end();
|
|
19
|
-
} else {
|
|
20
|
-
next();
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
const createStaticFileHandler = (rules, output = {}) => async (context, next) => {
|
|
24
|
-
const { url: requestUrl, req, res } = context;
|
|
25
|
-
const { assetPrefix = "/" } = output;
|
|
26
|
-
const hitRule = rules.find((item) => {
|
|
27
|
-
if (isString(item.path) && requestUrl.startsWith(item.path)) {
|
|
28
|
-
return true;
|
|
29
|
-
} else if (isRegExp(item.path) && item.path.test(requestUrl)) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
return false;
|
|
33
|
-
});
|
|
34
|
-
if (hitRule) {
|
|
35
|
-
const resume = removedPrefix(req, assetPrefix);
|
|
36
|
-
serve(hitRule.target)(req, res, () => {
|
|
37
|
-
resume();
|
|
38
|
-
next();
|
|
39
|
-
});
|
|
40
|
-
} else {
|
|
41
|
-
return next();
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
export {
|
|
45
|
-
createStaticFileHandler,
|
|
46
|
-
faviconFallbackHandler
|
|
47
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|