@modern-js/server 1.1.3-beta.0 → 1.1.4
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 +42 -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/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/cache/type.js +0 -1
- package/dist/js/modern/server/dev-server/dev-server-split.js +2 -6
- package/dist/js/modern/server/dev-server/dev-server.js +1 -1
- package/dist/js/modern/server/dev-server/index.js +1 -1
- package/dist/js/modern/server/index.js +17 -14
- package/dist/js/modern/server/modern-server-split.js +55 -6
- package/dist/js/modern/server/modern-server.js +85 -55
- package/dist/js/modern/type.js +0 -1
- package/dist/js/modern/utils.js +9 -1
- 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/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/server/dev-server/dev-server-split.js +5 -9
- package/dist/js/node/server/dev-server/dev-server.js +1 -1
- package/dist/js/node/server/dev-server/index.js +4 -4
- package/dist/js/node/server/index.js +16 -12
- package/dist/js/node/server/modern-server-split.js +61 -9
- package/dist/js/node/server/modern-server.js +86 -56
- package/dist/js/node/utils.js +12 -2
- package/dist/types/server/dev-server/dev-server-split.d.ts +3 -4
- package/dist/types/server/dev-server/index.d.ts +1 -1
- package/dist/types/server/modern-server-split.d.ts +15 -5
- package/dist/types/server/modern-server.d.ts +13 -6
- package/dist/types/type.d.ts +5 -0
- package/dist/types/utils.d.ts +2 -1
- package/package.json +17 -18
- package/src/server/dev-server/dev-server-split.ts +3 -7
- package/src/server/dev-server/dev-server.ts +7 -11
- package/src/server/dev-server/index.ts +1 -1
- package/src/server/index.ts +22 -12
- package/src/server/modern-server-split.ts +59 -7
- package/src/server/modern-server.ts +96 -62
- package/src/type.ts +5 -0
- package/src/utils.ts +14 -0
package/dist/types/type.d.ts
CHANGED
|
@@ -45,7 +45,12 @@ export declare type ModernServerOptions = {
|
|
|
45
45
|
logger?: Logger;
|
|
46
46
|
measure?: Measure;
|
|
47
47
|
apiOnly?: boolean;
|
|
48
|
+
ssrOnly?: boolean;
|
|
48
49
|
webOnly?: boolean;
|
|
50
|
+
proxyTarget?: {
|
|
51
|
+
ssr?: string;
|
|
52
|
+
api?: string;
|
|
53
|
+
};
|
|
49
54
|
};
|
|
50
55
|
export declare type RenderResult = {
|
|
51
56
|
content: string | Buffer;
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export declare const mergeExtension: (users: any[]) => {
|
|
|
3
3
|
};
|
|
4
4
|
export declare const toMessage: (dig: string, e: Error | string) => string;
|
|
5
5
|
export declare const noop: () => void;
|
|
6
|
-
export declare const createErrorDocument: (status: number, text: string) => string;
|
|
6
|
+
export declare const createErrorDocument: (status: number, text: string) => string;
|
|
7
|
+
export declare function applyMixins(derivedCtor: any, constructors: any[]): void;
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.1.
|
|
14
|
+
"version": "1.1.4",
|
|
15
15
|
"jsnext:source": "./src/index.ts",
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
17
|
"main": "./dist/js/node/index.js",
|
|
@@ -26,14 +26,6 @@
|
|
|
26
26
|
"default": "./dist/js/treeshaking/index.js"
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
|
-
"scripts": {
|
|
30
|
-
"prepare": "pnpm build",
|
|
31
|
-
"prepublishOnly": "pnpm build --platform",
|
|
32
|
-
"new": "modern new",
|
|
33
|
-
"build": "modern build",
|
|
34
|
-
"dev": "modern build --watch",
|
|
35
|
-
"test": "modern test --passWithNoTests"
|
|
36
|
-
},
|
|
37
29
|
"dependencies": {
|
|
38
30
|
"@babel/core": "^7.15.0",
|
|
39
31
|
"@babel/compat-data": "^7.15.0",
|
|
@@ -41,12 +33,12 @@
|
|
|
41
33
|
"@babel/preset-typescript": "^7.15.0",
|
|
42
34
|
"@babel/register": "^7.15.3",
|
|
43
35
|
"@babel/runtime": "^7",
|
|
44
|
-
"@modern-js/core": "
|
|
45
|
-
"@modern-js/hmr-client": "
|
|
46
|
-
"@modern-js/server-plugin": "
|
|
47
|
-
"@modern-js/server-utils": "
|
|
48
|
-
"@modern-js/bff-utils": "
|
|
49
|
-
"@modern-js/utils": "
|
|
36
|
+
"@modern-js/core": "^1.1.4",
|
|
37
|
+
"@modern-js/hmr-client": "^1.1.1",
|
|
38
|
+
"@modern-js/server-plugin": "^1.1.2",
|
|
39
|
+
"@modern-js/server-utils": "^1.1.2",
|
|
40
|
+
"@modern-js/bff-utils": "^1.1.1",
|
|
41
|
+
"@modern-js/utils": "^1.1.4",
|
|
50
42
|
"axios": "^0.21.4",
|
|
51
43
|
"babel-plugin-module-resolver": "^4.1.0",
|
|
52
44
|
"chokidar": "^3.5.2",
|
|
@@ -71,7 +63,7 @@
|
|
|
71
63
|
"devDependencies": {
|
|
72
64
|
"@modern-js/module-tools": "^1.1.1",
|
|
73
65
|
"@modern-js/plugin-testing": "^1.1.1",
|
|
74
|
-
"@modern-js/types": "
|
|
66
|
+
"@modern-js/types": "^1.1.3",
|
|
75
67
|
"@types/jest": "^26",
|
|
76
68
|
"@types/lru-cache": "^5.1.1",
|
|
77
69
|
"@types/mime-types": "^2.1.0",
|
|
@@ -100,5 +92,12 @@
|
|
|
100
92
|
"publishConfig": {
|
|
101
93
|
"registry": "https://registry.npmjs.org/",
|
|
102
94
|
"access": "public"
|
|
103
|
-
}
|
|
104
|
-
|
|
95
|
+
},
|
|
96
|
+
"scripts": {
|
|
97
|
+
"new": "modern new",
|
|
98
|
+
"build": "modern build",
|
|
99
|
+
"dev": "modern build --watch",
|
|
100
|
+
"test": "modern test --passWithNoTests"
|
|
101
|
+
},
|
|
102
|
+
"readme": "\n<p align=\"center\">\n <a href=\"https://modernjs.dev\" target=\"blank\"><img src=\"https://lf3-static.bytednsdoc.com/obj/eden-cn/ylaelkeh7nuhfnuhf/modernjs-cover.png\" width=\"300\" alt=\"Modern.js Logo\" /></a>\n</p>\n<p align=\"center\">\n现代 Web 工程体系\n <br/>\n <a href=\"https://modernjs.dev\" target=\"blank\">\n modernjs.dev\n </a>\n</p>\n<p align=\"center\">\n The meta-framework suite designed from scratch for frontend-focused modern web development\n</p>\n\n# Introduction\n\n> The doc site ([modernjs.dev](https://modernjs.dev)) and articles are only available in Chinese for now, we are planning to add English versions soon.\n\n- [Modern.js: Hello, World!](https://zhuanlan.zhihu.com/p/426707646)\n\n## Getting Started\n\n- [Quick Start](https://modernjs.dev/docs/start)\n- [Guides](https://modernjs.dev/docs/guides)\n- [API References](https://modernjs.dev/docs/apis)\n\n## Contributing\n\n- [Contributing Guide](https://github.com/modern-js-dev/modern.js/blob/main/CONTRIBUTING.md)\n"
|
|
103
|
+
}
|
|
@@ -4,7 +4,7 @@ import { mergeExtension } from '@/utils';
|
|
|
4
4
|
import { ModernRouteInterface } from '@/libs/route';
|
|
5
5
|
import { ApiServerMode } from '@/constants';
|
|
6
6
|
|
|
7
|
-
export class
|
|
7
|
+
export class ModernSSRDevServer extends ModernDevServer {
|
|
8
8
|
protected prepareAPIHandler(
|
|
9
9
|
_m: ApiServerMode,
|
|
10
10
|
_: APIServerStartInput['config'],
|
|
@@ -23,14 +23,10 @@ export class WebModernDevServer extends ModernDevServer {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export class
|
|
27
|
-
protected prepareWebHandler(_: ReturnType<typeof mergeExtension>) {
|
|
28
|
-
return null as any;
|
|
29
|
-
}
|
|
30
|
-
|
|
26
|
+
export class ModernAPIDevServer extends ModernDevServer {
|
|
31
27
|
protected async prepareAPIHandler(
|
|
32
28
|
mode: ApiServerMode,
|
|
33
|
-
extension:
|
|
29
|
+
extension: APIServerStartInput['config'],
|
|
34
30
|
) {
|
|
35
31
|
return super.prepareAPIHandler(mode, extension);
|
|
36
32
|
}
|
|
@@ -13,9 +13,7 @@ import {
|
|
|
13
13
|
SHARED_DIR,
|
|
14
14
|
} from '@modern-js/utils';
|
|
15
15
|
import type { MultiCompiler, Compiler } from 'webpack';
|
|
16
|
-
import webpackDevMiddleware
|
|
17
|
-
WebpackDevMiddleware,
|
|
18
|
-
} from 'webpack-dev-middleware';
|
|
16
|
+
import webpackDevMiddleware from 'webpack-dev-middleware';
|
|
19
17
|
import { ModernServer } from '../modern-server';
|
|
20
18
|
import { createMockHandler } from '@/dev-tools/mock';
|
|
21
19
|
import { createProxyHandler, ProxyOptions } from '@/libs/proxy';
|
|
@@ -61,12 +59,10 @@ export class ModernDevServer extends ModernServer {
|
|
|
61
59
|
|
|
62
60
|
private watcher!: Watcher;
|
|
63
61
|
|
|
64
|
-
private devMiddleware!:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
next: NextFunction,
|
|
69
|
-
) => void);
|
|
62
|
+
private devMiddleware!: webpackDevMiddleware.API<
|
|
63
|
+
http.IncomingMessage,
|
|
64
|
+
http.ServerResponse
|
|
65
|
+
>;
|
|
70
66
|
|
|
71
67
|
constructor(options: ModernServerOptions) {
|
|
72
68
|
super(options);
|
|
@@ -239,7 +235,7 @@ export class ModernDevServer extends ModernServer {
|
|
|
239
235
|
const bundles = this.router.getBundles();
|
|
240
236
|
|
|
241
237
|
bundles.forEach(bundle => {
|
|
242
|
-
const filepath = path.join(distDir, bundle
|
|
238
|
+
const filepath = path.join(distDir, bundle as string);
|
|
243
239
|
if (require.cache[filepath]) {
|
|
244
240
|
delete require.cache[filepath];
|
|
245
241
|
}
|
|
@@ -252,7 +248,7 @@ export class ModernDevServer extends ModernServer {
|
|
|
252
248
|
const defaultWatched = [
|
|
253
249
|
`${pwd}/${mock}/**/*`,
|
|
254
250
|
`${pwd}/${SERVER_DIR}/**/*`,
|
|
255
|
-
`${pwd}/${API_DIR}
|
|
251
|
+
`${pwd}/${API_DIR}/!(typings)/**`,
|
|
256
252
|
`${pwd}/${SHARED_DIR}/**/*`,
|
|
257
253
|
];
|
|
258
254
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ModernAPIDevServer, ModernSSRDevServer } from './dev-server-split';
|
|
2
2
|
export { ModernDevServer } from './dev-server';
|
package/src/server/index.ts
CHANGED
|
@@ -7,10 +7,16 @@ import {
|
|
|
7
7
|
initAppContext,
|
|
8
8
|
initAppDir,
|
|
9
9
|
loadUserConfig,
|
|
10
|
+
ConfigContext,
|
|
11
|
+
UserConfig,
|
|
10
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';
|
|
14
20
|
import { ModernServerOptions, ServerHookRunner, ReadyOptions } from '@/type';
|
|
15
21
|
import { measure as defaultMeasure } from '@/libs/measure';
|
|
16
22
|
|
|
@@ -88,9 +94,11 @@ export class Server {
|
|
|
88
94
|
const { options } = this;
|
|
89
95
|
|
|
90
96
|
if (options.apiOnly) {
|
|
91
|
-
return new
|
|
97
|
+
return new ModernAPIServer(options);
|
|
98
|
+
} else if (options.ssrOnly) {
|
|
99
|
+
return new ModernSSRServer(options);
|
|
92
100
|
} else if (options.webOnly) {
|
|
93
|
-
return new
|
|
101
|
+
return new ModernWebServer(options);
|
|
94
102
|
} else {
|
|
95
103
|
return new ModernServer(options);
|
|
96
104
|
}
|
|
@@ -99,15 +107,15 @@ export class Server {
|
|
|
99
107
|
private createDevServer() {
|
|
100
108
|
const { options } = this;
|
|
101
109
|
const {
|
|
102
|
-
|
|
103
|
-
|
|
110
|
+
ModernAPIDevServer,
|
|
111
|
+
ModernSSRDevServer,
|
|
104
112
|
ModernDevServer,
|
|
105
113
|
} = require('./dev-server');
|
|
106
114
|
|
|
107
115
|
if (options.apiOnly) {
|
|
108
|
-
return new
|
|
109
|
-
} else if (options.
|
|
110
|
-
return new
|
|
116
|
+
return new ModernAPIDevServer(options);
|
|
117
|
+
} else if (options.ssrOnly) {
|
|
118
|
+
return new ModernSSRDevServer(options);
|
|
111
119
|
} else {
|
|
112
120
|
return new ModernDevServer(options);
|
|
113
121
|
}
|
|
@@ -115,8 +123,14 @@ export class Server {
|
|
|
115
123
|
|
|
116
124
|
private async createHookRunner() {
|
|
117
125
|
const { options } = this;
|
|
126
|
+
|
|
127
|
+
options.plugins?.forEach(p => {
|
|
128
|
+
serverManager.usePlugin(p);
|
|
129
|
+
});
|
|
130
|
+
|
|
118
131
|
const appContext = await this.initAppContext();
|
|
119
132
|
serverManager.run(() => {
|
|
133
|
+
ConfigContext.set(this.options.config as UserConfig);
|
|
120
134
|
AppContext.set({
|
|
121
135
|
...appContext,
|
|
122
136
|
distDirectory: path.join(
|
|
@@ -126,10 +140,6 @@ export class Server {
|
|
|
126
140
|
});
|
|
127
141
|
});
|
|
128
142
|
|
|
129
|
-
options.plugins?.forEach(p => {
|
|
130
|
-
serverManager.usePlugin(p);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
143
|
return serverManager.init({});
|
|
134
144
|
}
|
|
135
145
|
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import { APIServerStartInput } from '@modern-js/server-plugin';
|
|
2
2
|
import { ModernServer } from './modern-server';
|
|
3
3
|
import { mergeExtension } from '@/utils';
|
|
4
|
-
import { ModernRouteInterface } from '@/libs/route';
|
|
4
|
+
import { ModernRoute, ModernRouteInterface, RouteMatcher } from '@/libs/route';
|
|
5
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
|
+
}
|
|
6
20
|
|
|
7
|
-
export class WebModernServer extends ModernServer {
|
|
8
21
|
protected prepareAPIHandler(
|
|
9
22
|
_m: ApiServerMode,
|
|
10
|
-
_:
|
|
23
|
+
_: APIServerStartInput['config'],
|
|
11
24
|
) {
|
|
12
25
|
return null as any;
|
|
13
26
|
}
|
|
@@ -18,12 +31,24 @@ export class WebModernServer extends ModernServer {
|
|
|
18
31
|
return super.prepareWebHandler(extension);
|
|
19
32
|
}
|
|
20
33
|
|
|
21
|
-
protected filterRoutes(routes: ModernRouteInterface[]) {
|
|
22
|
-
|
|
34
|
+
// protected filterRoutes(routes: ModernRouteInterface[]) {
|
|
35
|
+
// return routes.filter(route => route.entryName);
|
|
36
|
+
// }
|
|
37
|
+
|
|
38
|
+
protected async preServerInit() {
|
|
39
|
+
// empty
|
|
23
40
|
}
|
|
24
41
|
}
|
|
25
42
|
|
|
26
|
-
export class
|
|
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
|
+
|
|
27
52
|
protected prepareWebHandler(_: ReturnType<typeof mergeExtension>) {
|
|
28
53
|
return null as any;
|
|
29
54
|
}
|
|
@@ -40,6 +65,33 @@ export class APIModernServer extends ModernServer {
|
|
|
40
65
|
}
|
|
41
66
|
|
|
42
67
|
protected async preServerInit() {
|
|
43
|
-
//
|
|
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
|
+
}
|
|
44
96
|
}
|
|
45
97
|
}
|
|
@@ -16,13 +16,18 @@ import {
|
|
|
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,
|
|
@@ -70,6 +75,8 @@ export class ModernServer {
|
|
|
70
75
|
|
|
71
76
|
protected readonly measure: Measure;
|
|
72
77
|
|
|
78
|
+
protected readonly proxyTarget: ModernServerOptions['proxyTarget'];
|
|
79
|
+
|
|
73
80
|
private readonly isDev: boolean = false;
|
|
74
81
|
|
|
75
82
|
private staticFileHandler!: ReturnType<typeof createStaticFileHandler>;
|
|
@@ -94,18 +101,20 @@ export class ModernServer {
|
|
|
94
101
|
staticGenerate,
|
|
95
102
|
logger,
|
|
96
103
|
measure,
|
|
104
|
+
proxyTarget,
|
|
97
105
|
}: ModernServerOptions) {
|
|
98
106
|
require('ignore-styles');
|
|
99
107
|
this.isDev = Boolean(dev);
|
|
100
108
|
|
|
101
109
|
this.pwd = pwd;
|
|
102
|
-
this.distDir = path.join(pwd, config.output.path || '');
|
|
110
|
+
this.distDir = path.join(pwd, config.output.path || 'dist');
|
|
103
111
|
this.workDir = this.isDev ? pwd : this.distDir;
|
|
104
112
|
this.conf = config;
|
|
105
113
|
this.logger = logger!;
|
|
106
114
|
this.measure = measure!;
|
|
107
115
|
this.router = new RouteMatchManager();
|
|
108
116
|
this.presetRoutes = routes;
|
|
117
|
+
this.proxyTarget = proxyTarget;
|
|
109
118
|
|
|
110
119
|
if (staticGenerate) {
|
|
111
120
|
this.staticGenerate = staticGenerate;
|
|
@@ -207,18 +216,6 @@ export class ModernServer {
|
|
|
207
216
|
return createServer(handler);
|
|
208
217
|
}
|
|
209
218
|
|
|
210
|
-
// warmup ssr function
|
|
211
|
-
protected warmupSSRBundle() {
|
|
212
|
-
const { distDir } = this;
|
|
213
|
-
const bundles = this.router.getBundles();
|
|
214
|
-
|
|
215
|
-
bundles.forEach(bundle => {
|
|
216
|
-
const filepath = path.join(distDir, bundle!);
|
|
217
|
-
// if error, just throw and let process die
|
|
218
|
-
require(filepath);
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
|
|
222
219
|
// read route spec from route.json
|
|
223
220
|
protected readRouteSpec() {
|
|
224
221
|
const file = path.join(this.distDir, ROUTE_SPEC_FILE);
|
|
@@ -272,13 +269,15 @@ export class ModernServer {
|
|
|
272
269
|
|
|
273
270
|
// if use lambda/, mean framework style of writing, then discard user extension
|
|
274
271
|
const apiExtension = mergeExtension(pluginAPIExt);
|
|
275
|
-
this.frameAPIHandler = await this.prepareAPIHandler(mode,
|
|
276
|
-
...apiExtension,
|
|
277
|
-
modernJsConfig: this.conf,
|
|
278
|
-
});
|
|
272
|
+
this.frameAPIHandler = await this.prepareAPIHandler(mode, apiExtension);
|
|
279
273
|
}
|
|
280
274
|
}
|
|
281
275
|
|
|
276
|
+
// Todo
|
|
277
|
+
protected async proxy() {
|
|
278
|
+
return null as any;
|
|
279
|
+
}
|
|
280
|
+
|
|
282
281
|
/* —————————————————————— function will be overwrite —————————————————————— */
|
|
283
282
|
protected async prepareWebHandler(
|
|
284
283
|
extension: ReturnType<typeof mergeExtension>,
|
|
@@ -317,75 +316,89 @@ export class ModernServer {
|
|
|
317
316
|
return routes;
|
|
318
317
|
}
|
|
319
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
|
+
|
|
320
338
|
protected async preServerInit() {
|
|
321
|
-
const { conf } = this;
|
|
339
|
+
const { conf, runner } = this;
|
|
322
340
|
const preMiddleware: ModernServerAsyncHandler[] =
|
|
323
|
-
await
|
|
341
|
+
await runner.preServerInit(conf);
|
|
324
342
|
|
|
325
343
|
preMiddleware.flat().forEach(mid => {
|
|
326
344
|
this.addHandler(mid);
|
|
327
345
|
});
|
|
328
346
|
}
|
|
329
347
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
if (favicon) {
|
|
336
|
-
faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
|
|
337
|
-
}
|
|
338
|
-
if (faviconByEntries) {
|
|
339
|
-
Object.keys(faviconByEntries).forEach(f => {
|
|
340
|
-
const curFavicon = faviconByEntries[f];
|
|
341
|
-
if (curFavicon) {
|
|
342
|
-
faviconNames.push(
|
|
343
|
-
curFavicon.substring(curFavicon.lastIndexOf('/') + 1),
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
});
|
|
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');
|
|
347
353
|
}
|
|
348
|
-
|
|
354
|
+
|
|
355
|
+
await this.frameAPIHandler(req, res);
|
|
349
356
|
}
|
|
350
357
|
|
|
351
|
-
|
|
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
|
+
}
|
|
352
365
|
|
|
366
|
+
/* —————————————————————— private function —————————————————————— */
|
|
353
367
|
// handler route.json, include api / csr / ssr
|
|
354
368
|
// eslint-disable-next-line max-statements
|
|
355
369
|
private async routeHandler(context: ModernServerContext) {
|
|
356
370
|
const { req, res } = context;
|
|
357
371
|
|
|
358
|
-
await this.
|
|
372
|
+
await this.emitRouteHook('beforeMatch', { context });
|
|
359
373
|
|
|
360
374
|
// match routes in the route spec
|
|
361
375
|
const matched = this.router.match(context.url);
|
|
362
376
|
if (!matched) {
|
|
363
377
|
this.render404(context);
|
|
364
378
|
return;
|
|
379
|
+
} else {
|
|
380
|
+
this.verifyMatch(context, matched);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (res.headersSent) {
|
|
384
|
+
return;
|
|
365
385
|
}
|
|
366
386
|
|
|
367
387
|
const routeAPI = createRouteAPI(matched, this.router);
|
|
368
|
-
await this.
|
|
369
|
-
{ context, routeAPI },
|
|
370
|
-
{ onLast: noop as any },
|
|
371
|
-
);
|
|
388
|
+
await this.emitRouteHook('afterMatch', { context, routeAPI });
|
|
372
389
|
|
|
373
390
|
if (res.headersSent) {
|
|
374
391
|
return;
|
|
375
392
|
}
|
|
376
393
|
|
|
377
394
|
const { current } = routeAPI as any;
|
|
378
|
-
const route = current.generate();
|
|
395
|
+
const route: ModernRoute = current.generate();
|
|
379
396
|
const params = current.parseURLParams(context.url);
|
|
380
397
|
context.setParams(params);
|
|
381
398
|
|
|
382
399
|
// route is api service
|
|
383
400
|
if (route.isApi) {
|
|
384
|
-
|
|
385
|
-
throw new Error('can not found api hanlder');
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
await this.frameAPIHandler(req, res);
|
|
401
|
+
this.handleAPI(context);
|
|
389
402
|
return;
|
|
390
403
|
}
|
|
391
404
|
|
|
@@ -398,8 +411,11 @@ export class ModernServer {
|
|
|
398
411
|
return;
|
|
399
412
|
}
|
|
400
413
|
|
|
401
|
-
|
|
402
|
-
|
|
414
|
+
if (route.entryName) {
|
|
415
|
+
await this.emitRouteHook('beforeRender', { context });
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const file = await this.handleWeb(context, route);
|
|
403
419
|
if (!file) {
|
|
404
420
|
this.render404(context);
|
|
405
421
|
return;
|
|
@@ -415,10 +431,7 @@ export class ModernServer {
|
|
|
415
431
|
let response = file.content;
|
|
416
432
|
if (route.entryName) {
|
|
417
433
|
const templateAPI = createTemplateAPI(file.content.toString());
|
|
418
|
-
await this.
|
|
419
|
-
{ context, templateAPI },
|
|
420
|
-
{ onLast: noop as any },
|
|
421
|
-
);
|
|
434
|
+
await this.emitRouteHook('afterRender', { context, templateAPI });
|
|
422
435
|
await this.injectMicroFE(context, templateAPI);
|
|
423
436
|
response = templateAPI.get();
|
|
424
437
|
}
|
|
@@ -581,5 +594,26 @@ export class ModernServer {
|
|
|
581
594
|
const text = ERROR_PAGE_TEXT[status] || ERROR_PAGE_TEXT[500];
|
|
582
595
|
res.end(createErrorDocument(status, text));
|
|
583
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
|
+
}
|
|
584
618
|
}
|
|
585
619
|
/* eslint-enable max-lines */
|
package/src/type.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -49,3 +49,17 @@ export const createErrorDocument = (status: number, text: string) => {
|
|
|
49
49
|
</html>
|
|
50
50
|
`;
|
|
51
51
|
};
|
|
52
|
+
|
|
53
|
+
// This can live anywhere in your codebase:
|
|
54
|
+
export function applyMixins(derivedCtor: any, constructors: any[]) {
|
|
55
|
+
constructors.forEach(baseCtor => {
|
|
56
|
+
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
|
|
57
|
+
Object.defineProperty(
|
|
58
|
+
derivedCtor.prototype,
|
|
59
|
+
name,
|
|
60
|
+
Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
|
|
61
|
+
Object.create(null),
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|