@modern-js/prod-server 1.20.1 → 1.21.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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # @modern-js/prod-server
2
2
 
3
+ ## 1.21.0
4
+
5
+ ### Patch Changes
6
+
7
+ - f51c59a: feat: remove node internal package like fs or path which import by ssr runtime
8
+ feat: 删除在 ssr runtime 中引用的 node 内部包
9
+ - 8f3674a: chore: reduce parameters for dev-server & update default config value in builder startDevServer
10
+
11
+ chore: 缩简 devServer 配置定义 & 更新 builder startDevServer 方法 config 默认值
12
+
13
+ - 519965e: fix: should not do render if set location header and 302 status in middleware
14
+ fix: 如果在 middleware 中设置了 location 头和 302 状态码,则不应该走渲染逻辑
15
+ - 67d80b7: fix(prod-server): failed to match URL which ends with ".html"
16
+
17
+ fix(prod-server): 修复无法匹配到以 ".html" 结尾的 URL 的问题
18
+
19
+ - @modern-js/server-core@1.21.0
20
+ - @modern-js/utils@1.21.0
21
+
3
22
  ## 1.20.1
4
23
 
5
24
  ### Patch Changes
@@ -19,7 +19,7 @@ export const requireConfig = serverConfigPath => {
19
19
  return {};
20
20
  };
21
21
  /**
22
- * 对配置进行合并,开发环境下,cliConfig 与 serverConfig 进行深合并
22
+ * 对配置进行合并,开发环境下,cliConfig 与 serverConfig 进行深合并
23
23
  * 生产环境下,resolvedConfig 与 serverConfig 进行深合并
24
24
  * resolvedConfigPath: 构建序列化后的 modern.config.js 文件路径
25
25
  */
@@ -32,7 +32,18 @@ export const createRenderHandler = ({
32
32
  const modernEntry = getModernEntry(entry);
33
33
  const useModern = // route.enableModernMode &&
34
34
  supportModern(ctx) && fs.existsSync(modernEntry);
35
- const templateHTML = useModern ? modernEntry : entry; // handles ssr first
35
+ const templatePath = useModern ? modernEntry : entry;
36
+
37
+ if (!fs.existsSync(templatePath)) {
38
+ throw new Error(`Could not find template file: ${templatePath}`);
39
+ }
40
+
41
+ const content = await readFile(templatePath);
42
+
43
+ if (!content) {
44
+ return null;
45
+ } // handles ssr first
46
+
36
47
 
37
48
  if (route.isSSR) {
38
49
  try {
@@ -41,7 +52,7 @@ export const createRenderHandler = ({
41
52
  entryName: route.entryName,
42
53
  urlPath: route.urlPath,
43
54
  bundle: route.bundle,
44
- template: templateHTML,
55
+ template: content.toString(),
45
56
  staticGenerate
46
57
  }, runner);
47
58
  return result;
@@ -51,14 +62,8 @@ export const createRenderHandler = ({
51
62
  }
52
63
  }
53
64
 
54
- const content = await readFile(templateHTML);
55
-
56
- if (!content) {
57
- return null;
58
- }
59
-
60
65
  return {
61
66
  content,
62
- contentType: mime.contentType(path.extname(templateHTML))
67
+ contentType: mime.contentType(path.extname(templatePath))
63
68
  };
64
69
  };
@@ -1,5 +1,5 @@
1
1
  import path from 'path';
2
- import { mime, SERVER_RENDER_FUNCTION_NAME } from '@modern-js/utils';
2
+ import { fs, LOADABLE_STATS_FILE, mime, SERVER_RENDER_FUNCTION_NAME } from '@modern-js/utils';
3
3
  import cookie from 'cookie';
4
4
  import cache from "./cache";
5
5
  import { createLogger, createMetrics } from "./measure";
@@ -13,6 +13,8 @@ export const render = async (ctx, renderOptions, runner) => {
13
13
  staticGenerate
14
14
  } = renderOptions;
15
15
  const bundleJS = path.join(distDir, bundle);
16
+ const loadableUri = path.join(distDir, LOADABLE_STATS_FILE);
17
+ const loadableStats = fs.existsSync(loadableUri) ? require(loadableUri) : '';
16
18
  const context = {
17
19
  request: {
18
20
  baseUrl: urlPath,
@@ -34,8 +36,8 @@ export const render = async (ctx, renderOptions, runner) => {
34
36
  },
35
37
  redirection: {},
36
38
  template,
39
+ loadableStats,
37
40
  entryName,
38
- distDir,
39
41
  staticGenerate,
40
42
  logger: undefined,
41
43
  metrics: undefined
@@ -56,7 +56,11 @@ export class RouteMatcher {
56
56
 
57
57
 
58
58
  matchUrlPath(requestUrl) {
59
- const urlWithoutSlash = requestUrl.endsWith('/') && requestUrl !== '/' ? requestUrl.slice(0, -1) : requestUrl;
59
+ let urlWithoutSlash = requestUrl.endsWith('/') && requestUrl !== '/' ? requestUrl.slice(0, -1) : requestUrl;
60
+
61
+ if (urlWithoutSlash.endsWith('.html')) {
62
+ urlWithoutSlash = urlWithoutSlash.slice(0, -5);
63
+ }
60
64
 
61
65
  if (this.urlMatcher) {
62
66
  return Boolean(this.urlMatcher(urlWithoutSlash));
@@ -381,7 +381,7 @@ export class ModernServer {
381
381
  routeAPI
382
382
  });
383
383
 
384
- if (res.headersSent) {
384
+ if (this.isSend(res)) {
385
385
  return;
386
386
  }
387
387
 
@@ -405,7 +405,7 @@ export class ModernServer {
405
405
  } // frameWebHandler has process request
406
406
 
407
407
 
408
- if (res.headersSent) {
408
+ if (this.isSend(res)) {
409
409
  return;
410
410
  }
411
411
 
@@ -439,8 +439,7 @@ export class ModernServer {
439
439
  return;
440
440
  }
441
441
 
442
- if (res.getHeader('Location') && isRedirect(res.statusCode)) {
443
- res.end();
442
+ if (this.isSend(res)) {
444
443
  return;
445
444
  }
446
445
 
@@ -452,6 +451,11 @@ export class ModernServer {
452
451
  context,
453
452
  templateAPI
454
453
  });
454
+
455
+ if (this.isSend(res)) {
456
+ return;
457
+ }
458
+
455
459
  await this.injectMicroFE(context, templateAPI); // It will inject _SERVER_DATA twice, when SSG mode.
456
460
  // The first time was in ssg html created, the seoncd time was in prod-server start.
457
461
  // but the second wound causes route error.
@@ -465,6 +469,19 @@ export class ModernServer {
465
469
  res.end(response);
466
470
  }
467
471
 
472
+ isSend(res) {
473
+ if (res.headersSent) {
474
+ return true;
475
+ }
476
+
477
+ if (res.getHeader('Location') && isRedirect(res.statusCode)) {
478
+ res.end();
479
+ return true;
480
+ }
481
+
482
+ return false;
483
+ }
484
+
468
485
  async injectMicroFE(context, templateAPI) {
469
486
  var _conf$runtime, _conf$server;
470
487
 
@@ -38,7 +38,7 @@ const requireConfig = serverConfigPath => {
38
38
  return {};
39
39
  };
40
40
  /**
41
- * 对配置进行合并,开发环境下,cliConfig 与 serverConfig 进行深合并
41
+ * 对配置进行合并,开发环境下,cliConfig 与 serverConfig 进行深合并
42
42
  * 生产环境下,resolvedConfig 与 serverConfig 进行深合并
43
43
  * resolvedConfigPath: 构建序列化后的 modern.config.js 文件路径
44
44
  */
@@ -55,7 +55,18 @@ const createRenderHandler = ({
55
55
  const useModern = // route.enableModernMode &&
56
56
  (0, _modern.supportModern)(ctx) && _utils.fs.existsSync(modernEntry);
57
57
 
58
- const templateHTML = useModern ? modernEntry : entry; // handles ssr first
58
+ const templatePath = useModern ? modernEntry : entry;
59
+
60
+ if (!_utils.fs.existsSync(templatePath)) {
61
+ throw new Error(`Could not find template file: ${templatePath}`);
62
+ }
63
+
64
+ const content = await (0, _reader.readFile)(templatePath);
65
+
66
+ if (!content) {
67
+ return null;
68
+ } // handles ssr first
69
+
59
70
 
60
71
  if (route.isSSR) {
61
72
  try {
@@ -64,7 +75,7 @@ const createRenderHandler = ({
64
75
  entryName: route.entryName,
65
76
  urlPath: route.urlPath,
66
77
  bundle: route.bundle,
67
- template: templateHTML,
78
+ template: content.toString(),
68
79
  staticGenerate
69
80
  }, runner);
70
81
  return result;
@@ -74,15 +85,9 @@ const createRenderHandler = ({
74
85
  }
75
86
  }
76
87
 
77
- const content = await (0, _reader.readFile)(templateHTML);
78
-
79
- if (!content) {
80
- return null;
81
- }
82
-
83
88
  return {
84
89
  content,
85
- contentType: _utils.mime.contentType(_path.default.extname(templateHTML))
90
+ contentType: _utils.mime.contentType(_path.default.extname(templatePath))
86
91
  };
87
92
  };
88
93
 
@@ -29,6 +29,9 @@ const render = async (ctx, renderOptions, runner) => {
29
29
 
30
30
  const bundleJS = _path.default.join(distDir, bundle);
31
31
 
32
+ const loadableUri = _path.default.join(distDir, _utils.LOADABLE_STATS_FILE);
33
+
34
+ const loadableStats = _utils.fs.existsSync(loadableUri) ? require(loadableUri) : '';
32
35
  const context = {
33
36
  request: {
34
37
  baseUrl: urlPath,
@@ -50,8 +53,8 @@ const render = async (ctx, renderOptions, runner) => {
50
53
  },
51
54
  redirection: {},
52
55
  template,
56
+ loadableStats,
53
57
  entryName,
54
- distDir,
55
58
  staticGenerate,
56
59
  logger: undefined,
57
60
  metrics: undefined
@@ -68,7 +68,11 @@ class RouteMatcher {
68
68
 
69
69
 
70
70
  matchUrlPath(requestUrl) {
71
- const urlWithoutSlash = requestUrl.endsWith('/') && requestUrl !== '/' ? requestUrl.slice(0, -1) : requestUrl;
71
+ let urlWithoutSlash = requestUrl.endsWith('/') && requestUrl !== '/' ? requestUrl.slice(0, -1) : requestUrl;
72
+
73
+ if (urlWithoutSlash.endsWith('.html')) {
74
+ urlWithoutSlash = urlWithoutSlash.slice(0, -5);
75
+ }
72
76
 
73
77
  if (this.urlMatcher) {
74
78
  return Boolean(this.urlMatcher(urlWithoutSlash));
@@ -418,7 +418,7 @@ class ModernServer {
418
418
  routeAPI
419
419
  });
420
420
 
421
- if (res.headersSent) {
421
+ if (this.isSend(res)) {
422
422
  return;
423
423
  }
424
424
 
@@ -442,7 +442,7 @@ class ModernServer {
442
442
  } // frameWebHandler has process request
443
443
 
444
444
 
445
- if (res.headersSent) {
445
+ if (this.isSend(res)) {
446
446
  return;
447
447
  }
448
448
 
@@ -476,8 +476,7 @@ class ModernServer {
476
476
  return;
477
477
  }
478
478
 
479
- if (res.getHeader('Location') && (0, _utils2.isRedirect)(res.statusCode)) {
480
- res.end();
479
+ if (this.isSend(res)) {
481
480
  return;
482
481
  }
483
482
 
@@ -489,6 +488,11 @@ class ModernServer {
489
488
  context,
490
489
  templateAPI
491
490
  });
491
+
492
+ if (this.isSend(res)) {
493
+ return;
494
+ }
495
+
492
496
  await this.injectMicroFE(context, templateAPI); // It will inject _SERVER_DATA twice, when SSG mode.
493
497
  // The first time was in ssg html created, the seoncd time was in prod-server start.
494
498
  // but the second wound causes route error.
@@ -502,6 +506,19 @@ class ModernServer {
502
506
  res.end(response);
503
507
  }
504
508
 
509
+ isSend(res) {
510
+ if (res.headersSent) {
511
+ return true;
512
+ }
513
+
514
+ if (res.getHeader('Location') && (0, _utils2.isRedirect)(res.statusCode)) {
515
+ res.end();
516
+ return true;
517
+ }
518
+
519
+ return false;
520
+ }
521
+
505
522
  async injectMicroFE(context, templateAPI) {
506
523
  var _conf$runtime, _conf$server;
507
524
 
@@ -1,9 +1,8 @@
1
- import type { NormalizedConfig } from '@modern-js/core';
2
- import type { ServerConfig } from '@modern-js/server-core';
1
+ import type { ServerConfig, ServerOptions } from '@modern-js/server-core';
3
2
  export declare const getServerConfigPath: (distDirectory: string, serverConfigFile?: string) => string;
4
3
  export declare const requireConfig: (serverConfigPath: string) => any;
5
4
  /**
6
- * 对配置进行合并,开发环境下,cliConfig 与 serverConfig 进行深合并
5
+ * 对配置进行合并,开发环境下,cliConfig 与 serverConfig 进行深合并
7
6
  * 生产环境下,resolvedConfig 与 serverConfig 进行深合并
8
7
  * resolvedConfigPath: 构建序列化后的 modern.config.js 文件路径
9
8
  */
@@ -13,7 +12,7 @@ export declare const loadConfig: ({
13
12
  serverConfig,
14
13
  resolvedConfigPath
15
14
  }: {
16
- cliConfig: NormalizedConfig;
15
+ cliConfig: ServerOptions;
17
16
  serverConfig: ServerConfig;
18
17
  resolvedConfigPath: string;
19
18
  }) => any;
@@ -1,9 +1,9 @@
1
- import { NormalizedConfig } from '@modern-js/core';
1
+ import { ServerOptions } from '@modern-js/server-core';
2
2
  import type { ModernServerContext } from '@modern-js/types';
3
3
  import { NextFunction } from '../type';
4
4
  declare type Rule = {
5
5
  path: string | RegExp;
6
6
  target: string;
7
7
  };
8
- export declare const createStaticFileHandler: (rules: Rule[], output?: NormalizedConfig['output']) => (context: ModernServerContext, next: NextFunction) => Promise<void>;
8
+ export declare const createStaticFileHandler: (rules: Rule[], output?: ServerOptions['output']) => (context: ModernServerContext, next: NextFunction) => Promise<void>;
9
9
  export {};
@@ -1,7 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { IncomingMessage, ServerResponse, Server } from 'http';
3
- import { Adapter, APIServerStartInput } from '@modern-js/server-core';
4
- import type { NormalizedConfig } from '@modern-js/core';
3
+ import { Adapter, APIServerStartInput, ServerOptions } from '@modern-js/server-core';
5
4
  import type { ModernServerContext } from '@modern-js/types';
6
5
  import type { ContextOptions } from '../libs/context';
7
6
  import { ModernServerOptions, NextFunction, ServerHookRunner, Metrics, Logger, ModernServerInterface, HookNames, BuildOptions, ModernServerHandler } from '../type';
@@ -14,7 +13,7 @@ export declare class ModernServer implements ModernServerInterface {
14
13
  distDir: string;
15
14
  protected workDir: string;
16
15
  protected router: RouteMatchManager;
17
- protected conf: NormalizedConfig;
16
+ protected conf: ServerOptions;
18
17
  protected handlers: ModernServerAsyncHandler[];
19
18
  protected presetRoutes?: ModernRouteInterface[];
20
19
  protected runner: ServerHookRunner;
@@ -70,6 +69,7 @@ export declare class ModernServer implements ModernServerInterface {
70
69
  protected warmupSSRBundle(): void;
71
70
  protected createContext(req: IncomingMessage, res: ServerResponse, options?: ContextOptions): import("../libs/context").ModernServerContext;
72
71
  private routeHandler;
72
+ private isSend;
73
73
  private injectMicroFE;
74
74
  private compose;
75
75
  private requestHandler;
@@ -1,9 +1,8 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
3
  import { IncomingMessage, Server, ServerResponse } from 'http';
4
- import { serverManager } from '@modern-js/server-core';
4
+ import { serverManager, ServerOptions } from '@modern-js/server-core';
5
5
  import type { ServerPlugin } from '@modern-js/server-core';
6
- import type { NormalizedConfig } from '@modern-js/core';
7
6
  import type { Metrics, Logger, NextFunction, ModernServerContext } from '@modern-js/types';
8
7
  import type { ModernRouteInterface } from './libs/route';
9
8
  declare module 'http' {
@@ -15,7 +14,7 @@ declare module 'http' {
15
14
  declare type Plugin = string | [string, any] | ServerPlugin;
16
15
  export declare type ModernServerOptions = {
17
16
  pwd: string;
18
- config: NormalizedConfig;
17
+ config: ServerOptions;
19
18
  plugins?: Plugin[];
20
19
  routes?: ModernRouteInterface[];
21
20
  staticGenerate?: boolean;
@@ -42,8 +41,8 @@ export declare type RenderResult = {
42
41
  export declare type ConfWithBFF = {
43
42
  bff?: {
44
43
  prefix: string;
45
- };
46
- } & NormalizedConfig;
44
+ } & ServerOptions['bff'];
45
+ };
47
46
  export declare type Then<T> = T extends PromiseLike<infer U> ? U : T;
48
47
  export declare type ServerHookRunner = Then<ReturnType<typeof serverManager.init>>;
49
48
  export declare type BuildOptions = {
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.20.1",
14
+ "version": "1.21.0",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -28,9 +28,9 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@modern-js/utils": "1.20.1",
31
+ "@modern-js/utils": "1.21.0",
32
32
  "@babel/compat-data": "^7.17.10",
33
- "@modern-js/server-core": "1.20.1",
33
+ "@modern-js/server-core": "1.21.0",
34
34
  "axios": "^0.24.0",
35
35
  "etag": "^1.8.1",
36
36
  "fresh": "^0.5.2",
@@ -45,10 +45,10 @@
45
45
  "ua-parser-js": "^0.7.28"
46
46
  },
47
47
  "devDependencies": {
48
- "@modern-js/types": "1.20.1",
49
- "@modern-js/core": "1.20.1",
50
- "@scripts/jest-config": "1.20.1",
51
- "@scripts/build": "1.20.1",
48
+ "@modern-js/types": "1.21.0",
49
+ "@modern-js/core": "1.21.0",
50
+ "@scripts/jest-config": "1.21.0",
51
+ "@scripts/build": "1.21.0",
52
52
  "@types/cookie": "^0.4.1",
53
53
  "@types/jest": "^27",
54
54
  "@types/lru-cache": "^5.1.1",