@modern-js/prod-server 1.0.1
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 +16 -0
- package/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/js/modern/constants.js +26 -0
- package/dist/js/modern/index.js +14 -0
- package/dist/js/modern/libs/context/context.js +180 -0
- package/dist/js/modern/libs/context/index.js +3 -0
- package/dist/js/modern/libs/hook-api/route.js +39 -0
- package/dist/js/modern/libs/hook-api/template.js +61 -0
- package/dist/js/modern/libs/metrics.js +12 -0
- package/dist/js/modern/libs/proxy.js +33 -0
- package/dist/js/modern/libs/render/cache/__tests__/cache.fun.test.js +70 -0
- package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +233 -0
- package/dist/js/modern/libs/render/cache/__tests__/cacheable.js +53 -0
- package/dist/js/modern/libs/render/cache/__tests__/error-configuration.js +35 -0
- package/dist/js/modern/libs/render/cache/__tests__/matched-cache.js +121 -0
- package/dist/js/modern/libs/render/cache/index.js +74 -0
- package/dist/js/modern/libs/render/cache/page-caches/index.js +9 -0
- package/dist/js/modern/libs/render/cache/page-caches/lru.js +35 -0
- package/dist/js/modern/libs/render/cache/spr.js +280 -0
- package/dist/js/modern/libs/render/cache/type.js +1 -0
- package/dist/js/modern/libs/render/cache/util.js +79 -0
- package/dist/js/modern/libs/render/index.js +65 -0
- package/dist/js/modern/libs/render/modern/browser-list.js +7 -0
- package/dist/js/modern/libs/render/modern/index.js +42 -0
- package/dist/js/modern/libs/render/reader.js +112 -0
- package/dist/js/modern/libs/render/ssr.js +58 -0
- package/dist/js/modern/libs/render/static.js +46 -0
- package/dist/js/modern/libs/render/type.js +7 -0
- package/dist/js/modern/libs/route/index.js +68 -0
- package/dist/js/modern/libs/route/matcher.js +94 -0
- package/dist/js/modern/libs/route/route.js +24 -0
- package/dist/js/modern/libs/serve-file.js +28 -0
- package/dist/js/modern/server/index.js +120 -0
- package/dist/js/modern/server/modern-server-split.js +81 -0
- package/dist/js/modern/server/modern-server.js +576 -0
- package/dist/js/modern/type.js +1 -0
- package/dist/js/modern/utils.js +112 -0
- package/dist/js/node/constants.js +36 -0
- package/dist/js/node/index.js +74 -0
- package/dist/js/node/libs/context/context.js +194 -0
- package/dist/js/node/libs/context/index.js +18 -0
- package/dist/js/node/libs/hook-api/route.js +48 -0
- package/dist/js/node/libs/hook-api/template.js +69 -0
- package/dist/js/node/libs/metrics.js +18 -0
- package/dist/js/node/libs/proxy.js +44 -0
- package/dist/js/node/libs/render/cache/__tests__/cache.fun.test.js +77 -0
- package/dist/js/node/libs/render/cache/__tests__/cache.test.js +238 -0
- package/dist/js/node/libs/render/cache/__tests__/cacheable.js +60 -0
- package/dist/js/node/libs/render/cache/__tests__/error-configuration.js +42 -0
- package/dist/js/node/libs/render/cache/__tests__/matched-cache.js +128 -0
- package/dist/js/node/libs/render/cache/index.js +86 -0
- package/dist/js/node/libs/render/cache/page-caches/index.js +17 -0
- package/dist/js/node/libs/render/cache/page-caches/lru.js +47 -0
- package/dist/js/node/libs/render/cache/spr.js +298 -0
- package/dist/js/node/libs/render/cache/type.js +5 -0
- package/dist/js/node/libs/render/cache/util.js +105 -0
- package/dist/js/node/libs/render/index.js +91 -0
- package/dist/js/node/libs/render/modern/browser-list.js +14 -0
- package/dist/js/node/libs/render/modern/index.js +58 -0
- package/dist/js/node/libs/render/reader.js +139 -0
- package/dist/js/node/libs/render/ssr.js +76 -0
- package/dist/js/node/libs/render/static.js +62 -0
- package/dist/js/node/libs/render/type.js +14 -0
- package/dist/js/node/libs/route/index.js +83 -0
- package/dist/js/node/libs/route/matcher.js +108 -0
- package/dist/js/node/libs/route/route.js +33 -0
- package/dist/js/node/libs/serve-file.js +41 -0
- package/dist/js/node/server/index.js +142 -0
- package/dist/js/node/server/modern-server-split.js +97 -0
- package/dist/js/node/server/modern-server.js +614 -0
- package/dist/js/node/type.js +5 -0
- package/dist/js/node/utils.js +143 -0
- package/dist/js/styles/tsconfig.json +12 -0
- package/dist/types/constants.d.ts +20 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/libs/context/context.d.ts +61 -0
- package/dist/types/libs/context/index.d.ts +4 -0
- package/dist/types/libs/hook-api/route.d.ts +14 -0
- package/dist/types/libs/hook-api/template.d.ts +14 -0
- package/dist/types/libs/metrics.d.ts +3 -0
- package/dist/types/libs/proxy.d.ts +4 -0
- package/dist/types/libs/render/cache/__tests__/cache.fun.test.d.ts +1 -0
- package/dist/types/libs/render/cache/__tests__/cache.test.d.ts +1 -0
- package/dist/types/libs/render/cache/__tests__/cacheable.d.ts +62 -0
- package/dist/types/libs/render/cache/__tests__/error-configuration.d.ts +28 -0
- package/dist/types/libs/render/cache/__tests__/matched-cache.d.ts +124 -0
- package/dist/types/libs/render/cache/index.d.ts +6 -0
- package/dist/types/libs/render/cache/page-caches/index.d.ts +2 -0
- package/dist/types/libs/render/cache/page-caches/lru.d.ts +15 -0
- package/dist/types/libs/render/cache/spr.d.ts +24 -0
- package/dist/types/libs/render/cache/type.d.ts +48 -0
- package/dist/types/libs/render/cache/util.d.ts +17 -0
- package/dist/types/libs/render/index.d.ts +18 -0
- package/dist/types/libs/render/modern/browser-list.d.ts +1 -0
- package/dist/types/libs/render/modern/index.d.ts +3 -0
- package/dist/types/libs/render/reader.d.ts +18 -0
- package/dist/types/libs/render/ssr.d.ts +10 -0
- package/dist/types/libs/render/static.d.ts +3 -0
- package/dist/types/libs/render/type.d.ts +33 -0
- package/dist/types/libs/route/index.d.ts +15 -0
- package/dist/types/libs/route/matcher.d.ts +15 -0
- package/dist/types/libs/route/route.d.ts +14 -0
- package/dist/types/libs/serve-file.d.ts +8 -0
- package/dist/types/server/index.d.ts +20 -0
- package/dist/types/server/modern-server-split.d.ts +26 -0
- package/dist/types/server/modern-server.d.ts +72 -0
- package/dist/types/type.d.ts +56 -0
- package/dist/types/utils.d.ts +19 -0
- package/jest.config.js +9 -0
- package/modern.config.js +2 -0
- package/package.json +82 -0
- package/src/constants.ts +26 -0
- package/src/index.ts +18 -0
- package/src/libs/context/context.ts +183 -0
- package/src/libs/context/index.ts +7 -0
- package/src/libs/hook-api/route.ts +42 -0
- package/src/libs/hook-api/template.ts +53 -0
- package/src/libs/metrics.ts +15 -0
- package/src/libs/proxy.ts +42 -0
- package/src/libs/render/cache/__tests__/cache.fun.test.ts +94 -0
- package/src/libs/render/cache/__tests__/cache.test.ts +240 -0
- package/src/libs/render/cache/__tests__/cacheable.ts +44 -0
- package/src/libs/render/cache/__tests__/error-configuration.ts +34 -0
- package/src/libs/render/cache/__tests__/matched-cache.ts +88 -0
- package/src/libs/render/cache/index.ts +75 -0
- package/src/libs/render/cache/page-caches/index.ts +11 -0
- package/src/libs/render/cache/page-caches/lru.ts +38 -0
- package/src/libs/render/cache/spr.ts +301 -0
- package/src/libs/render/cache/type.ts +59 -0
- package/src/libs/render/cache/util.ts +97 -0
- package/src/libs/render/index.ts +79 -0
- package/src/libs/render/modern/browser-list.ts +7 -0
- package/src/libs/render/modern/index.ts +41 -0
- package/src/libs/render/modern/module.d.ts +4 -0
- package/src/libs/render/reader.ts +119 -0
- package/src/libs/render/ssr.ts +67 -0
- package/src/libs/render/static.ts +52 -0
- package/src/libs/render/type.ts +38 -0
- package/src/libs/route/index.ts +76 -0
- package/src/libs/route/matcher.ts +108 -0
- package/src/libs/route/route.ts +34 -0
- package/src/libs/serve-file.ts +34 -0
- package/src/server/index.ts +147 -0
- package/src/server/modern-server-split.ts +97 -0
- package/src/server/modern-server.ts +613 -0
- package/src/tsconfig.json +12 -0
- package/src/type.ts +61 -0
- package/src/utils.ts +122 -0
- package/tests/.eslintrc.js +6 -0
- package/tests/context.test.ts +52 -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 +12 -0
- package/tests/fixtures/reader/index.ts +3 -0
- package/tests/fixtures/route-spec/dynamic.json +13 -0
- package/tests/fixtures/route-spec/index.json +29 -0
- package/tests/fixtures/ssr/bundle.js +5 -0
- package/tests/fixtures/static-dir/bar.html +11 -0
- package/tests/fixtures/static-dir/baz/index.html +11 -0
- package/tests/fixtures/static-dir/foo/index.html +11 -0
- package/tests/helper.ts +8 -0
- package/tests/hook.test.ts +44 -0
- package/tests/middleware.test.ts +179 -0
- package/tests/render.test.ts +102 -0
- package/tests/route.test.ts +77 -0
- package/tests/server.test.ts +101 -0
- package/tests/tsconfig.json +12 -0
- package/tests/utils.test.ts +106 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ModernServerContext } from '../context';
|
|
2
|
+
import { RenderResult, ServerHookRunner } from '../../type';
|
|
3
|
+
export declare const render: (ctx: ModernServerContext, renderOptions: {
|
|
4
|
+
distDir: string;
|
|
5
|
+
bundle: string;
|
|
6
|
+
urlPath: string;
|
|
7
|
+
template: string;
|
|
8
|
+
entryName: string;
|
|
9
|
+
staticGenerate: boolean;
|
|
10
|
+
}, runner: ServerHookRunner) => Promise<RenderResult>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BaseSSRServerContext } from '@modern-js/types/server';
|
|
2
|
+
declare type MetaKeyMap = {
|
|
3
|
+
header?: string[];
|
|
4
|
+
query?: string[];
|
|
5
|
+
};
|
|
6
|
+
declare type MetaKeyMatch = {
|
|
7
|
+
header?: MatchMap;
|
|
8
|
+
query?: MatchMap;
|
|
9
|
+
};
|
|
10
|
+
declare type MatchMap = Record<string, Record<string, string>>;
|
|
11
|
+
export declare type CacheConfig = {
|
|
12
|
+
interval: number;
|
|
13
|
+
staleLimit: number | boolean;
|
|
14
|
+
level: number;
|
|
15
|
+
includes?: MetaKeyMap | null;
|
|
16
|
+
excludes?: MetaKeyMap | null;
|
|
17
|
+
matches?: MetaKeyMatch | null;
|
|
18
|
+
};
|
|
19
|
+
export declare enum RenderLevel {
|
|
20
|
+
CLIENT_RENDER = 0,
|
|
21
|
+
SERVER_PREFETCH = 1,
|
|
22
|
+
SERVER_RENDER = 2,
|
|
23
|
+
}
|
|
24
|
+
export declare type SSRServerContext = BaseSSRServerContext & {
|
|
25
|
+
cacheConfig?: CacheConfig;
|
|
26
|
+
staticGenerate?: boolean;
|
|
27
|
+
};
|
|
28
|
+
export declare type ModernSSRReactComponent = React.ComponentType<any> & {
|
|
29
|
+
init: (context: SSRServerContext) => Promise<void>;
|
|
30
|
+
prefetch: (context: SSRServerContext) => Promise<Record<string, any>>;
|
|
31
|
+
};
|
|
32
|
+
export declare type RenderFunction = (context: SSRServerContext) => Promise<string>;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RouteMatcher } from './matcher';
|
|
2
|
+
import { ModernRoute, ModernRouteInterface } from './route';
|
|
3
|
+
export declare class RouteMatchManager {
|
|
4
|
+
matchers: RouteMatcher[];
|
|
5
|
+
private specs;
|
|
6
|
+
constructor();
|
|
7
|
+
private filter;
|
|
8
|
+
private best;
|
|
9
|
+
reset(specs: ModernRouteInterface[]): void;
|
|
10
|
+
match(pathname: string): RouteMatcher | undefined;
|
|
11
|
+
matchEntry(entryname: string): RouteMatcher | undefined;
|
|
12
|
+
getBundles(): (string | undefined)[];
|
|
13
|
+
}
|
|
14
|
+
export type { ModernRouteInterface, ModernRoute };
|
|
15
|
+
export { RouteMatcher };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MatchFunction } from 'path-to-regexp';
|
|
2
|
+
import { ModernRoute, ModernRouteInterface } from './route';
|
|
3
|
+
export declare class RouteMatcher {
|
|
4
|
+
spec: ModernRouteInterface;
|
|
5
|
+
urlPath: string;
|
|
6
|
+
urlMatcher?: MatchFunction;
|
|
7
|
+
urlReg?: RegExp;
|
|
8
|
+
constructor(spec: ModernRouteInterface);
|
|
9
|
+
generate(url: string): ModernRoute;
|
|
10
|
+
parseURLParams(pathname: string): Record<string, string>;
|
|
11
|
+
matchLength(pathname: string): number | null;
|
|
12
|
+
matchUrlPath(requestUrl: string): boolean;
|
|
13
|
+
matchEntry(entryName: string): boolean;
|
|
14
|
+
private setupUrlPath;
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ServerRoute as ModernRouteInterface } from '@modern-js/types';
|
|
2
|
+
export type { ModernRouteInterface };
|
|
3
|
+
export declare class ModernRoute implements ModernRouteInterface {
|
|
4
|
+
entryName: string;
|
|
5
|
+
urlPath: string;
|
|
6
|
+
entryPath: string;
|
|
7
|
+
bundle: string;
|
|
8
|
+
isApi: boolean;
|
|
9
|
+
isSSR: boolean;
|
|
10
|
+
isSPA: boolean;
|
|
11
|
+
enableModernMode?: boolean;
|
|
12
|
+
params: Record<string, any>;
|
|
13
|
+
constructor(routeSpec: ModernRouteInterface);
|
|
14
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NextFunction } from '../type';
|
|
2
|
+
import { ModernServerContext } from './context';
|
|
3
|
+
declare type Rule = {
|
|
4
|
+
path: string | RegExp;
|
|
5
|
+
target: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const createStaticFileHandler: (rules: Rule[]) => (context: ModernServerContext, next: NextFunction) => Promise<void>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IncomingMessage, ServerResponse, Server as httpServer } from 'http';
|
|
3
|
+
import { ModernServerOptions, ReadyOptions } from '../type';
|
|
4
|
+
import { ModernServer } from './modern-server';
|
|
5
|
+
export declare class Server {
|
|
6
|
+
options: ModernServerOptions;
|
|
7
|
+
protected serverImpl: (options: ModernServerOptions) => ModernServer;
|
|
8
|
+
private server;
|
|
9
|
+
private app;
|
|
10
|
+
private runner;
|
|
11
|
+
constructor(options: ModernServerOptions);
|
|
12
|
+
getRequestHandler(): (req: IncomingMessage, res: ServerResponse, next?: (() => void) | undefined) => void;
|
|
13
|
+
ready(readyOptions?: ReadyOptions): void;
|
|
14
|
+
init(): Promise<this>;
|
|
15
|
+
listen(port: number | undefined, listener: any): void;
|
|
16
|
+
listener(app: httpServer): void;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
private createHookRunner;
|
|
19
|
+
private initAppContext;
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { APIServerStartInput } from '@modern-js/server-core';
|
|
2
|
+
import { mergeExtension } from '../utils';
|
|
3
|
+
import { ModernRoute, ModernRouteInterface, RouteMatcher } from '../libs/route';
|
|
4
|
+
import { ApiServerMode } from '../constants';
|
|
5
|
+
import { ModernServerContext } from '../libs/context';
|
|
6
|
+
import { ModernServer } from './modern-server';
|
|
7
|
+
export declare class ModernSSRServer extends ModernServer {
|
|
8
|
+
protected warmupSSRBundle(): Promise<void>;
|
|
9
|
+
protected verifyMatch(context: ModernServerContext, matched: RouteMatcher): void;
|
|
10
|
+
protected prepareAPIHandler(_m: ApiServerMode, _: APIServerStartInput['config']): any;
|
|
11
|
+
protected prepareWebHandler(extension: ReturnType<typeof mergeExtension>): Promise<import("@modern-js/server-core").Adapter>;
|
|
12
|
+
protected preServerInit(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare class ModernAPIServer extends ModernServer {
|
|
15
|
+
protected emitRouteHook(_: string, _input: any): Promise<void>;
|
|
16
|
+
protected warmupSSRBundle(): Promise<void>;
|
|
17
|
+
protected prepareWebHandler(_: ReturnType<typeof mergeExtension>): any;
|
|
18
|
+
protected prepareAPIHandler(mode: ApiServerMode, extension: APIServerStartInput['config']): Promise<import("@modern-js/server-core").Adapter>;
|
|
19
|
+
protected filterRoutes(routes: ModernRouteInterface[]): ModernRouteInterface[];
|
|
20
|
+
protected preServerInit(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export declare class ModernWebServer extends ModernServer {
|
|
23
|
+
protected warmupSSRBundle(): Promise<void>;
|
|
24
|
+
protected handleAPI(context: ModernServerContext): Promise<void>;
|
|
25
|
+
protected handleWeb(context: ModernServerContext, route: ModernRoute): Promise<any>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IncomingMessage, ServerResponse, Server } from 'http';
|
|
3
|
+
import { Adapter, APIServerStartInput } from '@modern-js/server-core';
|
|
4
|
+
import type { NormalizedConfig } from '@modern-js/core';
|
|
5
|
+
import { ModernServerOptions, NextFunction, ServerHookRunner, Metrics, Logger, ReadyOptions } from '../type';
|
|
6
|
+
import { RouteMatchManager, ModernRouteInterface, ModernRoute, RouteMatcher } from '../libs/route';
|
|
7
|
+
import { mergeExtension } from '../utils';
|
|
8
|
+
import * as reader from '../libs/render/reader';
|
|
9
|
+
import { ModernServerContext } from '../libs/context';
|
|
10
|
+
import { ApiServerMode } from '../constants';
|
|
11
|
+
declare type ModernServerHandler = (context: ModernServerContext, next: NextFunction) => Promise<void> | void;
|
|
12
|
+
declare type ModernServerAsyncHandler = (context: ModernServerContext, next: NextFunction) => Promise<void>;
|
|
13
|
+
export declare class ModernServer {
|
|
14
|
+
protected pwd: string;
|
|
15
|
+
protected distDir: string;
|
|
16
|
+
protected workDir: string;
|
|
17
|
+
protected router: RouteMatchManager;
|
|
18
|
+
protected conf: NormalizedConfig;
|
|
19
|
+
protected handlers: ModernServerAsyncHandler[];
|
|
20
|
+
protected presetRoutes?: ModernRouteInterface[];
|
|
21
|
+
protected runner: ServerHookRunner;
|
|
22
|
+
protected readonly logger: Logger;
|
|
23
|
+
protected readonly metrics: Metrics;
|
|
24
|
+
protected reader: typeof reader;
|
|
25
|
+
protected readonly proxyTarget: ModernServerOptions['proxyTarget'];
|
|
26
|
+
private staticFileHandler;
|
|
27
|
+
private routeRenderHandler;
|
|
28
|
+
private frameWebHandler;
|
|
29
|
+
private frameAPIHandler;
|
|
30
|
+
private proxyHandler;
|
|
31
|
+
private _handler;
|
|
32
|
+
private readonly staticGenerate;
|
|
33
|
+
constructor({
|
|
34
|
+
pwd,
|
|
35
|
+
config,
|
|
36
|
+
routes,
|
|
37
|
+
staticGenerate,
|
|
38
|
+
logger,
|
|
39
|
+
metrics,
|
|
40
|
+
proxyTarget
|
|
41
|
+
}: ModernServerOptions);
|
|
42
|
+
getRequestHandler(): (req: IncomingMessage, res: ServerResponse, next?: () => void) => void;
|
|
43
|
+
init(runner: ServerHookRunner): Promise<void>;
|
|
44
|
+
ready(_: ReadyOptions): void;
|
|
45
|
+
onListening(_: Server): void;
|
|
46
|
+
close(): Promise<void>;
|
|
47
|
+
createHTTPServer(handler: (req: IncomingMessage, res: ServerResponse, next?: () => void) => void): Promise<Server>;
|
|
48
|
+
protected readRouteSpec(): ModernRouteInterface[];
|
|
49
|
+
protected addHandler(handler: ModernServerHandler): void;
|
|
50
|
+
protected render404(context: ModernServerContext): void;
|
|
51
|
+
protected prepareFrameHandler(): Promise<void>;
|
|
52
|
+
protected proxy(): Promise<any>;
|
|
53
|
+
protected prepareWebHandler(extension: ReturnType<typeof mergeExtension>): Promise<Adapter>;
|
|
54
|
+
protected prepareAPIHandler(mode: ApiServerMode, extension: APIServerStartInput['config']): Promise<Adapter>;
|
|
55
|
+
protected filterRoutes(routes: ModernRouteInterface[]): ModernRouteInterface[];
|
|
56
|
+
protected emitRouteHook(eventName: 'beforeMatch' | 'afterMatch' | 'beforeRender' | 'afterRender', input: {
|
|
57
|
+
context: ModernServerContext;
|
|
58
|
+
[propsName: string]: any;
|
|
59
|
+
}): Promise<any>;
|
|
60
|
+
protected warmupSSRBundle(): void;
|
|
61
|
+
protected preServerInit(): Promise<void>;
|
|
62
|
+
protected handleAPI(context: ModernServerContext): Promise<void>;
|
|
63
|
+
protected handleWeb(context: ModernServerContext, route: ModernRoute): Promise<import("../type").RenderResult | null>;
|
|
64
|
+
protected verifyMatch(_c: ModernServerContext, _m: RouteMatcher): void;
|
|
65
|
+
private routeHandler;
|
|
66
|
+
private injectMicroFE;
|
|
67
|
+
private compose;
|
|
68
|
+
private requestHandler;
|
|
69
|
+
private onError;
|
|
70
|
+
private renderErrorPage;
|
|
71
|
+
}
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { serverManager } from '@modern-js/server-core';
|
|
3
|
+
import type { NormalizedConfig } from '@modern-js/core';
|
|
4
|
+
import type { Metrics, Logger, NextFunction } from '@modern-js/types/server';
|
|
5
|
+
import { ModernRouteInterface } from './libs/route';
|
|
6
|
+
declare module 'http' {
|
|
7
|
+
interface IncomingMessage {
|
|
8
|
+
logger: Logger;
|
|
9
|
+
metrics: Metrics;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
declare module '@modern-js/core' {
|
|
13
|
+
interface UserConfig {
|
|
14
|
+
bff?: {
|
|
15
|
+
proxy: Record<string, any>;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export declare type ModernServerOptions = {
|
|
20
|
+
pwd: string;
|
|
21
|
+
config: NormalizedConfig;
|
|
22
|
+
plugins?: {
|
|
23
|
+
pluginPath: string;
|
|
24
|
+
}[];
|
|
25
|
+
routes?: ModernRouteInterface[];
|
|
26
|
+
staticGenerate?: boolean;
|
|
27
|
+
loggerOptions?: Record<string, string>;
|
|
28
|
+
metricsOptions?: Record<string, string>;
|
|
29
|
+
logger?: Logger;
|
|
30
|
+
metrics?: Metrics;
|
|
31
|
+
apiOnly?: boolean;
|
|
32
|
+
ssrOnly?: boolean;
|
|
33
|
+
webOnly?: boolean;
|
|
34
|
+
proxyTarget?: {
|
|
35
|
+
ssr?: string;
|
|
36
|
+
api?: string;
|
|
37
|
+
};
|
|
38
|
+
[propName: string]: any;
|
|
39
|
+
};
|
|
40
|
+
export declare type RenderResult = {
|
|
41
|
+
content: string | Buffer;
|
|
42
|
+
contentType: string;
|
|
43
|
+
statusCode?: number;
|
|
44
|
+
redirect?: boolean;
|
|
45
|
+
};
|
|
46
|
+
export declare type ConfWithBFF = {
|
|
47
|
+
bff?: {
|
|
48
|
+
prefix: string;
|
|
49
|
+
};
|
|
50
|
+
} & NormalizedConfig;
|
|
51
|
+
export declare type Then<T> = T extends PromiseLike<infer U> ? U : T;
|
|
52
|
+
export declare type ServerHookRunner = Then<ReturnType<typeof serverManager.init>>;
|
|
53
|
+
export declare type ReadyOptions = {
|
|
54
|
+
routes?: ModernRouteInterface[];
|
|
55
|
+
};
|
|
56
|
+
export type { Metrics, Logger, NextFunction };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { NormalizedConfig } from '@modern-js/core';
|
|
2
|
+
export declare const mergeExtension: (users: any[]) => {
|
|
3
|
+
middleware: any[];
|
|
4
|
+
};
|
|
5
|
+
export declare const toMessage: (dig: string, e: Error | string) => string;
|
|
6
|
+
export declare const noop: () => void;
|
|
7
|
+
export declare const createErrorDocument: (status: number, text: string) => string;
|
|
8
|
+
export declare type CollectMiddlewaresResult = {
|
|
9
|
+
web: any[];
|
|
10
|
+
api: any[];
|
|
11
|
+
};
|
|
12
|
+
export declare const createMiddlewareCollecter: () => {
|
|
13
|
+
getMiddlewares: () => CollectMiddlewaresResult;
|
|
14
|
+
addWebMiddleware: (input: any) => void;
|
|
15
|
+
addAPIMiddleware: (input: any) => void;
|
|
16
|
+
};
|
|
17
|
+
export declare const toPath: (reg: string, params: Record<string, any>) => string;
|
|
18
|
+
export declare const getStaticReg: (output?: NormalizedConfig['output']) => RegExp;
|
|
19
|
+
export declare const prepareFavicons: (favicon: string | undefined, faviconByEntries?: Record<string, string | undefined> | undefined) => string[];
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const sharedConfig = require('@scripts/jest-config');
|
|
2
|
+
|
|
3
|
+
/** @type {import('@jest/types').Config.InitialOptions} */
|
|
4
|
+
module.exports = {
|
|
5
|
+
// eslint-disable-next-line node/no-unsupported-features/es-syntax
|
|
6
|
+
...sharedConfig,
|
|
7
|
+
testEnvironment: 'node',
|
|
8
|
+
rootDir: __dirname,
|
|
9
|
+
};
|
package/modern.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@modern-js/prod-server",
|
|
3
|
+
"description": "The meta-framework suite designed from scratch for frontend-focused modern web development.",
|
|
4
|
+
"homepage": "https://modernjs.dev",
|
|
5
|
+
"bugs": "https://github.com/modern-js-dev/modern.js/issues",
|
|
6
|
+
"repository": "modern-js-dev/modern.js",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"react",
|
|
10
|
+
"framework",
|
|
11
|
+
"modern",
|
|
12
|
+
"modern.js"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.1",
|
|
15
|
+
"jsnext:source": "./src/index.ts",
|
|
16
|
+
"types": "./dist/types/index.d.ts",
|
|
17
|
+
"main": "./dist/js/node/index.js",
|
|
18
|
+
"module": "./dist/js/treeshaking/index.js",
|
|
19
|
+
"jsnext:modern": "./dist/js/modern/index.js",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"node": {
|
|
23
|
+
"jsnext:source": "./src/index.ts",
|
|
24
|
+
"import": "./dist/js/modern/index.js",
|
|
25
|
+
"require": "./dist/js/node/index.js"
|
|
26
|
+
},
|
|
27
|
+
"default": "./dist/js/treeshaking/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modern-js/core": "^1.4.4",
|
|
32
|
+
"@modern-js/utils": "^1.3.3",
|
|
33
|
+
"@babel/compat-data": "^7.17.0",
|
|
34
|
+
"@modern-js/server-core": "^1.2.2",
|
|
35
|
+
"axios": "^0.24.0",
|
|
36
|
+
"compare-versions": "^3.6.0",
|
|
37
|
+
"http-proxy-middleware": "^2.0.1",
|
|
38
|
+
"ignore-styles": "^5.0.1",
|
|
39
|
+
"mime-types": "^2.1.32",
|
|
40
|
+
"path-to-regexp": "^6.2.0",
|
|
41
|
+
"serve-static": "^1.14.1",
|
|
42
|
+
"lru-cache": "^6.0.0",
|
|
43
|
+
"ua-parser-js": "^0.7.28",
|
|
44
|
+
"lodash.clone": "^4.5.0",
|
|
45
|
+
"cookie": "^0.4.2"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@modern-js/types": "^1.3.4",
|
|
49
|
+
"@scripts/jest-config": "0.0.0",
|
|
50
|
+
"@scripts/build": "0.0.0",
|
|
51
|
+
"del-cli": "^4.0.1",
|
|
52
|
+
"@types/lru-cache": "^5.1.1",
|
|
53
|
+
"@types/mime-types": "^2.1.0",
|
|
54
|
+
"@types/serve-static": "^1.13.10",
|
|
55
|
+
"@types/ua-parser-js": "^0.7.36",
|
|
56
|
+
"@types/lodash.clone": "^4",
|
|
57
|
+
"@types/cookie": "^0.4.1",
|
|
58
|
+
"typescript": "^4",
|
|
59
|
+
"@types/jest": "^26.0.9",
|
|
60
|
+
"@types/node": "^14",
|
|
61
|
+
"node-mocks-http": "^1.11.0",
|
|
62
|
+
"jest": "^27",
|
|
63
|
+
"portfinder": "^1.0.28"
|
|
64
|
+
},
|
|
65
|
+
"sideEffects": false,
|
|
66
|
+
"modernConfig": {
|
|
67
|
+
"output": {
|
|
68
|
+
"packageMode": "node-js"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"publishConfig": {
|
|
72
|
+
"access": "public",
|
|
73
|
+
"registry": "https://registry.npmjs.org/"
|
|
74
|
+
},
|
|
75
|
+
"scripts": {
|
|
76
|
+
"new": "modern new",
|
|
77
|
+
"build": "modern build",
|
|
78
|
+
"dev": "modern build --watch",
|
|
79
|
+
"test": "jest --passWithNoTests"
|
|
80
|
+
},
|
|
81
|
+
"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"
|
|
82
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const AGGRED_DIR = {
|
|
2
|
+
mock: 'config/mock',
|
|
3
|
+
server: 'server',
|
|
4
|
+
api: 'api',
|
|
5
|
+
shared: 'shared',
|
|
6
|
+
lambda: 'lambda',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export enum ApiServerMode {
|
|
10
|
+
func = 'function',
|
|
11
|
+
frame = 'framework',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const ERROR_DIGEST = {
|
|
15
|
+
INIT: 'Server init error',
|
|
16
|
+
ENOTF: 'Page could not be found',
|
|
17
|
+
WARMUP: 'SSR warmup failed',
|
|
18
|
+
EINTER: 'Internal server error',
|
|
19
|
+
ERENDER: 'SSR render failed',
|
|
20
|
+
EMICROINJ: 'Get micro-frontend info failed',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const ERROR_PAGE_TEXT: Record<number, string> = {
|
|
24
|
+
404: 'This page could not be found.',
|
|
25
|
+
500: 'Internal Server Error.',
|
|
26
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ModernServerOptions } from './type';
|
|
2
|
+
import { Server } from './server';
|
|
3
|
+
|
|
4
|
+
export { Server };
|
|
5
|
+
export { ModernServer } from './server/modern-server';
|
|
6
|
+
export { createProxyHandler } from './libs/proxy';
|
|
7
|
+
export * from './type';
|
|
8
|
+
export * from './constants';
|
|
9
|
+
|
|
10
|
+
export default (options: ModernServerOptions): Promise<Server> => {
|
|
11
|
+
if (options == null) {
|
|
12
|
+
throw new Error('can not start mserver without options');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const server = new Server(options);
|
|
16
|
+
|
|
17
|
+
return server.init();
|
|
18
|
+
};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
import { URL } from 'url';
|
|
3
|
+
import qs from 'querystring';
|
|
4
|
+
import type {
|
|
5
|
+
ModernServerContext as ModernServerContextInterface,
|
|
6
|
+
Metrics,
|
|
7
|
+
Logger,
|
|
8
|
+
} from '@modern-js/types/server';
|
|
9
|
+
import { toMessage } from '../../utils';
|
|
10
|
+
|
|
11
|
+
export type ContextOptions = {
|
|
12
|
+
logger?: Logger;
|
|
13
|
+
metrics?: Metrics;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export class ModernServerContext implements ModernServerContextInterface {
|
|
17
|
+
/**
|
|
18
|
+
* http request
|
|
19
|
+
*/
|
|
20
|
+
public req: IncomingMessage;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* http response
|
|
24
|
+
*/
|
|
25
|
+
public res: ServerResponse;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* url params
|
|
29
|
+
*/
|
|
30
|
+
public params: Record<string, string> = {};
|
|
31
|
+
|
|
32
|
+
public logger: Logger;
|
|
33
|
+
|
|
34
|
+
public metrics?: Metrics;
|
|
35
|
+
|
|
36
|
+
public serverData: Record<string, any>;
|
|
37
|
+
|
|
38
|
+
constructor(req: IncomingMessage, res: ServerResponse) {
|
|
39
|
+
this.req = req;
|
|
40
|
+
this.res = res;
|
|
41
|
+
this.logger = req.logger;
|
|
42
|
+
this.metrics = req.metrics;
|
|
43
|
+
this.serverData = {};
|
|
44
|
+
|
|
45
|
+
this.bind();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private bind() {
|
|
49
|
+
const { req, res } = this as any;
|
|
50
|
+
req.get = (key: string) => this.getReqHeader(key);
|
|
51
|
+
res.set = (key: string, value: any) => this.res.setHeader(key, value);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public setParams(params: Record<string, string>) {
|
|
55
|
+
this.params = params;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public setServerData(key: string, value: any) {
|
|
59
|
+
this.serverData[key] = value;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public getReqHeader(key: string) {
|
|
63
|
+
const { req } = this;
|
|
64
|
+
const field = key.toLowerCase();
|
|
65
|
+
switch (field) {
|
|
66
|
+
case 'referer':
|
|
67
|
+
case 'referrer':
|
|
68
|
+
return req.headers.referrer || req.headers.referer || '';
|
|
69
|
+
default:
|
|
70
|
+
return req.headers[field] || '';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* request property */
|
|
75
|
+
public get headers() {
|
|
76
|
+
return this.req.headers;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public get method(): string {
|
|
80
|
+
return this.req.method!;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public get url() {
|
|
84
|
+
return this.req.url || '';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public set url(val) {
|
|
88
|
+
this.req.url = val;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public get host() {
|
|
92
|
+
let host = this.getReqHeader('X-Forwarded-Host');
|
|
93
|
+
if (!host) {
|
|
94
|
+
host = this.getReqHeader('Host');
|
|
95
|
+
}
|
|
96
|
+
return (host as string).split(/\s*,\s*/, 1)[0] || '';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public get protocol() {
|
|
100
|
+
if ((this.req.socket as any).encrypted) {
|
|
101
|
+
return 'https';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const proto = this.getReqHeader('X-Forwarded-Proto');
|
|
105
|
+
return proto ? (proto as string).split(/\s*,\s*/, 1)[0] : 'http';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public get origin() {
|
|
109
|
+
return `${this.protocol}://${this.host}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public get href() {
|
|
113
|
+
return this.origin + this.url;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public get parsedURL() {
|
|
117
|
+
const url = new URL(this.req.url!, this.origin);
|
|
118
|
+
return url;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public get path() {
|
|
122
|
+
return this.parsedURL.pathname;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public set path(p) {
|
|
126
|
+
const url = new URL(this.req.url!, this.origin);
|
|
127
|
+
// this should never happend
|
|
128
|
+
if (!url || !p) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (url.pathname === p) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
url.pathname = p;
|
|
137
|
+
|
|
138
|
+
this.url = url.toString();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public get querystring() {
|
|
142
|
+
if (!this.req) {
|
|
143
|
+
return '';
|
|
144
|
+
}
|
|
145
|
+
return this.parsedURL.search.replace(/^\?/, '') || '';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public get query() {
|
|
149
|
+
const str = this.querystring;
|
|
150
|
+
return qs.parse(str);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* response property */
|
|
154
|
+
public get status() {
|
|
155
|
+
return this.res.statusCode;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public set status(statusCode) {
|
|
159
|
+
this.res.statusCode = statusCode;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* 判断链接是否已经关闭
|
|
164
|
+
*/
|
|
165
|
+
public resHasHandled(): boolean {
|
|
166
|
+
return this.res.writableEnded;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public logInfo() {
|
|
170
|
+
return {
|
|
171
|
+
headers: this.headers,
|
|
172
|
+
href: this.href,
|
|
173
|
+
url: this.url,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public error(dig: string, err: Error | string = '') {
|
|
178
|
+
const message = toMessage(dig, err);
|
|
179
|
+
const reqInfo = this.logInfo();
|
|
180
|
+
|
|
181
|
+
this.logger.error(`${reqInfo.url} - ${message}`, reqInfo);
|
|
182
|
+
}
|
|
183
|
+
}
|