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