@modern-js/server 0.0.0-plugins-202111301002 → 0.0.0-runtime-2021112193858
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 +59 -0
- package/dist/js/modern/dev-tools/babel/register.js +2 -2
- package/dist/js/modern/dev-tools/mock/getMockData.js +2 -2
- package/dist/js/modern/libs/context/context.js +15 -7
- package/dist/js/modern/libs/context/index.js +2 -2
- package/dist/js/modern/libs/hook-api/route.js +37 -0
- package/dist/js/modern/libs/{hook-api.js → hook-api/template.js} +0 -0
- package/dist/js/modern/libs/{measure.js → metrics.js} +2 -2
- package/dist/js/modern/libs/proxy.js +2 -2
- package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +2 -2
- package/dist/js/modern/libs/render/cache/index.js +2 -2
- package/dist/js/modern/libs/render/ssr.js +1 -1
- package/dist/js/modern/libs/route/index.js +4 -0
- package/dist/js/modern/libs/route/matcher.js +4 -0
- package/dist/js/modern/libs/route/route.js +1 -1
- package/dist/js/modern/server/dev-server/dev-server-split.js +28 -0
- package/dist/js/modern/server/{dev-server.js → dev-server/dev-server.js} +41 -22
- package/dist/js/modern/server/dev-server/index.js +2 -0
- package/dist/js/modern/server/index.js +65 -63
- package/dist/js/modern/server/modern-server-split.js +81 -0
- package/dist/js/modern/server/modern-server.js +121 -70
- package/dist/js/modern/utils.js +11 -3
- package/dist/js/node/dev-tools/babel/register.js +2 -2
- package/dist/js/node/dev-tools/mock/getMockData.js +2 -2
- package/dist/js/node/libs/context/context.js +15 -7
- package/dist/js/node/libs/context/index.js +2 -2
- package/dist/js/node/libs/hook-api/route.js +46 -0
- package/dist/js/node/libs/{hook-api.js → hook-api/template.js} +0 -0
- package/dist/js/node/libs/{measure.js → metrics.js} +3 -3
- package/dist/js/node/libs/proxy.js +2 -2
- package/dist/js/node/libs/render/cache/__tests__/cache.test.js +2 -2
- package/dist/js/node/libs/render/cache/index.js +2 -2
- package/dist/js/node/libs/render/ssr.js +1 -1
- package/dist/js/node/libs/route/index.js +4 -0
- package/dist/js/node/libs/route/matcher.js +4 -0
- package/dist/js/node/libs/route/route.js +1 -1
- package/dist/js/node/server/dev-server/dev-server-split.js +41 -0
- package/dist/js/node/server/{dev-server.js → dev-server/dev-server.js} +42 -21
- package/dist/js/node/server/dev-server/index.js +27 -0
- package/dist/js/node/server/index.js +72 -64
- package/dist/js/node/server/modern-server-split.js +97 -0
- package/dist/js/node/server/modern-server.js +124 -71
- package/dist/js/node/utils.js +14 -4
- package/dist/types/libs/context/context.d.ts +5 -5
- package/dist/types/libs/context/index.d.ts +3 -3
- package/dist/types/libs/hook-api/route.d.ts +13 -0
- package/dist/types/libs/{hook-api.d.ts → hook-api/template.d.ts} +0 -0
- package/dist/types/libs/metrics.d.ts +3 -0
- package/dist/types/libs/render/type.d.ts +2 -2
- package/dist/types/libs/route/index.d.ts +1 -0
- package/dist/types/libs/route/matcher.d.ts +1 -0
- package/dist/types/libs/route/route.d.ts +2 -10
- package/dist/types/server/dev-server/dev-server-split.d.ts +15 -0
- package/dist/types/server/{dev-server.d.ts → dev-server/dev-server.d.ts} +6 -5
- package/dist/types/server/dev-server/index.d.ts +2 -0
- package/dist/types/server/index.d.ts +3 -1
- package/dist/types/server/modern-server-split.d.ts +26 -0
- package/dist/types/server/modern-server.d.ts +20 -12
- package/dist/types/type.d.ts +9 -4
- package/dist/types/utils.d.ts +3 -2
- package/package.json +18 -20
- package/src/libs/context/context.ts +12 -8
- package/src/libs/context/index.ts +3 -3
- package/src/libs/hook-api/route.ts +38 -0
- package/src/libs/{hook-api.ts → hook-api/template.ts} +0 -0
- package/src/libs/{measure.ts → metrics.ts} +3 -3
- package/src/libs/render/ssr.ts +1 -1
- package/src/libs/render/type.ts +2 -2
- package/src/libs/route/index.ts +4 -0
- package/src/libs/route/matcher.ts +4 -0
- package/src/libs/route/route.ts +4 -20
- package/src/server/{web-server.ts → dev-server/dev-server-split.ts} +12 -14
- package/src/server/{dev-server.ts → dev-server/dev-server.ts} +62 -33
- package/src/server/dev-server/index.ts +2 -0
- package/src/server/index.ts +81 -48
- package/src/server/modern-server-split.ts +97 -0
- package/src/server/modern-server.ts +140 -90
- package/src/type.ts +9 -4
- package/src/utils.ts +16 -2
- package/dist/js/modern/server/api-server.js +0 -36
- package/dist/js/modern/server/web-server.js +0 -30
- package/dist/js/node/server/api-server.js +0 -50
- package/dist/js/node/server/web-server.js +0 -44
- package/dist/types/libs/measure.d.ts +0 -3
- package/dist/types/server/api-server.d.ts +0 -17
- package/dist/types/server/web-server.d.ts +0 -15
- package/src/server/api-server.ts +0 -47
package/src/server/index.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
ServerResponse,
|
|
4
|
-
createServer,
|
|
5
|
-
Server as httpServer,
|
|
6
|
-
} from 'http';
|
|
7
|
-
import { createServer as createHttpsServer } from 'https';
|
|
1
|
+
import { IncomingMessage, ServerResponse, Server as httpServer } from 'http';
|
|
2
|
+
import path from 'path';
|
|
8
3
|
import { serverManager } from '@modern-js/server-plugin';
|
|
9
4
|
import { logger as defaultLogger } from '@modern-js/utils';
|
|
10
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AppContext,
|
|
7
|
+
initAppContext,
|
|
8
|
+
initAppDir,
|
|
9
|
+
loadUserConfig,
|
|
10
|
+
ConfigContext,
|
|
11
|
+
UserConfig,
|
|
12
|
+
} from '@modern-js/core';
|
|
11
13
|
import { ModernServer } from './modern-server';
|
|
12
14
|
import type { ModernDevServer } from './dev-server';
|
|
13
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
ModernAPIServer,
|
|
17
|
+
ModernSSRServer,
|
|
18
|
+
ModernWebServer,
|
|
19
|
+
} from './modern-server-split';
|
|
20
|
+
import { ModernServerOptions, ServerHookRunner, ReadyOptions } from '@/type';
|
|
21
|
+
import { metrics as defaultMetrics } from '@/libs/metrics';
|
|
14
22
|
|
|
15
23
|
export class Server {
|
|
16
24
|
public options: ModernServerOptions;
|
|
@@ -23,9 +31,6 @@ export class Server {
|
|
|
23
31
|
|
|
24
32
|
constructor(options: ModernServerOptions) {
|
|
25
33
|
this.options = options;
|
|
26
|
-
options.plugins?.forEach(p => {
|
|
27
|
-
serverManager.usePlugin(p);
|
|
28
|
-
});
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
public getRequestHandler() {
|
|
@@ -41,38 +46,24 @@ export class Server {
|
|
|
41
46
|
|
|
42
47
|
public async init() {
|
|
43
48
|
const { options } = this;
|
|
44
|
-
this.runner = await serverManager.init({});
|
|
45
|
-
|
|
46
|
-
const { logger, measure } = await this.runner.create(
|
|
47
|
-
{
|
|
48
|
-
loggerOptions: options.logger,
|
|
49
|
-
measureOptions: options.measure,
|
|
50
|
-
},
|
|
51
|
-
{ onLast: () => ({} as any) },
|
|
52
|
-
);
|
|
53
49
|
|
|
54
|
-
options.logger = options.logger ||
|
|
55
|
-
options.
|
|
50
|
+
options.logger = options.logger || defaultLogger;
|
|
51
|
+
options.metrics = options.metrics || defaultMetrics;
|
|
56
52
|
|
|
53
|
+
// initialize server
|
|
57
54
|
if (options.dev) {
|
|
58
55
|
this.server = this.createDevServer();
|
|
59
|
-
|
|
60
|
-
// check if https is configured when start dev server
|
|
61
|
-
const devHttpsOption =
|
|
62
|
-
typeof options.dev === 'object' && options.dev.https;
|
|
63
|
-
if (devHttpsOption) {
|
|
64
|
-
const { genHttpsOptions } = require('@/dev-tools/https');
|
|
65
|
-
const httpsOptions = await genHttpsOptions(devHttpsOption);
|
|
66
|
-
this.app = createHttpsServer(httpsOptions, this.getRequestHandler());
|
|
67
|
-
} else {
|
|
68
|
-
this.app = createServer(this.getRequestHandler());
|
|
69
|
-
}
|
|
70
56
|
} else {
|
|
71
57
|
this.server = this.createProdServer();
|
|
72
|
-
this.app = createServer(this.getRequestHandler());
|
|
73
58
|
}
|
|
59
|
+
// check if https is configured when start dev server
|
|
60
|
+
this.app = await this.server.createHTTPServer(this.getRequestHandler());
|
|
61
|
+
|
|
62
|
+
this.runner = await this.createHookRunner();
|
|
63
|
+
|
|
64
|
+
// runner can only be used after server init
|
|
65
|
+
await this.server.init(this.runner);
|
|
74
66
|
|
|
75
|
-
await this.server.init();
|
|
76
67
|
return this;
|
|
77
68
|
}
|
|
78
69
|
|
|
@@ -103,28 +94,70 @@ export class Server {
|
|
|
103
94
|
const { options } = this;
|
|
104
95
|
|
|
105
96
|
if (options.apiOnly) {
|
|
106
|
-
|
|
107
|
-
|
|
97
|
+
return new ModernAPIServer(options);
|
|
98
|
+
} else if (options.ssrOnly) {
|
|
99
|
+
return new ModernSSRServer(options);
|
|
108
100
|
} else if (options.webOnly) {
|
|
109
|
-
|
|
110
|
-
return new WebModernServer(options, this.runner);
|
|
101
|
+
return new ModernWebServer(options);
|
|
111
102
|
} else {
|
|
112
|
-
return new ModernServer(options
|
|
103
|
+
return new ModernServer(options);
|
|
113
104
|
}
|
|
114
105
|
}
|
|
115
106
|
|
|
116
107
|
private createDevServer() {
|
|
117
108
|
const { options } = this;
|
|
109
|
+
const {
|
|
110
|
+
ModernAPIDevServer,
|
|
111
|
+
ModernSSRDevServer,
|
|
112
|
+
ModernDevServer,
|
|
113
|
+
} = require('./dev-server');
|
|
118
114
|
|
|
119
115
|
if (options.apiOnly) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const { WebModernDevServer } = require('./web-server');
|
|
124
|
-
return new WebModernDevServer(options, this.runner);
|
|
116
|
+
return new ModernAPIDevServer(options);
|
|
117
|
+
} else if (options.ssrOnly) {
|
|
118
|
+
return new ModernSSRDevServer(options);
|
|
125
119
|
} else {
|
|
126
|
-
|
|
127
|
-
return new ModernDevServer(options, this.runner);
|
|
120
|
+
return new ModernDevServer(options);
|
|
128
121
|
}
|
|
129
122
|
}
|
|
123
|
+
|
|
124
|
+
private async createHookRunner() {
|
|
125
|
+
const { options } = this;
|
|
126
|
+
|
|
127
|
+
options.plugins?.forEach(p => {
|
|
128
|
+
serverManager.usePlugin(p);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const appContext = await this.initAppContext();
|
|
132
|
+
serverManager.run(() => {
|
|
133
|
+
ConfigContext.set(this.options.config as UserConfig);
|
|
134
|
+
AppContext.set({
|
|
135
|
+
...appContext,
|
|
136
|
+
distDirectory: path.join(
|
|
137
|
+
options.pwd,
|
|
138
|
+
options.config.output.path || 'dist',
|
|
139
|
+
),
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
return serverManager.init({});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private async initAppContext() {
|
|
147
|
+
const appDirectory = await initAppDir();
|
|
148
|
+
|
|
149
|
+
const loaded = await loadUserConfig(appDirectory);
|
|
150
|
+
|
|
151
|
+
const plugins = this.options.plugins?.map(p => ({
|
|
152
|
+
server: p,
|
|
153
|
+
cli: undefined,
|
|
154
|
+
}));
|
|
155
|
+
|
|
156
|
+
const appContext = initAppContext(
|
|
157
|
+
appDirectory,
|
|
158
|
+
plugins || [],
|
|
159
|
+
loaded.filePath,
|
|
160
|
+
);
|
|
161
|
+
return appContext;
|
|
162
|
+
}
|
|
130
163
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { APIServerStartInput } from '@modern-js/server-plugin';
|
|
2
|
+
import { ModernServer } from './modern-server';
|
|
3
|
+
import { mergeExtension } from '@/utils';
|
|
4
|
+
import { ModernRoute, ModernRouteInterface, RouteMatcher } from '@/libs/route';
|
|
5
|
+
import { ApiServerMode } from '@/constants';
|
|
6
|
+
import { ModernServerContext } from '@/libs/context';
|
|
7
|
+
|
|
8
|
+
export class ModernSSRServer extends ModernServer {
|
|
9
|
+
// Todo should not invoke any route hook in modernSSRServer
|
|
10
|
+
|
|
11
|
+
protected async warmupSSRBundle() {
|
|
12
|
+
// empty
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
protected verifyMatch(context: ModernServerContext, matched: RouteMatcher) {
|
|
16
|
+
if (matched.generate().isApi) {
|
|
17
|
+
this.render404(context);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
protected prepareAPIHandler(
|
|
22
|
+
_m: ApiServerMode,
|
|
23
|
+
_: APIServerStartInput['config'],
|
|
24
|
+
) {
|
|
25
|
+
return null as any;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
protected async prepareWebHandler(
|
|
29
|
+
extension: ReturnType<typeof mergeExtension>,
|
|
30
|
+
) {
|
|
31
|
+
return super.prepareWebHandler(extension);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// protected filterRoutes(routes: ModernRouteInterface[]) {
|
|
35
|
+
// return routes.filter(route => route.entryName);
|
|
36
|
+
// }
|
|
37
|
+
|
|
38
|
+
protected async preServerInit() {
|
|
39
|
+
// empty
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class ModernAPIServer extends ModernServer {
|
|
44
|
+
protected async emitRouteHook(_: string, _input: any) {
|
|
45
|
+
// empty
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected async warmupSSRBundle() {
|
|
49
|
+
// empty
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected prepareWebHandler(_: ReturnType<typeof mergeExtension>) {
|
|
53
|
+
return null as any;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
protected async prepareAPIHandler(
|
|
57
|
+
mode: ApiServerMode,
|
|
58
|
+
extension: APIServerStartInput['config'],
|
|
59
|
+
) {
|
|
60
|
+
return super.prepareAPIHandler(mode, extension);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
protected filterRoutes(routes: ModernRouteInterface[]) {
|
|
64
|
+
return routes.filter(route => route.isApi);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
protected async preServerInit() {
|
|
68
|
+
// empty
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export class ModernWebServer extends ModernServer {
|
|
73
|
+
protected async warmupSSRBundle() {
|
|
74
|
+
// empty
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
protected async handleAPI(context: ModernServerContext) {
|
|
78
|
+
const { proxyTarget } = this;
|
|
79
|
+
if (!proxyTarget?.api) {
|
|
80
|
+
this.proxy();
|
|
81
|
+
} else {
|
|
82
|
+
this.render404(context);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
protected async handleWeb(context: ModernServerContext, route: ModernRoute) {
|
|
87
|
+
const { proxyTarget } = this;
|
|
88
|
+
|
|
89
|
+
if (route.isSSR && proxyTarget?.ssr) {
|
|
90
|
+
return this.proxy();
|
|
91
|
+
} else {
|
|
92
|
+
// if no proxyTarget but access web server, degradation to csr
|
|
93
|
+
route.isSSR = false;
|
|
94
|
+
return super.handleWeb(context, route);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* eslint-disable max-lines */
|
|
2
|
-
import { IncomingMessage, ServerResponse, Server } from 'http';
|
|
2
|
+
import { IncomingMessage, ServerResponse, Server, createServer } from 'http';
|
|
3
3
|
import util from 'util';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { fs, ROUTE_SPEC_FILE } from '@modern-js/utils';
|
|
6
|
-
import { Adapter } from '@modern-js/server-plugin';
|
|
7
|
-
import {
|
|
6
|
+
import { Adapter, APIServerStartInput } from '@modern-js/server-plugin';
|
|
7
|
+
import { createMiddlewareCollecter } from '@modern-js/server-utils';
|
|
8
8
|
import type { NormalizedConfig } from '@modern-js/core';
|
|
9
9
|
import mime from 'mime-types';
|
|
10
10
|
import axios from 'axios';
|
|
@@ -12,17 +12,22 @@ import {
|
|
|
12
12
|
ModernServerOptions,
|
|
13
13
|
NextFunction,
|
|
14
14
|
ServerHookRunner,
|
|
15
|
-
|
|
15
|
+
Metrics,
|
|
16
16
|
Logger,
|
|
17
17
|
ReadyOptions,
|
|
18
18
|
ConfWithBFF,
|
|
19
|
-
} from '
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
} from '@/type';
|
|
20
|
+
import {
|
|
21
|
+
RouteMatchManager,
|
|
22
|
+
ModernRouteInterface,
|
|
23
|
+
ModernRoute,
|
|
24
|
+
RouteMatcher,
|
|
25
|
+
} from '@/libs/route';
|
|
26
|
+
import { createRenderHandler } from '@/libs/render';
|
|
27
|
+
import { createStaticFileHandler } from '@/libs/serve-file';
|
|
28
|
+
import { createErrorDocument, mergeExtension, noop } from '@/utils';
|
|
29
|
+
import * as reader from '@/libs/render/reader';
|
|
30
|
+
import { createProxyHandler, ProxyOptions } from '@/libs/proxy';
|
|
26
31
|
import { createContext, ModernServerContext } from '@/libs/context';
|
|
27
32
|
import {
|
|
28
33
|
AGGRED_DIR,
|
|
@@ -30,7 +35,8 @@ import {
|
|
|
30
35
|
ERROR_DIGEST,
|
|
31
36
|
ERROR_PAGE_TEXT,
|
|
32
37
|
} from '@/constants';
|
|
33
|
-
import { createTemplateAPI } from '@/libs/hook-api';
|
|
38
|
+
import { createTemplateAPI } from '@/libs/hook-api/template';
|
|
39
|
+
import { createRouteAPI } from '@/libs/hook-api/route';
|
|
34
40
|
|
|
35
41
|
type ModernServerHandler = (
|
|
36
42
|
context: ModernServerContext,
|
|
@@ -63,11 +69,13 @@ export class ModernServer {
|
|
|
63
69
|
|
|
64
70
|
protected presetRoutes?: ModernRouteInterface[];
|
|
65
71
|
|
|
72
|
+
protected runner!: ServerHookRunner;
|
|
73
|
+
|
|
66
74
|
protected readonly logger: Logger;
|
|
67
75
|
|
|
68
|
-
protected readonly
|
|
76
|
+
protected readonly metrics: Metrics;
|
|
69
77
|
|
|
70
|
-
|
|
78
|
+
protected readonly proxyTarget: ModernServerOptions['proxyTarget'];
|
|
71
79
|
|
|
72
80
|
private readonly isDev: boolean = false;
|
|
73
81
|
|
|
@@ -85,30 +93,28 @@ export class ModernServer {
|
|
|
85
93
|
|
|
86
94
|
private proxyHandler: ReturnType<typeof createProxyHandler> = null;
|
|
87
95
|
|
|
88
|
-
constructor(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
runner: ServerHookRunner,
|
|
99
|
-
) {
|
|
96
|
+
constructor({
|
|
97
|
+
pwd,
|
|
98
|
+
config,
|
|
99
|
+
dev,
|
|
100
|
+
routes,
|
|
101
|
+
staticGenerate,
|
|
102
|
+
logger,
|
|
103
|
+
metrics,
|
|
104
|
+
proxyTarget,
|
|
105
|
+
}: ModernServerOptions) {
|
|
100
106
|
require('ignore-styles');
|
|
101
107
|
this.isDev = Boolean(dev);
|
|
102
108
|
|
|
103
109
|
this.pwd = pwd;
|
|
104
|
-
this.distDir = path.join(pwd, config.output.path || '');
|
|
110
|
+
this.distDir = path.join(pwd, config.output.path || 'dist');
|
|
105
111
|
this.workDir = this.isDev ? pwd : this.distDir;
|
|
106
112
|
this.conf = config;
|
|
107
|
-
this.runner = runner;
|
|
108
113
|
this.logger = logger!;
|
|
109
|
-
this.
|
|
114
|
+
this.metrics = metrics!;
|
|
110
115
|
this.router = new RouteMatchManager();
|
|
111
116
|
this.presetRoutes = routes;
|
|
117
|
+
this.proxyTarget = proxyTarget;
|
|
112
118
|
|
|
113
119
|
if (staticGenerate) {
|
|
114
120
|
this.staticGenerate = staticGenerate;
|
|
@@ -122,7 +128,9 @@ export class ModernServer {
|
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
// server prepare
|
|
125
|
-
public async init() {
|
|
131
|
+
public async init(runner: ServerHookRunner) {
|
|
132
|
+
this.runner = runner;
|
|
133
|
+
|
|
126
134
|
const { distDir, isDev, staticGenerate, conf } = this;
|
|
127
135
|
|
|
128
136
|
this.addHandler((ctx: ModernServerContext, next: NextFunction) => {
|
|
@@ -198,16 +206,14 @@ export class ModernServer {
|
|
|
198
206
|
reader.close();
|
|
199
207
|
}
|
|
200
208
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
require(filepath);
|
|
210
|
-
});
|
|
209
|
+
public async createHTTPServer(
|
|
210
|
+
handler: (
|
|
211
|
+
req: IncomingMessage,
|
|
212
|
+
res: ServerResponse,
|
|
213
|
+
next?: () => void,
|
|
214
|
+
) => void,
|
|
215
|
+
) {
|
|
216
|
+
return createServer(handler);
|
|
211
217
|
}
|
|
212
218
|
|
|
213
219
|
// read route spec from route.json
|
|
@@ -239,14 +245,7 @@ export class ModernServer {
|
|
|
239
245
|
|
|
240
246
|
// gather frame extension and get framework handler
|
|
241
247
|
protected async prepareFrameHandler() {
|
|
242
|
-
const { workDir, runner
|
|
243
|
-
|
|
244
|
-
// inner tool, gather user inject
|
|
245
|
-
let userAPIExt = [];
|
|
246
|
-
let userWebExt = [];
|
|
247
|
-
if (!conf.server.disableUserExtension) {
|
|
248
|
-
({ api: userAPIExt, web: userWebExt } = gather(workDir));
|
|
249
|
-
}
|
|
248
|
+
const { workDir, runner } = this;
|
|
250
249
|
|
|
251
250
|
// server hook, gather plugin inject
|
|
252
251
|
const { getMiddlewares, ...collector } = createMiddlewareCollecter();
|
|
@@ -259,7 +258,7 @@ export class ModernServer {
|
|
|
259
258
|
|
|
260
259
|
// get api or web server handler from server-framework plugin
|
|
261
260
|
if (await fs.pathExists(path.join(serverDir))) {
|
|
262
|
-
const webExtension = mergeExtension(pluginWebExt
|
|
261
|
+
const webExtension = mergeExtension(pluginWebExt);
|
|
263
262
|
this.frameWebHandler = await this.prepareWebHandler(webExtension);
|
|
264
263
|
}
|
|
265
264
|
|
|
@@ -269,14 +268,16 @@ export class ModernServer {
|
|
|
269
268
|
: ApiServerMode.func;
|
|
270
269
|
|
|
271
270
|
// if use lambda/, mean framework style of writing, then discard user extension
|
|
272
|
-
const apiExtension = mergeExtension(
|
|
273
|
-
pluginAPIExt,
|
|
274
|
-
mode === ApiServerMode.frame ? [] : userAPIExt,
|
|
275
|
-
);
|
|
271
|
+
const apiExtension = mergeExtension(pluginAPIExt);
|
|
276
272
|
this.frameAPIHandler = await this.prepareAPIHandler(mode, apiExtension);
|
|
277
273
|
}
|
|
278
274
|
}
|
|
279
275
|
|
|
276
|
+
// Todo
|
|
277
|
+
protected async proxy() {
|
|
278
|
+
return null as any;
|
|
279
|
+
}
|
|
280
|
+
|
|
280
281
|
/* —————————————————————— function will be overwrite —————————————————————— */
|
|
281
282
|
protected async prepareWebHandler(
|
|
282
283
|
extension: ReturnType<typeof mergeExtension>,
|
|
@@ -294,7 +295,7 @@ export class ModernServer {
|
|
|
294
295
|
|
|
295
296
|
protected async prepareAPIHandler(
|
|
296
297
|
mode: ApiServerMode,
|
|
297
|
-
extension:
|
|
298
|
+
extension: APIServerStartInput['config'],
|
|
298
299
|
) {
|
|
299
300
|
const { workDir, runner, conf } = this;
|
|
300
301
|
const { bff } = conf as ConfWithBFF;
|
|
@@ -305,7 +306,7 @@ export class ModernServer {
|
|
|
305
306
|
pwd: workDir,
|
|
306
307
|
mode,
|
|
307
308
|
config: extension,
|
|
308
|
-
prefix,
|
|
309
|
+
prefix: Array.isArray(prefix) ? prefix[0] : prefix,
|
|
309
310
|
},
|
|
310
311
|
{ onLast: () => null as any },
|
|
311
312
|
);
|
|
@@ -315,62 +316,89 @@ export class ModernServer {
|
|
|
315
316
|
return routes;
|
|
316
317
|
}
|
|
317
318
|
|
|
319
|
+
protected async emitRouteHook(
|
|
320
|
+
eventName: 'beforeMatch' | 'afterMatch' | 'beforeRender' | 'afterRender',
|
|
321
|
+
input: any,
|
|
322
|
+
) {
|
|
323
|
+
return this.runner[eventName](input, { onLast: noop as any });
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// warmup ssr function
|
|
327
|
+
protected warmupSSRBundle() {
|
|
328
|
+
const { distDir } = this;
|
|
329
|
+
const bundles = this.router.getBundles();
|
|
330
|
+
|
|
331
|
+
bundles.forEach(bundle => {
|
|
332
|
+
const filepath = path.join(distDir, bundle as string);
|
|
333
|
+
// if error, just throw and let process die
|
|
334
|
+
require(filepath);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
318
338
|
protected async preServerInit() {
|
|
319
|
-
const { conf } = this;
|
|
339
|
+
const { conf, runner } = this;
|
|
320
340
|
const preMiddleware: ModernServerAsyncHandler[] =
|
|
321
|
-
await
|
|
341
|
+
await runner.preServerInit(conf);
|
|
322
342
|
|
|
323
|
-
preMiddleware.forEach(mid => {
|
|
343
|
+
preMiddleware.flat().forEach(mid => {
|
|
324
344
|
this.addHandler(mid);
|
|
325
345
|
});
|
|
326
346
|
}
|
|
327
347
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (favicon) {
|
|
334
|
-
faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
|
|
335
|
-
}
|
|
336
|
-
if (faviconByEntries) {
|
|
337
|
-
Object.keys(faviconByEntries).forEach(f => {
|
|
338
|
-
const curFavicon = faviconByEntries[f];
|
|
339
|
-
if (curFavicon) {
|
|
340
|
-
faviconNames.push(
|
|
341
|
-
curFavicon.substring(curFavicon.lastIndexOf('/') + 1),
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
});
|
|
348
|
+
protected async handleAPI(context: ModernServerContext) {
|
|
349
|
+
const { req, res } = context;
|
|
350
|
+
|
|
351
|
+
if (!this.frameAPIHandler) {
|
|
352
|
+
throw new Error('can not found api hanlder');
|
|
345
353
|
}
|
|
346
|
-
|
|
354
|
+
|
|
355
|
+
await this.frameAPIHandler(req, res);
|
|
347
356
|
}
|
|
348
357
|
|
|
349
|
-
|
|
358
|
+
protected async handleWeb(context: ModernServerContext, route: ModernRoute) {
|
|
359
|
+
return this.routeRenderHandler(context, route);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
protected verifyMatch(_c: ModernServerContext, _m: RouteMatcher) {
|
|
363
|
+
// empty
|
|
364
|
+
}
|
|
350
365
|
|
|
366
|
+
/* —————————————————————— private function —————————————————————— */
|
|
351
367
|
// handler route.json, include api / csr / ssr
|
|
352
368
|
// eslint-disable-next-line max-statements
|
|
353
369
|
private async routeHandler(context: ModernServerContext) {
|
|
354
370
|
const { req, res } = context;
|
|
355
371
|
|
|
372
|
+
await this.emitRouteHook('beforeMatch', { context });
|
|
373
|
+
|
|
356
374
|
// match routes in the route spec
|
|
357
375
|
const matched = this.router.match(context.url);
|
|
358
376
|
if (!matched) {
|
|
359
377
|
this.render404(context);
|
|
360
378
|
return;
|
|
379
|
+
} else {
|
|
380
|
+
this.verifyMatch(context, matched);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (res.headersSent) {
|
|
384
|
+
return;
|
|
361
385
|
}
|
|
362
386
|
|
|
363
|
-
const
|
|
364
|
-
|
|
387
|
+
const routeAPI = createRouteAPI(matched, this.router);
|
|
388
|
+
await this.emitRouteHook('afterMatch', { context, routeAPI });
|
|
389
|
+
|
|
390
|
+
if (res.headersSent) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const { current } = routeAPI as any;
|
|
395
|
+
const route: ModernRoute = current.generate();
|
|
396
|
+
const params = current.parseURLParams(context.url);
|
|
365
397
|
context.setParams(params);
|
|
366
398
|
|
|
367
399
|
// route is api service
|
|
368
400
|
if (route.isApi) {
|
|
369
|
-
|
|
370
|
-
throw new Error('can not found api hanlder');
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
await this.frameAPIHandler(req, res);
|
|
401
|
+
this.handleAPI(context);
|
|
374
402
|
return;
|
|
375
403
|
}
|
|
376
404
|
|
|
@@ -383,7 +411,11 @@ export class ModernServer {
|
|
|
383
411
|
return;
|
|
384
412
|
}
|
|
385
413
|
|
|
386
|
-
|
|
414
|
+
if (route.entryName) {
|
|
415
|
+
await this.emitRouteHook('beforeRender', { context });
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const file = await this.handleWeb(context, route);
|
|
387
419
|
if (!file) {
|
|
388
420
|
this.render404(context);
|
|
389
421
|
return;
|
|
@@ -399,10 +431,7 @@ export class ModernServer {
|
|
|
399
431
|
let response = file.content;
|
|
400
432
|
if (route.entryName) {
|
|
401
433
|
const templateAPI = createTemplateAPI(file.content.toString());
|
|
402
|
-
await this.
|
|
403
|
-
{ context, templateAPI },
|
|
404
|
-
{ onLast: noop as any },
|
|
405
|
-
);
|
|
434
|
+
await this.emitRouteHook('afterRender', { context, templateAPI });
|
|
406
435
|
await this.injectMicroFE(context, templateAPI);
|
|
407
436
|
response = templateAPI.get();
|
|
408
437
|
}
|
|
@@ -519,7 +548,7 @@ export class ModernServer {
|
|
|
519
548
|
res.statusCode = 200;
|
|
520
549
|
const context: ModernServerContext = createContext(req, res, {
|
|
521
550
|
logger: this.logger,
|
|
522
|
-
|
|
551
|
+
metrics: this.metrics,
|
|
523
552
|
});
|
|
524
553
|
|
|
525
554
|
try {
|
|
@@ -565,5 +594,26 @@ export class ModernServer {
|
|
|
565
594
|
const text = ERROR_PAGE_TEXT[status] || ERROR_PAGE_TEXT[500];
|
|
566
595
|
res.end(createErrorDocument(status, text));
|
|
567
596
|
}
|
|
597
|
+
|
|
598
|
+
private prepareFavicons(
|
|
599
|
+
favicon: string | undefined,
|
|
600
|
+
faviconByEntries?: Record<string, string | undefined>,
|
|
601
|
+
) {
|
|
602
|
+
const faviconNames = [];
|
|
603
|
+
if (favicon) {
|
|
604
|
+
faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
|
|
605
|
+
}
|
|
606
|
+
if (faviconByEntries) {
|
|
607
|
+
Object.keys(faviconByEntries).forEach(f => {
|
|
608
|
+
const curFavicon = faviconByEntries[f];
|
|
609
|
+
if (curFavicon) {
|
|
610
|
+
faviconNames.push(
|
|
611
|
+
curFavicon.substring(curFavicon.lastIndexOf('/') + 1),
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
return faviconNames;
|
|
617
|
+
}
|
|
568
618
|
}
|
|
569
619
|
/* eslint-enable max-lines */
|
package/src/type.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Buffer } from 'buffer';
|
|
|
2
2
|
import type Webpack from 'webpack';
|
|
3
3
|
import { serverManager } from '@modern-js/server-plugin';
|
|
4
4
|
import type { NormalizedConfig } from '@modern-js/core';
|
|
5
|
-
import type {
|
|
5
|
+
import type { Metrics, Logger, NextFunction } from '@modern-js/types/server';
|
|
6
6
|
import { ModernRouteInterface } from './libs/route';
|
|
7
7
|
|
|
8
8
|
declare module '@modern-js/core' {
|
|
@@ -45,11 +45,16 @@ export type ModernServerOptions = {
|
|
|
45
45
|
staticGenerate?: boolean;
|
|
46
46
|
customServer?: boolean;
|
|
47
47
|
loggerOptions?: Record<string, string>;
|
|
48
|
-
|
|
48
|
+
metricsOptions?: Record<string, string>;
|
|
49
49
|
logger?: Logger;
|
|
50
|
-
|
|
50
|
+
metrics?: Metrics;
|
|
51
51
|
apiOnly?: boolean;
|
|
52
|
+
ssrOnly?: boolean;
|
|
52
53
|
webOnly?: boolean;
|
|
54
|
+
proxyTarget?: {
|
|
55
|
+
ssr?: string;
|
|
56
|
+
api?: string;
|
|
57
|
+
};
|
|
53
58
|
};
|
|
54
59
|
|
|
55
60
|
export type RenderResult = {
|
|
@@ -71,4 +76,4 @@ export type ServerHookRunner = Then<ReturnType<typeof serverManager.init>>;
|
|
|
71
76
|
|
|
72
77
|
export type ReadyOptions = { routes?: ModernRouteInterface[] };
|
|
73
78
|
|
|
74
|
-
export type {
|
|
79
|
+
export type { Metrics, Logger, NextFunction };
|