@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.
Files changed (70) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/js/modern/index.js +1 -7
  3. package/dist/js/modern/libs/context/context.js +3 -6
  4. package/dist/js/modern/libs/context/index.js +1 -7
  5. package/dist/js/modern/libs/hook-api/template.js +4 -4
  6. package/dist/js/modern/libs/proxy.js +1 -1
  7. package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +1 -2
  8. package/dist/js/modern/libs/render/index.js +6 -2
  9. package/dist/js/modern/libs/render/reader.js +8 -11
  10. package/dist/js/modern/libs/render/ssr.js +2 -1
  11. package/dist/js/modern/libs/route/index.js +2 -1
  12. package/dist/js/modern/server/index.js +3 -1
  13. package/dist/js/modern/server/modern-server.js +21 -11
  14. package/dist/js/modern/utils.js +1 -9
  15. package/dist/js/node/index.js +1 -49
  16. package/dist/js/node/libs/context/context.js +3 -6
  17. package/dist/js/node/libs/context/index.js +1 -7
  18. package/dist/js/node/libs/hook-api/template.js +4 -4
  19. package/dist/js/node/libs/proxy.js +1 -1
  20. package/dist/js/node/libs/render/cache/__tests__/cache.test.js +1 -2
  21. package/dist/js/node/libs/render/index.js +6 -2
  22. package/dist/js/node/libs/render/reader.js +8 -11
  23. package/dist/js/node/libs/render/ssr.js +2 -1
  24. package/dist/js/node/libs/route/index.js +6 -0
  25. package/dist/js/node/server/index.js +3 -1
  26. package/dist/js/node/server/modern-server.js +21 -11
  27. package/dist/js/node/utils.js +2 -12
  28. package/dist/types/index.d.ts +1 -3
  29. package/dist/types/libs/context/context.d.ts +7 -7
  30. package/dist/types/libs/context/index.d.ts +1 -8
  31. package/dist/types/libs/hook-api/template.d.ts +4 -4
  32. package/dist/types/libs/render/index.d.ts +10 -1
  33. package/dist/types/libs/render/ssr.d.ts +2 -1
  34. package/dist/types/libs/render/type.d.ts +2 -21
  35. package/dist/types/libs/route/index.d.ts +2 -1
  36. package/dist/types/server/modern-server.d.ts +1 -1
  37. package/dist/types/type.d.ts +6 -0
  38. package/dist/types/utils.d.ts +1 -2
  39. package/package.json +14 -12
  40. package/src/index.ts +2 -8
  41. package/src/libs/context/context.ts +8 -7
  42. package/src/libs/context/index.ts +2 -6
  43. package/src/libs/hook-api/template.ts +4 -4
  44. package/src/libs/proxy.ts +1 -1
  45. package/src/libs/render/cache/__tests__/cache.test.ts +2 -2
  46. package/src/libs/render/index.ts +21 -11
  47. package/src/libs/render/reader.ts +8 -8
  48. package/src/libs/render/ssr.ts +4 -0
  49. package/src/libs/render/type.ts +2 -17
  50. package/src/libs/route/index.ts +2 -1
  51. package/src/server/index.ts +1 -1
  52. package/src/server/modern-server.ts +20 -12
  53. package/src/type.ts +7 -0
  54. package/src/utils.ts +0 -14
  55. package/tests/.eslintrc.js +6 -0
  56. package/tests/context.test.ts +41 -0
  57. package/tests/fixtures/hosting-files/static/index.js +1 -0
  58. package/tests/fixtures/pure/modern.config.js +5 -0
  59. package/tests/fixtures/pure/package.json +21 -0
  60. package/tests/fixtures/pure/src/App.css +119 -0
  61. package/tests/fixtures/pure/src/App.tsx +43 -0
  62. package/tests/fixtures/pure/tsconfig.json +13 -0
  63. package/tests/fixtures/route-spec/index.json +29 -0
  64. package/tests/helper.ts +8 -0
  65. package/tests/hook.test.ts +44 -0
  66. package/tests/middleware.test.ts +178 -0
  67. package/tests/route.test.ts +54 -0
  68. package/tests/server.test.ts +89 -0
  69. package/tests/tsconfig.json +14 -0
  70. 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(context, route);
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.url);
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.afterHead(`<script>window.modern_manifest=${injection}</script>`);
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
- const context = (0, _context.createContext)(req, res, {
559
- logger: this.logger,
560
- metrics: this.metrics
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(context, route);
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);
@@ -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
- }; // This can live anywhere in your codebase:
68
-
69
-
70
- exports.createErrorDocument = createErrorDocument;
66
+ };
71
67
 
72
- function applyMixins(derivedCtor, constructors) {
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;
@@ -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
- beforeHead(fragment: string): this;
7
- afterHead(fragment: string): this;
8
- beforeBody(fragment: string): this;
9
- afterBody(fragment: string): this;
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
- }) => (ctx: ModernServerContext, route: ModernRoute) => Promise<RenderResult | null>;
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 { IncomingHttpHeaders } from 'http';
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, RouteMatcher, ModernRoute };
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,
@@ -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: {
@@ -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.1",
38
- "@modern-js/server-plugin": "^1.1.3",
39
- "@modern-js/server-utils": "^1.1.2",
40
- "@modern-js/bff-utils": "^1.1.1",
41
- "@modern-js/utils": "^1.1.5",
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.2",
65
- "@modern-js/plugin-testing": "^1.1.1",
66
- "@modern-js/types": "^1.1.4",
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 --passWithNoTests"
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: IncomingMessage,
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 beforeHead(fragment: string) {
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 afterHead(fragment: string) {
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 beforeBody(fragment: string) {
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 afterBody(fragment: string) {
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
@@ -54,7 +54,7 @@ export const createProxyHandler = (proxyOptions: ProxyOptions) => {
54
54
  );
55
55
  }
56
56
  } else {
57
- formatedProxy.concat(proxyOptions);
57
+ formatedProxy.push(...proxyOptions);
58
58
  }
59
59
 
60
60
  const middlewares = formatedProxy.map(option => {
@@ -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();
@@ -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: ModernServerContext,
22
- route: ModernRoute,
23
- ): Promise<RenderResult | null> {
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(ctx, {
47
- distDir,
48
- entryName: route.entryName,
49
- bundle: route.bundle,
50
- template: templateHTML,
51
- staticGenerate,
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
- clearInterval(this.timer);
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
- this.timer = setInterval(() => this.update, 5 * 60 * 1000).unref();
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();
@@ -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);
@@ -1,5 +1,4 @@
1
- import { IncomingHttpHeaders } from 'http';
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
  };
@@ -73,4 +73,5 @@ export class RouteMatchManager {
73
73
  }
74
74
  }
75
75
 
76
- export type { ModernRouteInterface, RouteMatcher, ModernRoute };
76
+ export type { ModernRouteInterface, ModernRoute };
77
+ export { RouteMatcher };