@modern-js/prod-server 2.0.0-beta.0 → 2.0.0-beta.2

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 (113) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/dist/js/modern/constants.js +0 -2
  3. package/dist/js/modern/index.js +0 -1
  4. package/dist/js/modern/libs/context/context.js +10 -56
  5. package/dist/js/modern/libs/hook-api/index.js +0 -31
  6. package/dist/js/modern/libs/hook-api/route.js +0 -8
  7. package/dist/js/modern/libs/hook-api/template.js +0 -16
  8. package/dist/js/modern/libs/loadConfig.js +3 -10
  9. package/dist/js/modern/libs/metrics.js +6 -6
  10. package/dist/js/modern/libs/proxy.js +7 -12
  11. package/dist/js/modern/libs/render/cache/__tests__/cache.fun.test.js +0 -1
  12. package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +0 -9
  13. package/dist/js/modern/libs/render/cache/index.js +8 -16
  14. package/dist/js/modern/libs/render/cache/page-caches/lru.js +0 -10
  15. package/dist/js/modern/libs/render/cache/spr.js +12 -62
  16. package/dist/js/modern/libs/render/cache/util.js +0 -6
  17. package/dist/js/modern/libs/render/index.js +6 -11
  18. package/dist/js/modern/libs/render/measure.js +1 -11
  19. package/dist/js/modern/libs/render/modern/index.js +2 -13
  20. package/dist/js/modern/libs/render/reader.js +13 -24
  21. package/dist/js/modern/libs/render/ssr.js +5 -6
  22. package/dist/js/modern/libs/render/static.js +6 -9
  23. package/dist/js/modern/libs/render/type.js +0 -1
  24. package/dist/js/modern/libs/route/index.js +8 -19
  25. package/dist/js/modern/libs/route/matcher.js +21 -29
  26. package/dist/js/modern/libs/route/route.js +0 -13
  27. package/dist/js/modern/libs/serve-file.js +5 -6
  28. package/dist/js/modern/server/index.js +25 -52
  29. package/dist/js/modern/server/modern-server-split.js +0 -11
  30. package/dist/js/modern/server/modern-server.js +87 -167
  31. package/dist/js/modern/utils.js +12 -27
  32. package/dist/js/modern/worker-server.js +34 -0
  33. package/dist/js/node/constants.js +0 -2
  34. package/dist/js/node/index.js +0 -10
  35. package/dist/js/node/libs/context/context.js +10 -65
  36. package/dist/js/node/libs/context/index.js +0 -3
  37. package/dist/js/node/libs/hook-api/index.js +0 -42
  38. package/dist/js/node/libs/hook-api/route.js +0 -10
  39. package/dist/js/node/libs/hook-api/template.js +0 -22
  40. package/dist/js/node/libs/loadConfig.js +3 -22
  41. package/dist/js/node/libs/metrics.js +6 -6
  42. package/dist/js/node/libs/proxy.js +7 -17
  43. package/dist/js/node/libs/render/cache/__tests__/cache.fun.test.js +0 -5
  44. package/dist/js/node/libs/render/cache/__tests__/cache.test.js +0 -12
  45. package/dist/js/node/libs/render/cache/index.js +8 -22
  46. package/dist/js/node/libs/render/cache/page-caches/index.js +0 -2
  47. package/dist/js/node/libs/render/cache/page-caches/lru.js +0 -14
  48. package/dist/js/node/libs/render/cache/spr.js +12 -71
  49. package/dist/js/node/libs/render/cache/util.js +0 -18
  50. package/dist/js/node/libs/render/index.js +6 -26
  51. package/dist/js/node/libs/render/measure.js +0 -17
  52. package/dist/js/node/libs/render/modern/index.js +2 -20
  53. package/dist/js/node/libs/render/reader.js +12 -39
  54. package/dist/js/node/libs/render/ssr.js +4 -16
  55. package/dist/js/node/libs/render/static.js +6 -18
  56. package/dist/js/node/libs/render/type.js +0 -1
  57. package/dist/js/node/libs/route/index.js +8 -22
  58. package/dist/js/node/libs/route/matcher.js +18 -34
  59. package/dist/js/node/libs/route/route.js +0 -15
  60. package/dist/js/node/libs/serve-file.js +5 -13
  61. package/dist/js/node/server/index.js +25 -72
  62. package/dist/js/node/server/modern-server-split.js +0 -13
  63. package/dist/js/node/server/modern-server.js +87 -196
  64. package/dist/js/node/utils.js +13 -52
  65. package/dist/js/node/worker-server.js +41 -0
  66. package/dist/js/treeshaking/constants.js +28 -0
  67. package/dist/js/treeshaking/index.js +13 -0
  68. package/dist/js/treeshaking/libs/context/context.js +243 -0
  69. package/dist/js/treeshaking/libs/context/index.js +5 -0
  70. package/dist/js/treeshaking/libs/hook-api/index.js +157 -0
  71. package/dist/js/treeshaking/libs/hook-api/route.js +33 -0
  72. package/dist/js/treeshaking/libs/hook-api/template.js +91 -0
  73. package/dist/js/treeshaking/libs/loadConfig.js +39 -0
  74. package/dist/js/treeshaking/libs/metrics.js +12 -0
  75. package/dist/js/treeshaking/libs/proxy.js +80 -0
  76. package/dist/js/treeshaking/libs/render/cache/__tests__/cache.fun.test.js +124 -0
  77. package/dist/js/treeshaking/libs/render/cache/__tests__/cache.test.js +464 -0
  78. package/dist/js/treeshaking/libs/render/cache/__tests__/cacheable.js +53 -0
  79. package/dist/js/treeshaking/libs/render/cache/__tests__/error-configuration.js +35 -0
  80. package/dist/js/treeshaking/libs/render/cache/__tests__/matched-cache.js +121 -0
  81. package/dist/js/treeshaking/libs/render/cache/index.js +184 -0
  82. package/dist/js/treeshaking/libs/render/cache/page-caches/index.js +30 -0
  83. package/dist/js/treeshaking/libs/render/cache/page-caches/lru.js +46 -0
  84. package/dist/js/treeshaking/libs/render/cache/spr.js +362 -0
  85. package/dist/js/treeshaking/libs/render/cache/type.js +1 -0
  86. package/dist/js/treeshaking/libs/render/cache/util.js +101 -0
  87. package/dist/js/treeshaking/libs/render/index.js +100 -0
  88. package/dist/js/treeshaking/libs/render/measure.js +61 -0
  89. package/dist/js/treeshaking/libs/render/modern/browser-list.js +7 -0
  90. package/dist/js/treeshaking/libs/render/modern/index.js +39 -0
  91. package/dist/js/treeshaking/libs/render/reader.js +191 -0
  92. package/dist/js/treeshaking/libs/render/ssr.js +98 -0
  93. package/dist/js/treeshaking/libs/render/static.js +84 -0
  94. package/dist/js/treeshaking/libs/render/type.js +6 -0
  95. package/dist/js/treeshaking/libs/route/index.js +94 -0
  96. package/dist/js/treeshaking/libs/route/matcher.js +113 -0
  97. package/dist/js/treeshaking/libs/route/route.js +26 -0
  98. package/dist/js/treeshaking/libs/serve-file.js +75 -0
  99. package/dist/js/treeshaking/server/index.js +339 -0
  100. package/dist/js/treeshaking/server/modern-server-split.js +152 -0
  101. package/dist/js/treeshaking/server/modern-server.js +946 -0
  102. package/dist/js/treeshaking/type.js +1 -0
  103. package/dist/js/treeshaking/utils.js +90 -0
  104. package/dist/js/treeshaking/worker-server.js +56 -0
  105. package/dist/types/index.d.ts +0 -2
  106. package/dist/types/libs/context/context.d.ts +0 -3
  107. package/dist/types/libs/loadConfig.d.ts +0 -1
  108. package/dist/types/libs/render/cache/index.d.ts +0 -2
  109. package/dist/types/libs/render/cache/spr.d.ts +0 -2
  110. package/dist/types/server/index.d.ts +0 -3
  111. package/dist/types/utils.d.ts +2 -3
  112. package/dist/types/worker-server.d.ts +16 -0
  113. package/package.json +31 -15
@@ -4,60 +4,38 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.ModernServer = void 0;
7
-
8
7
  var _http = require("http");
9
-
10
8
  var _util = _interopRequireDefault(require("util"));
11
-
12
9
  var _path = _interopRequireDefault(require("path"));
13
-
14
10
  var _utils = require("@modern-js/utils");
15
-
16
11
  var _route = require("../libs/route");
17
-
18
12
  var _render = require("../libs/render");
19
-
20
13
  var _serveFile = require("../libs/serve-file");
21
-
22
14
  var _utils2 = require("../utils");
23
-
24
15
  var reader = _interopRequireWildcard(require("../libs/render/reader"));
25
-
26
16
  var _proxy = require("../libs/proxy");
27
-
28
17
  var _context = require("../libs/context");
29
-
30
18
  var _template = require("../libs/hook-api/template");
31
-
32
19
  var _constants = require("../constants");
33
-
34
20
  var _hookApi = require("../libs/hook-api");
35
-
36
21
  const _excluded = ["getMiddlewares"];
37
-
38
22
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
39
-
40
23
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
41
-
42
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
-
44
25
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
45
-
46
26
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
47
-
48
27
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
49
-
50
28
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
51
-
52
29
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
53
-
54
30
  const API_DIR = './api';
55
31
  const SERVER_DIR = './server';
56
-
57
32
  class ModernServer {
58
33
  // appDirectory
34
+
59
35
  // product dist dir
36
+
60
37
  // work on src or dist
38
+
61
39
  constructor({
62
40
  pwd,
63
41
  config,
@@ -68,54 +46,30 @@ class ModernServer {
68
46
  runMode,
69
47
  proxyTarget
70
48
  }) {
71
- var _config$output;
72
-
73
49
  _defineProperty(this, "pwd", void 0);
74
-
75
50
  _defineProperty(this, "distDir", void 0);
76
-
77
51
  _defineProperty(this, "workDir", void 0);
78
-
79
52
  _defineProperty(this, "router", void 0);
80
-
81
53
  _defineProperty(this, "conf", void 0);
82
-
83
54
  _defineProperty(this, "handlers", []);
84
-
85
55
  _defineProperty(this, "presetRoutes", void 0);
86
-
87
56
  _defineProperty(this, "runner", void 0);
88
-
89
57
  _defineProperty(this, "logger", void 0);
90
-
91
58
  _defineProperty(this, "metrics", void 0);
92
-
93
59
  _defineProperty(this, "runMode", void 0);
94
-
95
60
  _defineProperty(this, "reader", reader);
96
-
97
61
  _defineProperty(this, "proxyTarget", void 0);
98
-
99
62
  _defineProperty(this, "staticFileHandler", void 0);
100
-
101
63
  _defineProperty(this, "routeRenderHandler", void 0);
102
-
103
64
  _defineProperty(this, "beforeRouteHandler", null);
104
-
105
65
  _defineProperty(this, "frameWebHandler", null);
106
-
107
66
  _defineProperty(this, "frameAPIHandler", null);
108
-
109
67
  _defineProperty(this, "proxyHandler", null);
110
-
111
68
  _defineProperty(this, "_handler", void 0);
112
-
113
69
  _defineProperty(this, "staticGenerate", void 0);
114
-
115
70
  require('ignore-styles');
116
-
117
71
  this.pwd = pwd;
118
- this.distDir = _path.default.join(pwd, ((_config$output = config.output) === null || _config$output === void 0 ? void 0 : _config$output.path) || 'dist');
72
+ this.distDir = _path.default.join(pwd, config.output.path || 'dist');
119
73
  this.workDir = this.distDir;
120
74
  this.conf = config;
121
75
  (0, _utils2.debug)('server conf', this.conf);
@@ -125,44 +79,48 @@ class ModernServer {
125
79
  this.presetRoutes = routes;
126
80
  this.proxyTarget = proxyTarget;
127
81
  this.staticGenerate = staticGenerate || false;
128
- this.runMode = runMode || _constants.RUN_MODE.FULL; // process.env.BUILD_TYPE = `${this.staticGenerate ? 'ssg' : 'ssr'}`;
129
- } // server prepare
130
-
82
+ this.runMode = runMode || _constants.RUN_MODE.FULL;
83
+ // process.env.BUILD_TYPE = `${this.staticGenerate ? 'ssg' : 'ssr'}`;
84
+ }
131
85
 
86
+ // server prepare
132
87
  async onInit(runner, app) {
133
88
  var _conf$bff;
134
-
135
89
  this.runner = runner;
136
90
  const {
137
91
  distDir,
138
92
  staticGenerate,
139
93
  conf
140
94
  } = this;
141
- (0, _utils2.debug)('final server conf', this.conf); // proxy handler, each proxy has own handler
142
-
95
+ (0, _utils2.debug)('final server conf', this.conf);
96
+ // proxy handler, each proxy has own handler
143
97
  this.proxyHandler = (0, _proxy.createProxyHandler)((_conf$bff = conf.bff) === null || _conf$bff === void 0 ? void 0 : _conf$bff.proxy);
144
-
145
98
  if (this.proxyHandler) {
146
99
  this.proxyHandler.forEach(handler => {
147
100
  this.addHandler(handler);
148
101
  });
149
- } // start file reader
150
-
102
+ }
151
103
 
104
+ // start file reader
152
105
  this.reader.init();
153
106
  app.on('close', () => {
154
107
  this.reader.close();
155
- }); // use preset routes priority
108
+ });
156
109
 
110
+ // use preset routes priority
157
111
  const usageRoutes = this.filterRoutes(this.getRoutes());
158
- this.router.reset(usageRoutes); // warmup ssr bundle in production env
112
+ this.router.reset(usageRoutes);
159
113
 
114
+ // warmup ssr bundle in production env
160
115
  this.warmupSSRBundle();
161
116
  await this.prepareFrameHandler();
162
- await this.prepareBeforeRouteHandler(usageRoutes, distDir); // Only work when without setting `assetPrefix`.
163
- // Setting `assetPrefix` means these resources should be uploaded to CDN.
117
+ await this.prepareBeforeRouteHandler(usageRoutes, distDir);
164
118
 
165
- const staticPathRegExp = (0, _utils2.getStaticReg)(this.conf.output || {});
119
+ // Only work when without setting `assetPrefix`.
120
+ // Setting `assetPrefix` means these resources should be uploaded to CDN.
121
+ const staticPathRegExp = (0, _utils2.getStaticReg)(this.conf.output || {},
122
+ // FIXME:
123
+ this.conf.html);
166
124
  this.staticFileHandler = (0, _serveFile.createStaticFileHandler)([{
167
125
  path: staticPathRegExp,
168
126
  target: distDir
@@ -172,34 +130,33 @@ class ModernServer {
172
130
  staticGenerate
173
131
  });
174
132
  await this.setupBeforeProdMiddleware();
175
- this.addHandler(this.staticFileHandler); // execute after staticFileHandler, can rename to staticFallbackHandler if needed.
133
+ this.addHandler(this.staticFileHandler);
176
134
 
135
+ // execute after staticFileHandler, can rename to staticFallbackHandler if needed.
177
136
  this.addHandler(_serveFile.faviconFallbackHandler);
178
137
  this.addBeforeRouteHandler();
179
- this.addHandler(this.routeHandler.bind(this)); // compose middlewares to http handler
138
+ this.addHandler(this.routeHandler.bind(this));
180
139
 
140
+ // compose middlewares to http handler
181
141
  this.compose();
182
- } // server ready
183
-
184
-
185
- onRepack(_) {// empty
186
142
  }
187
143
 
144
+ // server ready
145
+ onRepack(_) {
146
+ // empty
147
+ }
188
148
  addBeforeRouteHandler() {
189
149
  this.addHandler(async (context, next) => {
190
150
  if (this.beforeRouteHandler) {
191
151
  await this.beforeRouteHandler(context);
192
-
193
152
  if (this.isSend(context.res)) {
194
153
  return;
195
154
  }
196
- } // eslint-disable-next-line consistent-return
197
-
198
-
155
+ }
156
+ // eslint-disable-next-line consistent-return
199
157
  return next();
200
158
  });
201
159
  }
202
-
203
160
  onServerChange({
204
161
  filepath
205
162
  }) {
@@ -210,85 +167,71 @@ class ModernServer {
210
167
  api,
211
168
  server
212
169
  } = _constants.AGGRED_DIR;
213
-
214
170
  const apiPath = _path.default.normalize(_path.default.join(pwd, api));
215
-
216
171
  const serverPath = _path.default.normalize(_path.default.join(pwd, server));
217
-
218
172
  const onlyApi = filepath.startsWith(apiPath);
219
173
  const onlyWeb = filepath.startsWith(serverPath);
220
174
  this.prepareFrameHandler({
221
175
  onlyWeb,
222
176
  onlyApi
223
177
  });
224
- } // exposed requestHandler
225
-
178
+ }
226
179
 
180
+ // exposed requestHandler
227
181
  getRequestHandler() {
228
182
  return this.requestHandler.bind(this);
229
183
  }
230
-
231
184
  async render(req, res, url) {
232
185
  req.logger = this.logger;
233
186
  req.metrics = this.metrics;
234
187
  const context = (0, _context.createContext)(req, res);
235
188
  const matched = this.router.match(url || context.path);
236
-
237
189
  if (!matched) {
238
190
  return null;
239
191
  }
240
-
241
192
  const route = matched.generate(context.url);
242
193
  const result = await this.handleWeb(context, route);
243
-
244
194
  if (!result) {
245
195
  return null;
246
196
  }
247
-
248
197
  return result.content.toString();
249
198
  }
250
-
251
199
  async createHTTPServer(handler) {
252
200
  return (0, _http.createServer)(handler);
253
201
  }
202
+
254
203
  /* —————————————————————— function will be overwrite —————————————————————— */
255
204
  // get routes info
256
-
257
-
258
205
  getRoutes() {
259
206
  // Preferred to use preset routes
260
207
  if (this.presetRoutes) {
261
208
  return this.presetRoutes;
262
- } // read routes from spec file
263
-
209
+ }
264
210
 
211
+ // read routes from spec file
265
212
  const file = _path.default.join(this.distDir, _utils.ROUTE_SPEC_FILE);
266
-
267
213
  if (_utils.fs.existsSync(file)) {
268
214
  const content = _utils.fs.readJSONSync(file);
269
-
270
215
  return content.routes;
271
216
  }
272
-
273
217
  return [];
274
- } // add promisify request handler to server
275
- // handler should do not do more things after invoke next
276
-
218
+ }
277
219
 
220
+ // add promisify request handler to server
221
+ // handler should do not do more things after invoke next
278
222
  addHandler(handler) {
279
223
  if (handler[Symbol.toStringTag] === 'AsyncFunction') {
280
224
  this.handlers.push(handler);
281
225
  } else {
282
226
  this.handlers.push(_util.default.promisify(handler));
283
227
  }
284
- } // return 404 page
285
-
228
+ }
286
229
 
230
+ // return 404 page
287
231
  render404(context) {
288
232
  context.error(_constants.ERROR_DIGEST.ENOTF, '404 Not Found');
289
233
  this.renderErrorPage(context, 404);
290
234
  }
291
-
292
235
  async prepareBeforeRouteHandler(specs, distDir) {
293
236
  const {
294
237
  runner
@@ -300,9 +243,9 @@ class ModernServer {
300
243
  onLast: () => null
301
244
  });
302
245
  this.beforeRouteHandler = handler;
303
- } // gather frame extension and get framework handler
304
-
246
+ }
305
247
 
248
+ // gather frame extension and get framework handler
306
249
  async prepareFrameHandler(options) {
307
250
  const {
308
251
  workDir,
@@ -311,36 +254,32 @@ class ModernServer {
311
254
  const {
312
255
  onlyApi,
313
256
  onlyWeb
314
- } = options || {}; // server hook, gather plugin inject
257
+ } = options || {};
315
258
 
259
+ // server hook, gather plugin inject
316
260
  const _createMiddlewareColl = (0, _utils2.createMiddlewareCollecter)(),
317
- {
318
- getMiddlewares
319
- } = _createMiddlewareColl,
320
- collector = _objectWithoutProperties(_createMiddlewareColl, _excluded);
321
-
261
+ {
262
+ getMiddlewares
263
+ } = _createMiddlewareColl,
264
+ collector = _objectWithoutProperties(_createMiddlewareColl, _excluded);
322
265
  await runner.gather(collector);
323
266
  const {
324
267
  api: pluginAPIExt,
325
268
  web: pluginWebExt
326
269
  } = getMiddlewares();
327
-
328
270
  const apiDir = _path.default.join(workDir, API_DIR);
271
+ const serverDir = _path.default.join(workDir, SERVER_DIR);
329
272
 
330
- const serverDir = _path.default.join(workDir, SERVER_DIR); // get api or web server handler from server-framework plugin
331
-
332
-
273
+ // get api or web server handler from server-framework plugin
333
274
  if ((await _utils.fs.pathExists(_path.default.join(serverDir))) && !onlyApi) {
334
275
  const webExtension = (0, _utils2.mergeExtension)(pluginWebExt);
335
276
  this.frameWebHandler = await this.prepareWebHandler(webExtension);
336
277
  }
337
-
338
278
  if (_utils.fs.existsSync(apiDir) && !onlyWeb) {
339
279
  const apiExtension = (0, _utils2.mergeExtension)(pluginAPIExt);
340
280
  this.frameAPIHandler = await this.prepareAPIHandler(apiExtension);
341
281
  }
342
282
  }
343
-
344
283
  async prepareWebHandler(extension) {
345
284
  const {
346
285
  workDir,
@@ -354,7 +293,6 @@ class ModernServer {
354
293
  });
355
294
  return handler;
356
295
  }
357
-
358
296
  async prepareAPIHandler(extension) {
359
297
  const {
360
298
  workDir,
@@ -373,11 +311,9 @@ class ModernServer {
373
311
  onLast: () => null
374
312
  });
375
313
  }
376
-
377
314
  filterRoutes(routes) {
378
315
  return routes;
379
316
  }
380
-
381
317
  async setupBeforeProdMiddleware() {
382
318
  const {
383
319
  conf,
@@ -388,20 +324,16 @@ class ModernServer {
388
324
  this.addHandler(mid);
389
325
  });
390
326
  }
391
-
392
327
  async handleAPI(context) {
393
328
  const {
394
329
  req,
395
330
  res
396
331
  } = context;
397
-
398
332
  if (!this.frameAPIHandler) {
399
333
  throw new Error('can not found api handler');
400
334
  }
401
-
402
335
  await this.frameAPIHandler(req, res);
403
336
  }
404
-
405
337
  async handleWeb(context, route) {
406
338
  return this.routeRenderHandler({
407
339
  ctx: context,
@@ -409,232 +341,198 @@ class ModernServer {
409
341
  runner: this.runner
410
342
  });
411
343
  }
412
-
413
344
  async proxy() {
414
345
  return null;
415
- } // warmup ssr function
416
-
346
+ }
417
347
 
348
+ // warmup ssr function
418
349
  warmupSSRBundle() {
419
350
  const {
420
351
  distDir
421
352
  } = this;
422
353
  const bundles = this.router.getBundles();
423
354
  bundles.forEach(bundle => {
424
- const filepath = _path.default.join(distDir, bundle); // if error, just throw and let process die
425
-
426
-
355
+ const filepath = _path.default.join(distDir, bundle);
356
+ // if error, just throw and let process die
427
357
  require(filepath);
428
358
  });
429
359
  }
430
-
431
360
  createContext(req, res, options = {}) {
432
361
  return (0, _context.createContext)(req, res, options);
433
362
  }
363
+
434
364
  /* —————————————————————— private function —————————————————————— */
435
365
  // handler route.json, include api / csr / ssr
436
-
437
-
438
366
  async routeHandler(context) {
439
367
  const {
440
368
  res
441
- } = context; // match routes in the route spec
369
+ } = context;
442
370
 
371
+ // match routes in the route spec
443
372
  const matched = this.router.match(context.path);
444
-
445
373
  if (!matched) {
446
374
  this.render404(context);
447
375
  return;
448
- } // route is api service
449
-
376
+ }
450
377
 
378
+ // route is api service
451
379
  let route = matched.generate(context.url);
452
-
453
380
  if (route.isApi) {
454
381
  await this.handleAPI(context);
455
382
  return;
456
383
  }
384
+ const afterMatchContext = (0, _hookApi.createAfterMatchContext)(context, route.entryName);
457
385
 
458
- const afterMatchContext = (0, _hookApi.createAfterMatchContext)(context, route.entryName); // only full mode run server hook
459
-
386
+ // only full mode run server hook
460
387
  if (this.runMode === _constants.RUN_MODE.FULL) {
461
388
  await this.runner.afterMatch(afterMatchContext, {
462
389
  onLast: _utils2.noop
463
390
  });
464
391
  }
465
-
466
392
  if (this.isSend(res)) {
467
393
  return;
468
394
  }
469
-
470
395
  const {
471
396
  current,
472
397
  url,
473
398
  status
474
- } = afterMatchContext.router; // redirect to another url
475
-
399
+ } = afterMatchContext.router;
400
+ // redirect to another url
476
401
  if (url) {
477
402
  this.redirect(res, url, status);
478
403
  return;
479
- } // rewrite to another entry
480
-
404
+ }
481
405
 
406
+ // rewrite to another entry
482
407
  if (route.entryName !== current) {
483
408
  const matched = this.router.matchEntry(current);
484
-
485
409
  if (!matched) {
486
410
  this.render404(context);
487
411
  return;
488
412
  }
489
-
490
413
  route = matched.generate(context.url);
491
414
  }
492
-
493
415
  context.setParams(route.params);
494
416
  context.setServerData('router', {
495
417
  baseUrl: route.urlPath,
496
418
  params: route.params
497
419
  });
498
-
499
420
  if (this.frameWebHandler) {
500
421
  res.locals = res.locals || {};
501
422
  const middlewareContext = (0, _hookApi.createMiddlewareContext)(context);
502
423
  await this.frameWebHandler(middlewareContext);
503
424
  res.locals = _objectSpread(_objectSpread({}, res.locals), middlewareContext.response.locals);
504
- } // frameWebHandler has process request
505
-
425
+ }
506
426
 
427
+ // frameWebHandler has process request
507
428
  if (this.isSend(res)) {
508
429
  return;
509
430
  }
510
-
511
431
  if (route.responseHeaders) {
512
432
  Object.keys(route.responseHeaders).forEach(key => {
513
433
  const value = route.responseHeaders[key];
514
-
515
434
  if (value) {
516
435
  context.res.setHeader(key, value);
517
436
  }
518
437
  });
519
438
  }
520
-
521
439
  const renderResult = await this.handleWeb(context, route);
522
-
523
440
  if (!renderResult) {
524
441
  this.render404(context);
525
442
  return;
526
- } // React Router navigation
527
-
443
+ }
528
444
 
445
+ // React Router navigation
529
446
  if (renderResult.redirect) {
530
447
  this.redirect(res, renderResult.content, renderResult.statusCode);
531
448
  return;
532
449
  }
533
-
534
450
  if (this.isSend(res)) {
535
451
  return;
536
452
  }
537
-
538
453
  res.setHeader('content-type', renderResult.contentType);
539
454
  const {
540
455
  contentStream
541
456
  } = renderResult;
542
-
543
457
  if (contentStream) {
544
458
  contentStream.pipe((0, _template.templateInjectableStream)({
545
459
  prependHead: route.entryName ? `<script>window._SERVER_DATA=${JSON.stringify(context.serverData)}</script>` : undefined
546
460
  })).pipe(res);
547
461
  return;
548
462
  }
549
-
550
463
  let response = renderResult.content;
551
-
552
464
  if (route.entryName) {
553
- const afterRenderContext = (0, _hookApi.createAfterRenderContext)(context, response.toString()); // only full mode run server hook
554
- // FIXME: how to run server hook in streaming
465
+ const afterRenderContext = (0, _hookApi.createAfterRenderContext)(context, response.toString());
555
466
 
467
+ // only full mode run server hook
468
+ // FIXME: how to run server hook in streaming
556
469
  if (this.runMode === _constants.RUN_MODE.FULL) {
557
470
  await this.runner.afterRender(afterRenderContext, {
558
471
  onLast: _utils2.noop
559
472
  });
560
473
  }
561
-
562
474
  if (this.isSend(res)) {
563
475
  return;
564
- } // It will inject _SERVER_DATA twice, when SSG mode.
476
+ }
477
+
478
+ // It will inject _SERVER_DATA twice, when SSG mode.
565
479
  // The first time was in ssg html created, the seoncd time was in prod-server start.
566
480
  // but the second wound causes route error.
567
481
  // To ensure that the second injection fails, the _SERVER_DATA inject at the front of head,
568
-
569
-
570
482
  afterRenderContext.template.prependHead(`<script>window._SERVER_DATA=${JSON.stringify(context.serverData)}</script>`);
571
483
  response = afterRenderContext.template.get();
572
484
  }
573
-
574
485
  res.end(response);
575
486
  }
576
-
577
487
  isSend(res) {
578
488
  if (res.headersSent) {
579
489
  return true;
580
490
  }
581
-
582
491
  if (res.getHeader('Location') && (0, _utils2.isRedirect)(res.statusCode)) {
583
492
  res.end();
584
493
  return true;
585
494
  }
586
-
587
495
  return false;
588
- } // compose handlers and create the final handler
589
-
496
+ }
590
497
 
498
+ // compose handlers and create the final handler
591
499
  compose() {
592
500
  const {
593
501
  handlers
594
502
  } = this;
595
-
596
503
  if (!Array.isArray(handlers)) {
597
504
  throw new TypeError('Middleware stack must be an array!');
598
505
  }
599
-
600
506
  for (const fn of handlers) {
601
507
  if (typeof fn !== 'function') {
602
508
  throw new TypeError('Middleware must be composed of functions!');
603
509
  }
604
510
  }
605
-
606
511
  this._handler = (context, next) => {
607
512
  let i = 0;
608
-
609
513
  const dispatch = error => {
610
514
  if (error) {
611
515
  return this.onError(context, error);
612
516
  }
613
-
614
517
  const handler = handlers[i++];
615
-
616
518
  if (!handler) {
617
519
  return next();
618
520
  }
619
-
620
521
  return handler(context, dispatch).catch(onError);
621
522
  };
622
-
623
523
  const onError = err => {
624
524
  this.onError(context, err);
625
525
  };
626
-
627
526
  return dispatch();
628
527
  };
629
528
  }
630
-
631
- requestHandler(req, res, next = () => {// empty
529
+ requestHandler(req, res, next = () => {
530
+ // empty
632
531
  }) {
633
532
  res.statusCode = 200;
634
533
  req.logger = this.logger;
635
534
  req.metrics = this.metrics;
636
535
  let context;
637
-
638
536
  try {
639
537
  context = this.createContext(req, res);
640
538
  } catch (e) {
@@ -643,25 +541,21 @@ class ModernServer {
643
541
  res.setHeader('content-type', _utils.mime.contentType('html'));
644
542
  return res.end((0, _utils2.createErrorDocument)(500, _constants.ERROR_PAGE_TEXT[500]));
645
543
  }
646
-
647
544
  try {
648
545
  return this._handler(context, next);
649
546
  } catch (err) {
650
547
  return this.onError(context, err);
651
548
  }
652
549
  }
653
-
654
550
  redirect(res, url, status = 302) {
655
551
  res.setHeader('Location', url);
656
552
  res.statusCode = status;
657
553
  res.end();
658
554
  }
659
-
660
555
  onError(context, err) {
661
556
  context.error(_constants.ERROR_DIGEST.EINTER, err);
662
557
  this.renderErrorPage(context, 500);
663
558
  }
664
-
665
559
  async renderErrorPage(context, status) {
666
560
  const {
667
561
  res
@@ -670,14 +564,15 @@ class ModernServer {
670
564
  res.setHeader('content-type', _utils.mime.contentType('html'));
671
565
  const statusPage = `/${status}`;
672
566
  const customErrorPage = `/_error`;
673
- const matched = this.router.match(statusPage) || this.router.match(customErrorPage); // if no custom status page find
567
+ const matched = this.router.match(statusPage) || this.router.match(customErrorPage);
568
+ // if no custom status page find
674
569
 
675
570
  if (matched) {
676
571
  const route = matched.generate(context.url);
677
572
  const {
678
573
  entryName
679
- } = route; // check entryName, avoid matched '/' route
680
-
574
+ } = route;
575
+ // check entryName, avoid matched '/' route
681
576
  if (entryName === status.toString() || entryName === '_error') {
682
577
  try {
683
578
  const file = await this.routeRenderHandler({
@@ -685,22 +580,18 @@ class ModernServer {
685
580
  ctx: context,
686
581
  runner: this.runner
687
582
  });
688
-
689
583
  if (file) {
690
584
  context.res.end(file.content);
691
585
  return;
692
586
  }
693
- } catch (e) {// just catch error when the rendering error occurred in the custom error page.
587
+ } catch (e) {
588
+ // just catch error when the rendering error occurred in the custom error page.
694
589
  }
695
590
  }
696
591
  }
697
-
698
592
  const text = _constants.ERROR_PAGE_TEXT[status] || _constants.ERROR_PAGE_TEXT[500];
699
593
  context.res.end((0, _utils2.createErrorDocument)(status, text));
700
594
  }
701
-
702
595
  }
703
596
  /* eslint-enable max-lines */
704
-
705
-
706
597
  exports.ModernServer = ModernServer;