@modern-js/server 1.2.0 → 1.2.1-rc.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/js/modern/index.js +1 -7
- package/dist/js/modern/libs/context/context.js +3 -6
- package/dist/js/modern/libs/context/index.js +1 -7
- package/dist/js/modern/libs/hook-api/template.js +4 -4
- package/dist/js/modern/libs/proxy.js +1 -1
- package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +1 -2
- package/dist/js/modern/libs/render/index.js +6 -2
- package/dist/js/modern/libs/render/reader.js +8 -11
- package/dist/js/modern/libs/render/ssr.js +2 -1
- package/dist/js/modern/libs/route/index.js +2 -1
- package/dist/js/modern/server/index.js +3 -1
- package/dist/js/modern/server/modern-server.js +21 -11
- package/dist/js/modern/utils.js +1 -9
- package/dist/js/node/index.js +1 -49
- package/dist/js/node/libs/context/context.js +3 -6
- package/dist/js/node/libs/context/index.js +1 -7
- package/dist/js/node/libs/hook-api/template.js +4 -4
- package/dist/js/node/libs/proxy.js +1 -1
- package/dist/js/node/libs/render/cache/__tests__/cache.test.js +1 -2
- package/dist/js/node/libs/render/index.js +6 -2
- package/dist/js/node/libs/render/reader.js +8 -11
- package/dist/js/node/libs/render/ssr.js +2 -1
- package/dist/js/node/libs/route/index.js +6 -0
- package/dist/js/node/server/index.js +3 -1
- package/dist/js/node/server/modern-server.js +21 -11
- package/dist/js/node/utils.js +2 -12
- package/dist/types/index.d.ts +1 -3
- package/dist/types/libs/context/context.d.ts +7 -7
- package/dist/types/libs/context/index.d.ts +1 -8
- package/dist/types/libs/hook-api/template.d.ts +4 -4
- package/dist/types/libs/render/index.d.ts +10 -1
- package/dist/types/libs/render/ssr.d.ts +2 -1
- package/dist/types/libs/render/type.d.ts +2 -21
- package/dist/types/libs/route/index.d.ts +2 -1
- package/dist/types/server/modern-server.d.ts +1 -1
- package/dist/types/type.d.ts +6 -0
- package/dist/types/utils.d.ts +1 -2
- package/package.json +14 -12
- package/src/index.ts +2 -8
- package/src/libs/context/context.ts +8 -7
- package/src/libs/context/index.ts +2 -6
- package/src/libs/hook-api/template.ts +4 -4
- package/src/libs/proxy.ts +1 -1
- package/src/libs/render/cache/__tests__/cache.test.ts +2 -2
- package/src/libs/render/index.ts +21 -11
- package/src/libs/render/reader.ts +8 -8
- package/src/libs/render/ssr.ts +4 -0
- package/src/libs/render/type.ts +2 -17
- package/src/libs/route/index.ts +2 -1
- package/src/server/index.ts +1 -1
- package/src/server/modern-server.ts +20 -12
- package/src/type.ts +7 -0
- package/src/utils.ts +0 -14
- package/tests/.eslintrc.js +6 -0
- package/tests/context.test.ts +41 -0
- package/tests/fixtures/hosting-files/static/index.js +1 -0
- package/tests/fixtures/pure/modern.config.js +5 -0
- package/tests/fixtures/pure/package.json +21 -0
- package/tests/fixtures/pure/src/App.css +119 -0
- package/tests/fixtures/pure/src/App.tsx +43 -0
- package/tests/fixtures/pure/tsconfig.json +13 -0
- package/tests/fixtures/route-spec/index.json +29 -0
- package/tests/helper.ts +8 -0
- package/tests/hook.test.ts +44 -0
- package/tests/middleware.test.ts +178 -0
- package/tests/route.test.ts +54 -0
- package/tests/server.test.ts +89 -0
- package/tests/tsconfig.json +14 -0
- package/tests/utils.test.ts +40 -0
|
@@ -74,6 +74,8 @@ class ModernServer {
|
|
|
74
74
|
metrics,
|
|
75
75
|
proxyTarget
|
|
76
76
|
}) {
|
|
77
|
+
var _config$output;
|
|
78
|
+
|
|
77
79
|
this.pwd = void 0;
|
|
78
80
|
this.distDir = void 0;
|
|
79
81
|
this.workDir = void 0;
|
|
@@ -90,15 +92,15 @@ class ModernServer {
|
|
|
90
92
|
this.routeRenderHandler = void 0;
|
|
91
93
|
this.frameWebHandler = null;
|
|
92
94
|
this.frameAPIHandler = null;
|
|
95
|
+
this.proxyHandler = null;
|
|
93
96
|
this._handler = void 0;
|
|
94
97
|
this.staticGenerate = false;
|
|
95
|
-
this.proxyHandler = null;
|
|
96
98
|
|
|
97
99
|
require('ignore-styles');
|
|
98
100
|
|
|
99
101
|
this.isDev = Boolean(dev);
|
|
100
102
|
this.pwd = pwd;
|
|
101
|
-
this.distDir = _path.default.join(pwd, config.output.path || 'dist');
|
|
103
|
+
this.distDir = _path.default.join(pwd, ((_config$output = config.output) === null || _config$output === void 0 ? void 0 : _config$output.path) || 'dist');
|
|
102
104
|
this.workDir = this.isDev ? pwd : this.distDir;
|
|
103
105
|
this.conf = config;
|
|
104
106
|
this.logger = logger;
|
|
@@ -158,7 +160,7 @@ class ModernServer {
|
|
|
158
160
|
const {
|
|
159
161
|
favicon,
|
|
160
162
|
faviconByEntries
|
|
161
|
-
} = this.conf.output;
|
|
163
|
+
} = this.conf.output || {};
|
|
162
164
|
const favicons = this.prepareFavicons(favicon, faviconByEntries); // Only work when without setting `assetPrefix`.
|
|
163
165
|
// Setting `assetPrefix` means these resources should be uploaded to CDN.
|
|
164
166
|
|
|
@@ -206,6 +208,7 @@ class ModernServer {
|
|
|
206
208
|
|
|
207
209
|
return [];
|
|
208
210
|
} // add promisify request handler to server
|
|
211
|
+
// handler should do not do more things after invoke next
|
|
209
212
|
|
|
210
213
|
|
|
211
214
|
addHandler(handler) {
|
|
@@ -348,7 +351,11 @@ class ModernServer {
|
|
|
348
351
|
}
|
|
349
352
|
|
|
350
353
|
async handleWeb(context, route) {
|
|
351
|
-
return this.routeRenderHandler(
|
|
354
|
+
return this.routeRenderHandler({
|
|
355
|
+
ctx: context,
|
|
356
|
+
route,
|
|
357
|
+
runner: this.runner
|
|
358
|
+
});
|
|
352
359
|
}
|
|
353
360
|
|
|
354
361
|
verifyMatch(_c, _m) {// empty
|
|
@@ -367,7 +374,7 @@ class ModernServer {
|
|
|
367
374
|
context
|
|
368
375
|
}); // match routes in the route spec
|
|
369
376
|
|
|
370
|
-
const matched = this.router.match(context.
|
|
377
|
+
const matched = this.router.match(context.path);
|
|
371
378
|
|
|
372
379
|
if (!matched) {
|
|
373
380
|
this.render404(context);
|
|
@@ -508,7 +515,7 @@ class ModernServer {
|
|
|
508
515
|
const injection = JSON.stringify(_objectSpread(_objectSpread({}, manifest), {}, {
|
|
509
516
|
modules
|
|
510
517
|
}));
|
|
511
|
-
templateAPI.
|
|
518
|
+
templateAPI.appendHead(`<script>window.modern_manifest=${injection}</script>`);
|
|
512
519
|
} catch (e) {
|
|
513
520
|
context.error(_constants.ERROR_DIGEST.EMICROINJ, e);
|
|
514
521
|
}
|
|
@@ -555,10 +562,9 @@ class ModernServer {
|
|
|
555
562
|
requestHandler(req, res, next = () => {// empty
|
|
556
563
|
}) {
|
|
557
564
|
res.statusCode = 200;
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
});
|
|
565
|
+
req.logger = req.logger || this.logger;
|
|
566
|
+
req.metrics = req.metrics || this.metrics;
|
|
567
|
+
const context = (0, _context.createContext)(req, res);
|
|
562
568
|
|
|
563
569
|
try {
|
|
564
570
|
this._handler(context, next);
|
|
@@ -590,7 +596,11 @@ class ModernServer {
|
|
|
590
596
|
|
|
591
597
|
if (entryName === status.toString() || entryName === '_error') {
|
|
592
598
|
try {
|
|
593
|
-
const file = await this.routeRenderHandler(
|
|
599
|
+
const file = await this.routeRenderHandler({
|
|
600
|
+
route,
|
|
601
|
+
ctx: context,
|
|
602
|
+
runner: this.runner
|
|
603
|
+
});
|
|
594
604
|
|
|
595
605
|
if (file) {
|
|
596
606
|
context.res.end(file.content);
|
package/dist/js/node/utils.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.applyMixins = applyMixins;
|
|
7
6
|
exports.toMessage = exports.noop = exports.mergeExtension = exports.createErrorDocument = void 0;
|
|
8
7
|
|
|
9
8
|
const mergeExtension = users => {
|
|
@@ -64,15 +63,6 @@ const createErrorDocument = (status, text) => {
|
|
|
64
63
|
</body>
|
|
65
64
|
</html>
|
|
66
65
|
`;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
exports.createErrorDocument = createErrorDocument;
|
|
66
|
+
};
|
|
71
67
|
|
|
72
|
-
|
|
73
|
-
constructors.forEach(baseCtor => {
|
|
74
|
-
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
|
|
75
|
-
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null));
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
}
|
|
68
|
+
exports.createErrorDocument = createErrorDocument;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { ModernServerOptions } from './type';
|
|
2
2
|
import { Server } from './server';
|
|
3
|
-
export * from './type';
|
|
4
|
-
export * from './libs/context';
|
|
5
|
-
export * from './libs/route';
|
|
6
3
|
export type { SSRServerContext } from './libs/render/type';
|
|
7
4
|
export { Server };
|
|
5
|
+
export type { ModernServerOptions };
|
|
8
6
|
|
|
9
7
|
declare const _default: (options: ModernServerOptions) => Promise<Server>;
|
|
10
8
|
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
/// <reference path="../../type.d.ts" />
|
|
1
2
|
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node/http" />
|
|
2
4
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
5
|
import { URL } from 'url';
|
|
4
6
|
import qs from 'querystring';
|
|
5
7
|
import type { ModernServerContext as ModernServerContextInterface, Metrics, Logger } from '@modern-js/types/server';
|
|
8
|
+
export declare type ContextOptions = {
|
|
9
|
+
logger?: Logger;
|
|
10
|
+
metrics?: Metrics;
|
|
11
|
+
};
|
|
6
12
|
export declare class ModernServerContext implements ModernServerContextInterface {
|
|
7
13
|
/**
|
|
8
14
|
* http request
|
|
@@ -20,13 +26,7 @@ export declare class ModernServerContext implements ModernServerContextInterface
|
|
|
20
26
|
params: Record<string, string>;
|
|
21
27
|
logger: Logger;
|
|
22
28
|
metrics?: Metrics;
|
|
23
|
-
constructor(req: IncomingMessage, res: ServerResponse
|
|
24
|
-
logger,
|
|
25
|
-
metrics
|
|
26
|
-
}: {
|
|
27
|
-
logger: Logger;
|
|
28
|
-
metrics: Metrics;
|
|
29
|
-
});
|
|
29
|
+
constructor(req: IncomingMessage, res: ServerResponse);
|
|
30
30
|
private bind;
|
|
31
31
|
setParams(params: Record<string, string>): void;
|
|
32
32
|
getReqHeader(key: string): string | string[];
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
-
import { Metrics, Logger } from '../../type';
|
|
3
2
|
import { ModernServerContext } from './context';
|
|
4
|
-
export declare const createContext: (req: IncomingMessage, res: ServerResponse
|
|
5
|
-
logger,
|
|
6
|
-
metrics
|
|
7
|
-
}: {
|
|
8
|
-
logger: Logger;
|
|
9
|
-
metrics: Metrics;
|
|
10
|
-
}) => ModernServerContext;
|
|
3
|
+
export declare const createContext: (req: IncomingMessage, res: ServerResponse) => ModernServerContext;
|
|
11
4
|
export { ModernServerContext };
|
|
@@ -3,10 +3,10 @@ declare class TemplateAPI {
|
|
|
3
3
|
constructor(content: string);
|
|
4
4
|
get(): string;
|
|
5
5
|
set(content: string): void;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
prependHead(fragment: string): this;
|
|
7
|
+
appendHead(fragment: string): this;
|
|
8
|
+
prependBody(fragment: string): this;
|
|
9
|
+
appendBody(fragment: string): this;
|
|
10
10
|
replace(reg: RegExp | string, text: string): this;
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { RenderResult } from '../../type';
|
|
2
2
|
import { ModernRoute } from '../route';
|
|
3
3
|
import { ModernServerContext } from '../context';
|
|
4
|
+
import { ServerHookRunner } from "../../type.d";
|
|
4
5
|
export declare const createRenderHandler: ({
|
|
5
6
|
distDir,
|
|
6
7
|
staticGenerate
|
|
7
8
|
}: {
|
|
8
9
|
distDir: string;
|
|
9
10
|
staticGenerate: boolean;
|
|
10
|
-
}) => (
|
|
11
|
+
}) => ({
|
|
12
|
+
ctx,
|
|
13
|
+
route,
|
|
14
|
+
runner
|
|
15
|
+
}: {
|
|
16
|
+
ctx: ModernServerContext;
|
|
17
|
+
route: ModernRoute;
|
|
18
|
+
runner: ServerHookRunner;
|
|
19
|
+
}) => Promise<RenderResult | null>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ModernServerContext } from '../context';
|
|
2
2
|
import { RenderResult } from '../../type';
|
|
3
|
+
import { ServerHookRunner } from "../../type.d";
|
|
3
4
|
export declare const render: (ctx: ModernServerContext, renderOptions: {
|
|
4
5
|
distDir: string;
|
|
5
6
|
bundle: string;
|
|
6
7
|
template: string;
|
|
7
8
|
entryName: string;
|
|
8
9
|
staticGenerate: boolean;
|
|
9
|
-
}) => Promise<RenderResult>;
|
|
10
|
+
}, runner: ServerHookRunner) => Promise<RenderResult>;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
/// <reference types="react" />
|
|
3
|
-
import {
|
|
4
|
-
import { Metrics, Logger } from '../../type';
|
|
2
|
+
import { BaseSSRServerContext } from '@modern-js/types/server';
|
|
5
3
|
declare type MetaKeyMap = {
|
|
6
4
|
header?: string[];
|
|
7
5
|
query?: string[];
|
|
@@ -24,24 +22,7 @@ export declare enum RenderLevel {
|
|
|
24
22
|
SERVER_PREFETCH = 1,
|
|
25
23
|
SERVER_RENDER = 2,
|
|
26
24
|
}
|
|
27
|
-
export declare type SSRServerContext = {
|
|
28
|
-
request: {
|
|
29
|
-
params: Record<string, string>;
|
|
30
|
-
pathname: string;
|
|
31
|
-
query: Record<string, string>;
|
|
32
|
-
headers: IncomingHttpHeaders;
|
|
33
|
-
cookie?: string;
|
|
34
|
-
};
|
|
35
|
-
redirection: {
|
|
36
|
-
url?: string;
|
|
37
|
-
status?: number;
|
|
38
|
-
};
|
|
39
|
-
distDir: string;
|
|
40
|
-
template: string;
|
|
41
|
-
entryName: string;
|
|
42
|
-
logger: Logger;
|
|
43
|
-
metrics?: Metrics;
|
|
44
|
-
loadableManifest?: string;
|
|
25
|
+
export declare type SSRServerContext = BaseSSRServerContext & {
|
|
45
26
|
cacheConfig?: CacheConfig;
|
|
46
27
|
staticGenerate?: boolean;
|
|
47
28
|
};
|
|
@@ -11,4 +11,5 @@ export declare class RouteMatchManager {
|
|
|
11
11
|
matchEntry(entryname: string): RouteMatcher | undefined;
|
|
12
12
|
getBundles(): (string | undefined)[];
|
|
13
13
|
}
|
|
14
|
-
export type { ModernRouteInterface,
|
|
14
|
+
export type { ModernRouteInterface, ModernRoute };
|
|
15
|
+
export { RouteMatcher };
|
|
@@ -26,9 +26,9 @@ export declare class ModernServer {
|
|
|
26
26
|
private routeRenderHandler;
|
|
27
27
|
private frameWebHandler;
|
|
28
28
|
private frameAPIHandler;
|
|
29
|
+
private proxyHandler;
|
|
29
30
|
private _handler;
|
|
30
31
|
private readonly staticGenerate;
|
|
31
|
-
private proxyHandler;
|
|
32
32
|
constructor({
|
|
33
33
|
pwd,
|
|
34
34
|
config,
|
package/dist/types/type.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ import { serverManager } from '@modern-js/server-plugin';
|
|
|
4
4
|
import type { NormalizedConfig } from '@modern-js/core';
|
|
5
5
|
import type { Metrics, Logger, NextFunction } from '@modern-js/types/server';
|
|
6
6
|
import { ModernRouteInterface } from './libs/route';
|
|
7
|
+
declare module 'http' {
|
|
8
|
+
interface IncomingMessage {
|
|
9
|
+
logger: Logger;
|
|
10
|
+
metrics: Metrics;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
7
13
|
declare module '@modern-js/core' {
|
|
8
14
|
interface UserConfig {
|
|
9
15
|
bff: {
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -3,5 +3,4 @@ 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;
|
|
7
|
-
export declare function applyMixins(derivedCtor: any, constructors: any[]): void;
|
|
6
|
+
export declare const createErrorDocument: (status: number, text: string) => string;
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.2.0",
|
|
14
|
+
"version": "1.2.1-rc.0",
|
|
15
15
|
"jsnext:source": "./src/index.ts",
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
17
|
"main": "./dist/js/node/index.js",
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"@babel/preset-typescript": "^7.15.0",
|
|
34
34
|
"@babel/register": "^7.15.3",
|
|
35
35
|
"@babel/runtime": "^7",
|
|
36
|
-
"@modern-js/core": "^1.2.0",
|
|
37
|
-
"@modern-js/hmr-client": "^1.1.
|
|
38
|
-
"@modern-js/server-plugin": "^1.1.
|
|
39
|
-
"@modern-js/server-utils": "^1.1.
|
|
40
|
-
"@modern-js/bff-utils": "^1.1.
|
|
41
|
-
"@modern-js/utils": "^1.1.
|
|
36
|
+
"@modern-js/core": "^1.2.1-rc.0",
|
|
37
|
+
"@modern-js/hmr-client": "^1.1.2-rc.0",
|
|
38
|
+
"@modern-js/server-plugin": "^1.1.4-rc.0",
|
|
39
|
+
"@modern-js/server-utils": "^1.1.3-rc.0",
|
|
40
|
+
"@modern-js/bff-utils": "^1.1.2-rc.0",
|
|
41
|
+
"@modern-js/utils": "^1.1.6-rc.0",
|
|
42
42
|
"axios": "^0.21.4",
|
|
43
43
|
"babel-plugin-module-resolver": "^4.1.0",
|
|
44
44
|
"chokidar": "^3.5.2",
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
"ws": "^8.2.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@modern-js/module-tools": "^1.1.
|
|
65
|
-
"@modern-js/plugin-testing": "^1.
|
|
66
|
-
"@modern-js/types": "^1.1.
|
|
64
|
+
"@modern-js/module-tools": "^1.1.4",
|
|
65
|
+
"@modern-js/plugin-testing": "^1.2.2",
|
|
66
|
+
"@modern-js/types": "^1.1.5-rc.0",
|
|
67
67
|
"@types/jest": "^26",
|
|
68
68
|
"@types/lru-cache": "^5.1.1",
|
|
69
69
|
"@types/mime-types": "^2.1.0",
|
|
@@ -78,7 +78,9 @@
|
|
|
78
78
|
"@types/webpack-dev-middleware": "^5.0.2",
|
|
79
79
|
"@types/ws": "^7.4.7",
|
|
80
80
|
"typescript": "^4",
|
|
81
|
-
"webpack": "^5.54.0"
|
|
81
|
+
"webpack": "^5.54.0",
|
|
82
|
+
"node-mocks-http": "^1.11.0",
|
|
83
|
+
"portfinder": "^1.0.28"
|
|
82
84
|
},
|
|
83
85
|
"peerDependencies": {
|
|
84
86
|
"webpack": "^5.54.0"
|
|
@@ -97,7 +99,7 @@
|
|
|
97
99
|
"new": "modern new",
|
|
98
100
|
"build": "modern build",
|
|
99
101
|
"dev": "modern build --watch",
|
|
100
|
-
"test": "modern test
|
|
102
|
+
"test": "modern test"
|
|
101
103
|
},
|
|
102
104
|
"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
105
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { ModernServerOptions } from './type';
|
|
2
|
-
|
|
3
2
|
import { Server } from './server';
|
|
4
3
|
|
|
5
|
-
export * from './type';
|
|
6
|
-
export * from './libs/context';
|
|
7
|
-
export * from './libs/route';
|
|
8
4
|
export type { SSRServerContext } from './libs/render/type';
|
|
9
5
|
export { Server };
|
|
6
|
+
export type { ModernServerOptions };
|
|
10
7
|
|
|
11
8
|
export default (options: ModernServerOptions): Promise<Server> => {
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13
|
-
const allowEnvs = ['production', 'development', 'test'];
|
|
14
|
-
|
|
15
9
|
if (options == null) {
|
|
16
|
-
throw new Error();
|
|
10
|
+
throw new Error('can not start mserver without options');
|
|
17
11
|
}
|
|
18
12
|
|
|
19
13
|
const server = new Server(options);
|
|
@@ -8,6 +8,11 @@ import type {
|
|
|
8
8
|
} from '@modern-js/types/server';
|
|
9
9
|
import { toMessage } from '../../utils';
|
|
10
10
|
|
|
11
|
+
export type ContextOptions = {
|
|
12
|
+
logger?: Logger;
|
|
13
|
+
metrics?: Metrics;
|
|
14
|
+
};
|
|
15
|
+
|
|
11
16
|
export class ModernServerContext implements ModernServerContextInterface {
|
|
12
17
|
/**
|
|
13
18
|
* http request
|
|
@@ -28,15 +33,11 @@ export class ModernServerContext implements ModernServerContextInterface {
|
|
|
28
33
|
|
|
29
34
|
public metrics?: Metrics;
|
|
30
35
|
|
|
31
|
-
constructor(
|
|
32
|
-
req: IncomingMessage,
|
|
33
|
-
res: ServerResponse,
|
|
34
|
-
{ logger, metrics }: { logger: Logger; metrics: Metrics },
|
|
35
|
-
) {
|
|
36
|
+
constructor(req: IncomingMessage, res: ServerResponse) {
|
|
36
37
|
this.req = req;
|
|
37
38
|
this.res = res;
|
|
38
|
-
this.logger = logger;
|
|
39
|
-
this.metrics = metrics;
|
|
39
|
+
this.logger = req.logger;
|
|
40
|
+
this.metrics = req.metrics;
|
|
40
41
|
|
|
41
42
|
this.bind();
|
|
42
43
|
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
-
import { Metrics, Logger } from '../../type';
|
|
3
2
|
import { ModernServerContext } from './context';
|
|
4
3
|
|
|
5
|
-
export const createContext = (
|
|
6
|
-
req
|
|
7
|
-
res: ServerResponse,
|
|
8
|
-
{ logger, metrics }: { logger: Logger; metrics: Metrics },
|
|
9
|
-
) => new ModernServerContext(req, res, { logger, metrics });
|
|
4
|
+
export const createContext = (req: IncomingMessage, res: ServerResponse) =>
|
|
5
|
+
new ModernServerContext(req, res);
|
|
10
6
|
|
|
11
7
|
export { ModernServerContext };
|
|
@@ -24,22 +24,22 @@ class TemplateAPI {
|
|
|
24
24
|
this.content = content;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
public
|
|
27
|
+
public prependHead(fragment: string) {
|
|
28
28
|
const { head } = RegList.before;
|
|
29
29
|
return this.replace(head, `${head}${fragment}`);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
public
|
|
32
|
+
public appendHead(fragment: string) {
|
|
33
33
|
const { head } = RegList.after;
|
|
34
34
|
return this.replace(head, `${fragment}${head}`);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
public
|
|
37
|
+
public prependBody(fragment: string) {
|
|
38
38
|
const { body } = RegList.before;
|
|
39
39
|
return this.replace(body, `${body}${fragment}`);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
public
|
|
42
|
+
public appendBody(fragment: string) {
|
|
43
43
|
const { body } = RegList.after;
|
|
44
44
|
return this.replace(body, `${fragment}${body}`);
|
|
45
45
|
}
|
package/src/libs/proxy.ts
CHANGED
|
@@ -15,6 +15,8 @@ const createCacheConfig = (config: any = {}) => ({
|
|
|
15
15
|
...config,
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
jest.setTimeout(60000);
|
|
19
|
+
|
|
18
20
|
describe('cache', () => {
|
|
19
21
|
it('should cache correctly', async () => {
|
|
20
22
|
destroyCache();
|
|
@@ -179,7 +181,6 @@ describe('cache', () => {
|
|
|
179
181
|
}
|
|
180
182
|
});
|
|
181
183
|
|
|
182
|
-
jest.setTimeout(1000 * 10);
|
|
183
184
|
it('should stale cache correctly', async () => {
|
|
184
185
|
destroyCache();
|
|
185
186
|
const cache = createCache();
|
|
@@ -207,7 +208,6 @@ describe('cache', () => {
|
|
|
207
208
|
expect(staleResult?.isStale).toBe(true);
|
|
208
209
|
});
|
|
209
210
|
|
|
210
|
-
jest.setTimeout(1000 * 15);
|
|
211
211
|
it('should garbage cache correctly', async () => {
|
|
212
212
|
destroyCache();
|
|
213
213
|
const cache = createCache();
|
package/src/libs/render/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { readFile } from './reader';
|
|
|
9
9
|
import * as ssr from './ssr';
|
|
10
10
|
import { supportModern, getModernEntry } from './modern';
|
|
11
11
|
import { ERROR_DIGEST } from '@/constants';
|
|
12
|
+
import { ServerHookRunner } from '@/type';
|
|
12
13
|
|
|
13
14
|
export const createRenderHandler = ({
|
|
14
15
|
distDir,
|
|
@@ -17,10 +18,15 @@ export const createRenderHandler = ({
|
|
|
17
18
|
distDir: string;
|
|
18
19
|
staticGenerate: boolean;
|
|
19
20
|
}) =>
|
|
20
|
-
async function render(
|
|
21
|
-
ctx
|
|
22
|
-
route
|
|
23
|
-
|
|
21
|
+
async function render({
|
|
22
|
+
ctx,
|
|
23
|
+
route,
|
|
24
|
+
runner,
|
|
25
|
+
}: {
|
|
26
|
+
ctx: ModernServerContext;
|
|
27
|
+
route: ModernRoute;
|
|
28
|
+
runner: ServerHookRunner;
|
|
29
|
+
}): Promise<RenderResult | null> {
|
|
24
30
|
if (ctx.resHasHandled()) {
|
|
25
31
|
return null;
|
|
26
32
|
}
|
|
@@ -43,13 +49,17 @@ export const createRenderHandler = ({
|
|
|
43
49
|
// handles ssr first
|
|
44
50
|
if (route.isSSR) {
|
|
45
51
|
try {
|
|
46
|
-
const result = await ssr.render(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
const result = await ssr.render(
|
|
53
|
+
ctx,
|
|
54
|
+
{
|
|
55
|
+
distDir,
|
|
56
|
+
entryName: route.entryName,
|
|
57
|
+
bundle: route.bundle,
|
|
58
|
+
template: templateHTML,
|
|
59
|
+
staticGenerate,
|
|
60
|
+
},
|
|
61
|
+
runner,
|
|
62
|
+
);
|
|
53
63
|
return result;
|
|
54
64
|
} catch (err) {
|
|
55
65
|
ctx.error(ERROR_DIGEST.ERENDER, (err as Error).stack);
|
|
@@ -24,7 +24,7 @@ const createCacheItem = async (filepath: string, mtime: Date) => {
|
|
|
24
24
|
class LruReader {
|
|
25
25
|
private readonly cache: LRU<string, FileCache>;
|
|
26
26
|
|
|
27
|
-
private timer?: NodeJS.Timeout;
|
|
27
|
+
// private timer?: NodeJS.Timeout;
|
|
28
28
|
|
|
29
29
|
constructor() {
|
|
30
30
|
this.cache = new LRU({
|
|
@@ -35,13 +35,13 @@ class LruReader {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
public init() {
|
|
38
|
-
this.timeTask();
|
|
38
|
+
// this.timeTask();
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
public close() {
|
|
42
|
-
if (this.timer) {
|
|
43
|
-
|
|
44
|
-
}
|
|
42
|
+
// if (this.timer) {
|
|
43
|
+
// clearInterval(this.timer);
|
|
44
|
+
// }
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
public async read(filepath: string) {
|
|
@@ -94,9 +94,9 @@ class LruReader {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
private timeTask() {
|
|
98
|
-
|
|
99
|
-
}
|
|
97
|
+
// private timeTask() {
|
|
98
|
+
// this.timer = setInterval(() => this.update, 5 * 60 * 1000).unref();
|
|
99
|
+
// }
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
const reader = new LruReader();
|
package/src/libs/render/ssr.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { ModernServerContext } from '../context';
|
|
|
5
5
|
import { RenderResult } from '../../type';
|
|
6
6
|
import cache from './cache';
|
|
7
7
|
import { SSRServerContext } from './type';
|
|
8
|
+
import { ServerHookRunner } from '@/type';
|
|
8
9
|
|
|
9
10
|
export const render = async (
|
|
10
11
|
ctx: ModernServerContext,
|
|
@@ -15,6 +16,7 @@ export const render = async (
|
|
|
15
16
|
entryName: string;
|
|
16
17
|
staticGenerate: boolean;
|
|
17
18
|
},
|
|
19
|
+
runner: ServerHookRunner,
|
|
18
20
|
): Promise<RenderResult> => {
|
|
19
21
|
const { bundle, distDir, template, entryName, staticGenerate } =
|
|
20
22
|
renderOptions;
|
|
@@ -37,6 +39,8 @@ export const render = async (
|
|
|
37
39
|
metrics: ctx.metrics,
|
|
38
40
|
};
|
|
39
41
|
|
|
42
|
+
runner.extendSSRContext(context);
|
|
43
|
+
|
|
40
44
|
const serverRender = require(bundleJS)[SERVER_RENDER_FUNCTION_NAME];
|
|
41
45
|
|
|
42
46
|
const html = await cache(serverRender, ctx)(context);
|
package/src/libs/render/type.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Metrics, Logger } from '../../type';
|
|
1
|
+
import { BaseSSRServerContext } from '@modern-js/types/server';
|
|
3
2
|
|
|
4
3
|
type MetaKeyMap = {
|
|
5
4
|
header?: string[];
|
|
@@ -26,21 +25,7 @@ export enum RenderLevel {
|
|
|
26
25
|
SERVER_RENDER,
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
export type SSRServerContext = {
|
|
30
|
-
request: {
|
|
31
|
-
params: Record<string, string>;
|
|
32
|
-
pathname: string;
|
|
33
|
-
query: Record<string, string>;
|
|
34
|
-
headers: IncomingHttpHeaders;
|
|
35
|
-
cookie?: string;
|
|
36
|
-
};
|
|
37
|
-
redirection: { url?: string; status?: number };
|
|
38
|
-
distDir: string;
|
|
39
|
-
template: string;
|
|
40
|
-
entryName: string;
|
|
41
|
-
logger: Logger;
|
|
42
|
-
metrics?: Metrics;
|
|
43
|
-
loadableManifest?: string;
|
|
28
|
+
export type SSRServerContext = BaseSSRServerContext & {
|
|
44
29
|
cacheConfig?: CacheConfig;
|
|
45
30
|
staticGenerate?: boolean;
|
|
46
31
|
};
|
package/src/libs/route/index.ts
CHANGED