@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
@@ -0,0 +1,946 @@
1
+ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
2
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
3
+ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
4
+ import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
5
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
6
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
7
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
8
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
9
+ var _excluded = ["getMiddlewares"];
10
+ /* eslint-disable max-lines */
11
+ import { createServer } from 'http';
12
+ import util from 'util';
13
+ import path from 'path';
14
+ import { fs, mime, ROUTE_SPEC_FILE } from '@modern-js/utils';
15
+ import { RouteMatchManager } from "../libs/route";
16
+ import { createRenderHandler } from "../libs/render";
17
+ import { createStaticFileHandler, faviconFallbackHandler } from "../libs/serve-file";
18
+ import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect } from "../utils";
19
+ import * as reader from "../libs/render/reader";
20
+ import { createProxyHandler } from "../libs/proxy";
21
+ import { createContext as _createContext } from "../libs/context";
22
+ import { templateInjectableStream } from "../libs/hook-api/template";
23
+ import { AGGRED_DIR, ERROR_DIGEST, ERROR_PAGE_TEXT, RUN_MODE } from "../constants";
24
+ import { createAfterMatchContext, createAfterRenderContext, createMiddlewareContext } from "../libs/hook-api";
25
+ var API_DIR = './api';
26
+ var SERVER_DIR = './server';
27
+ export var ModernServer = /*#__PURE__*/function () {
28
+ // appDirectory
29
+
30
+ // product dist dir
31
+
32
+ // work on src or dist
33
+
34
+ function ModernServer(_ref) {
35
+ var pwd = _ref.pwd,
36
+ config = _ref.config,
37
+ routes = _ref.routes,
38
+ staticGenerate = _ref.staticGenerate,
39
+ logger = _ref.logger,
40
+ metrics = _ref.metrics,
41
+ runMode = _ref.runMode,
42
+ proxyTarget = _ref.proxyTarget;
43
+ _classCallCheck(this, ModernServer);
44
+ _defineProperty(this, "pwd", void 0);
45
+ _defineProperty(this, "distDir", void 0);
46
+ _defineProperty(this, "workDir", void 0);
47
+ _defineProperty(this, "router", void 0);
48
+ _defineProperty(this, "conf", void 0);
49
+ _defineProperty(this, "handlers", []);
50
+ _defineProperty(this, "presetRoutes", void 0);
51
+ _defineProperty(this, "runner", void 0);
52
+ _defineProperty(this, "logger", void 0);
53
+ _defineProperty(this, "metrics", void 0);
54
+ _defineProperty(this, "runMode", void 0);
55
+ _defineProperty(this, "reader", reader);
56
+ _defineProperty(this, "proxyTarget", void 0);
57
+ _defineProperty(this, "staticFileHandler", void 0);
58
+ _defineProperty(this, "routeRenderHandler", void 0);
59
+ _defineProperty(this, "beforeRouteHandler", null);
60
+ _defineProperty(this, "frameWebHandler", null);
61
+ _defineProperty(this, "frameAPIHandler", null);
62
+ _defineProperty(this, "proxyHandler", null);
63
+ _defineProperty(this, "_handler", void 0);
64
+ _defineProperty(this, "staticGenerate", void 0);
65
+ require('ignore-styles');
66
+ this.pwd = pwd;
67
+ this.distDir = path.join(pwd, config.output.path || 'dist');
68
+ this.workDir = this.distDir;
69
+ this.conf = config;
70
+ debug('server conf', this.conf);
71
+ this.logger = logger;
72
+ this.metrics = metrics;
73
+ this.router = new RouteMatchManager();
74
+ this.presetRoutes = routes;
75
+ this.proxyTarget = proxyTarget;
76
+ this.staticGenerate = staticGenerate || false;
77
+ this.runMode = runMode || RUN_MODE.FULL;
78
+ // process.env.BUILD_TYPE = `${this.staticGenerate ? 'ssg' : 'ssr'}`;
79
+ }
80
+
81
+ // server prepare
82
+ _createClass(ModernServer, [{
83
+ key: "onInit",
84
+ value: function () {
85
+ var _onInit = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(runner, app) {
86
+ var _conf$bff,
87
+ _this = this;
88
+ var distDir, staticGenerate, conf, usageRoutes, staticPathRegExp;
89
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
90
+ while (1) {
91
+ switch (_context.prev = _context.next) {
92
+ case 0:
93
+ this.runner = runner;
94
+ distDir = this.distDir, staticGenerate = this.staticGenerate, conf = this.conf;
95
+ debug('final server conf', this.conf);
96
+ // proxy handler, each proxy has own handler
97
+ this.proxyHandler = createProxyHandler((_conf$bff = conf.bff) === null || _conf$bff === void 0 ? void 0 : _conf$bff.proxy);
98
+ if (this.proxyHandler) {
99
+ this.proxyHandler.forEach(function (handler) {
100
+ _this.addHandler(handler);
101
+ });
102
+ }
103
+
104
+ // start file reader
105
+ this.reader.init();
106
+ app.on('close', function () {
107
+ _this.reader.close();
108
+ });
109
+
110
+ // use preset routes priority
111
+ usageRoutes = this.filterRoutes(this.getRoutes());
112
+ this.router.reset(usageRoutes);
113
+
114
+ // warmup ssr bundle in production env
115
+ this.warmupSSRBundle();
116
+ _context.next = 12;
117
+ return this.prepareFrameHandler();
118
+ case 12:
119
+ _context.next = 14;
120
+ return this.prepareBeforeRouteHandler(usageRoutes, distDir);
121
+ case 14:
122
+ // Only work when without setting `assetPrefix`.
123
+ // Setting `assetPrefix` means these resources should be uploaded to CDN.
124
+ staticPathRegExp = getStaticReg(this.conf.output || {},
125
+ // FIXME:
126
+ this.conf.html);
127
+ this.staticFileHandler = createStaticFileHandler([{
128
+ path: staticPathRegExp,
129
+ target: distDir
130
+ }], this.conf.output);
131
+ this.routeRenderHandler = createRenderHandler({
132
+ distDir: distDir,
133
+ staticGenerate: staticGenerate
134
+ });
135
+ _context.next = 19;
136
+ return this.setupBeforeProdMiddleware();
137
+ case 19:
138
+ this.addHandler(this.staticFileHandler);
139
+
140
+ // execute after staticFileHandler, can rename to staticFallbackHandler if needed.
141
+ this.addHandler(faviconFallbackHandler);
142
+ this.addBeforeRouteHandler();
143
+ this.addHandler(this.routeHandler.bind(this));
144
+
145
+ // compose middlewares to http handler
146
+ this.compose();
147
+ case 24:
148
+ case "end":
149
+ return _context.stop();
150
+ }
151
+ }
152
+ }, _callee, this);
153
+ }));
154
+ function onInit(_x, _x2) {
155
+ return _onInit.apply(this, arguments);
156
+ }
157
+ return onInit;
158
+ }() // server ready
159
+ }, {
160
+ key: "onRepack",
161
+ value: function onRepack(_) {
162
+ // empty
163
+ }
164
+ }, {
165
+ key: "addBeforeRouteHandler",
166
+ value: function addBeforeRouteHandler() {
167
+ var _this2 = this;
168
+ this.addHandler( /*#__PURE__*/function () {
169
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(context, next) {
170
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
171
+ while (1) {
172
+ switch (_context2.prev = _context2.next) {
173
+ case 0:
174
+ if (!_this2.beforeRouteHandler) {
175
+ _context2.next = 5;
176
+ break;
177
+ }
178
+ _context2.next = 3;
179
+ return _this2.beforeRouteHandler(context);
180
+ case 3:
181
+ if (!_this2.isSend(context.res)) {
182
+ _context2.next = 5;
183
+ break;
184
+ }
185
+ return _context2.abrupt("return");
186
+ case 5:
187
+ return _context2.abrupt("return", next());
188
+ case 6:
189
+ case "end":
190
+ return _context2.stop();
191
+ }
192
+ }
193
+ }, _callee2);
194
+ }));
195
+ return function (_x3, _x4) {
196
+ return _ref2.apply(this, arguments);
197
+ };
198
+ }());
199
+ }
200
+ }, {
201
+ key: "onServerChange",
202
+ value: function onServerChange(_ref3) {
203
+ var filepath = _ref3.filepath;
204
+ var pwd = this.pwd;
205
+ var api = AGGRED_DIR.api,
206
+ server = AGGRED_DIR.server;
207
+ var apiPath = path.normalize(path.join(pwd, api));
208
+ var serverPath = path.normalize(path.join(pwd, server));
209
+ var onlyApi = filepath.startsWith(apiPath);
210
+ var onlyWeb = filepath.startsWith(serverPath);
211
+ this.prepareFrameHandler({
212
+ onlyWeb: onlyWeb,
213
+ onlyApi: onlyApi
214
+ });
215
+ }
216
+
217
+ // exposed requestHandler
218
+ }, {
219
+ key: "getRequestHandler",
220
+ value: function getRequestHandler() {
221
+ return this.requestHandler.bind(this);
222
+ }
223
+ }, {
224
+ key: "render",
225
+ value: function () {
226
+ var _render = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(req, res, url) {
227
+ var context, matched, route, result;
228
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
229
+ while (1) {
230
+ switch (_context3.prev = _context3.next) {
231
+ case 0:
232
+ req.logger = this.logger;
233
+ req.metrics = this.metrics;
234
+ context = _createContext(req, res);
235
+ matched = this.router.match(url || context.path);
236
+ if (matched) {
237
+ _context3.next = 6;
238
+ break;
239
+ }
240
+ return _context3.abrupt("return", null);
241
+ case 6:
242
+ route = matched.generate(context.url);
243
+ _context3.next = 9;
244
+ return this.handleWeb(context, route);
245
+ case 9:
246
+ result = _context3.sent;
247
+ if (result) {
248
+ _context3.next = 12;
249
+ break;
250
+ }
251
+ return _context3.abrupt("return", null);
252
+ case 12:
253
+ return _context3.abrupt("return", result.content.toString());
254
+ case 13:
255
+ case "end":
256
+ return _context3.stop();
257
+ }
258
+ }
259
+ }, _callee3, this);
260
+ }));
261
+ function render(_x5, _x6, _x7) {
262
+ return _render.apply(this, arguments);
263
+ }
264
+ return render;
265
+ }()
266
+ }, {
267
+ key: "createHTTPServer",
268
+ value: function () {
269
+ var _createHTTPServer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(handler) {
270
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
271
+ while (1) {
272
+ switch (_context4.prev = _context4.next) {
273
+ case 0:
274
+ return _context4.abrupt("return", createServer(handler));
275
+ case 1:
276
+ case "end":
277
+ return _context4.stop();
278
+ }
279
+ }
280
+ }, _callee4);
281
+ }));
282
+ function createHTTPServer(_x8) {
283
+ return _createHTTPServer.apply(this, arguments);
284
+ }
285
+ return createHTTPServer;
286
+ }()
287
+ /* —————————————————————— function will be overwrite —————————————————————— */
288
+ // get routes info
289
+ }, {
290
+ key: "getRoutes",
291
+ value: function getRoutes() {
292
+ // Preferred to use preset routes
293
+ if (this.presetRoutes) {
294
+ return this.presetRoutes;
295
+ }
296
+
297
+ // read routes from spec file
298
+ var file = path.join(this.distDir, ROUTE_SPEC_FILE);
299
+ if (fs.existsSync(file)) {
300
+ var content = fs.readJSONSync(file);
301
+ return content.routes;
302
+ }
303
+ return [];
304
+ }
305
+
306
+ // add promisify request handler to server
307
+ // handler should do not do more things after invoke next
308
+ }, {
309
+ key: "addHandler",
310
+ value: function addHandler(handler) {
311
+ if (handler[Symbol.toStringTag] === 'AsyncFunction') {
312
+ this.handlers.push(handler);
313
+ } else {
314
+ this.handlers.push(util.promisify(handler));
315
+ }
316
+ }
317
+
318
+ // return 404 page
319
+ }, {
320
+ key: "render404",
321
+ value: function render404(context) {
322
+ context.error(ERROR_DIGEST.ENOTF, '404 Not Found');
323
+ this.renderErrorPage(context, 404);
324
+ }
325
+ }, {
326
+ key: "prepareBeforeRouteHandler",
327
+ value: function () {
328
+ var _prepareBeforeRouteHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(specs, distDir) {
329
+ var runner, handler;
330
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
331
+ while (1) {
332
+ switch (_context5.prev = _context5.next) {
333
+ case 0:
334
+ runner = this.runner;
335
+ _context5.next = 3;
336
+ return runner.preparebeforeRouteHandler({
337
+ serverRoutes: specs,
338
+ distDir: distDir
339
+ }, {
340
+ onLast: function onLast() {
341
+ return null;
342
+ }
343
+ });
344
+ case 3:
345
+ handler = _context5.sent;
346
+ this.beforeRouteHandler = handler;
347
+ case 5:
348
+ case "end":
349
+ return _context5.stop();
350
+ }
351
+ }
352
+ }, _callee5, this);
353
+ }));
354
+ function prepareBeforeRouteHandler(_x9, _x10) {
355
+ return _prepareBeforeRouteHandler.apply(this, arguments);
356
+ }
357
+ return prepareBeforeRouteHandler;
358
+ }() // gather frame extension and get framework handler
359
+ }, {
360
+ key: "prepareFrameHandler",
361
+ value: function () {
362
+ var _prepareFrameHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(options) {
363
+ var workDir, runner, _ref4, onlyApi, onlyWeb, _createMiddlewareColl, getMiddlewares, collector, _getMiddlewares, pluginAPIExt, pluginWebExt, apiDir, serverDir, webExtension, apiExtension;
364
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
365
+ while (1) {
366
+ switch (_context6.prev = _context6.next) {
367
+ case 0:
368
+ workDir = this.workDir, runner = this.runner;
369
+ _ref4 = options || {}, onlyApi = _ref4.onlyApi, onlyWeb = _ref4.onlyWeb; // server hook, gather plugin inject
370
+ _createMiddlewareColl = createMiddlewareCollecter(), getMiddlewares = _createMiddlewareColl.getMiddlewares, collector = _objectWithoutProperties(_createMiddlewareColl, _excluded);
371
+ _context6.next = 5;
372
+ return runner.gather(collector);
373
+ case 5:
374
+ _getMiddlewares = getMiddlewares(), pluginAPIExt = _getMiddlewares.api, pluginWebExt = _getMiddlewares.web;
375
+ apiDir = path.join(workDir, API_DIR);
376
+ serverDir = path.join(workDir, SERVER_DIR); // get api or web server handler from server-framework plugin
377
+ _context6.next = 10;
378
+ return fs.pathExists(path.join(serverDir));
379
+ case 10:
380
+ _context6.t0 = _context6.sent;
381
+ if (!_context6.t0) {
382
+ _context6.next = 13;
383
+ break;
384
+ }
385
+ _context6.t0 = !onlyApi;
386
+ case 13:
387
+ if (!_context6.t0) {
388
+ _context6.next = 18;
389
+ break;
390
+ }
391
+ webExtension = mergeExtension(pluginWebExt);
392
+ _context6.next = 17;
393
+ return this.prepareWebHandler(webExtension);
394
+ case 17:
395
+ this.frameWebHandler = _context6.sent;
396
+ case 18:
397
+ if (!(fs.existsSync(apiDir) && !onlyWeb)) {
398
+ _context6.next = 23;
399
+ break;
400
+ }
401
+ apiExtension = mergeExtension(pluginAPIExt);
402
+ _context6.next = 22;
403
+ return this.prepareAPIHandler(apiExtension);
404
+ case 22:
405
+ this.frameAPIHandler = _context6.sent;
406
+ case 23:
407
+ case "end":
408
+ return _context6.stop();
409
+ }
410
+ }
411
+ }, _callee6, this);
412
+ }));
413
+ function prepareFrameHandler(_x11) {
414
+ return _prepareFrameHandler.apply(this, arguments);
415
+ }
416
+ return prepareFrameHandler;
417
+ }()
418
+ }, {
419
+ key: "prepareWebHandler",
420
+ value: function () {
421
+ var _prepareWebHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(extension) {
422
+ var workDir, runner, handler;
423
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
424
+ while (1) {
425
+ switch (_context7.prev = _context7.next) {
426
+ case 0:
427
+ workDir = this.workDir, runner = this.runner;
428
+ _context7.next = 3;
429
+ return runner.prepareWebServer({
430
+ pwd: workDir,
431
+ config: extension
432
+ }, {
433
+ onLast: function onLast() {
434
+ return null;
435
+ }
436
+ });
437
+ case 3:
438
+ handler = _context7.sent;
439
+ return _context7.abrupt("return", handler);
440
+ case 5:
441
+ case "end":
442
+ return _context7.stop();
443
+ }
444
+ }
445
+ }, _callee7, this);
446
+ }));
447
+ function prepareWebHandler(_x12) {
448
+ return _prepareWebHandler.apply(this, arguments);
449
+ }
450
+ return prepareWebHandler;
451
+ }()
452
+ }, {
453
+ key: "prepareAPIHandler",
454
+ value: function () {
455
+ var _prepareAPIHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(extension) {
456
+ var workDir, runner, conf, _ref5, bff, prefix;
457
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
458
+ while (1) {
459
+ switch (_context8.prev = _context8.next) {
460
+ case 0:
461
+ workDir = this.workDir, runner = this.runner, conf = this.conf;
462
+ _ref5 = conf, bff = _ref5.bff;
463
+ prefix = (bff === null || bff === void 0 ? void 0 : bff.prefix) || '/api';
464
+ return _context8.abrupt("return", runner.prepareApiServer({
465
+ pwd: workDir,
466
+ config: extension,
467
+ prefix: Array.isArray(prefix) ? prefix[0] : prefix
468
+ }, {
469
+ onLast: function onLast() {
470
+ return null;
471
+ }
472
+ }));
473
+ case 4:
474
+ case "end":
475
+ return _context8.stop();
476
+ }
477
+ }
478
+ }, _callee8, this);
479
+ }));
480
+ function prepareAPIHandler(_x13) {
481
+ return _prepareAPIHandler.apply(this, arguments);
482
+ }
483
+ return prepareAPIHandler;
484
+ }()
485
+ }, {
486
+ key: "filterRoutes",
487
+ value: function filterRoutes(routes) {
488
+ return routes;
489
+ }
490
+ }, {
491
+ key: "setupBeforeProdMiddleware",
492
+ value: function () {
493
+ var _setupBeforeProdMiddleware = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9() {
494
+ var _this3 = this;
495
+ var conf, runner, preMiddleware;
496
+ return _regeneratorRuntime().wrap(function _callee9$(_context9) {
497
+ while (1) {
498
+ switch (_context9.prev = _context9.next) {
499
+ case 0:
500
+ conf = this.conf, runner = this.runner;
501
+ _context9.next = 3;
502
+ return runner.beforeProdServer(conf);
503
+ case 3:
504
+ preMiddleware = _context9.sent;
505
+ preMiddleware.flat().forEach(function (mid) {
506
+ _this3.addHandler(mid);
507
+ });
508
+ case 5:
509
+ case "end":
510
+ return _context9.stop();
511
+ }
512
+ }
513
+ }, _callee9, this);
514
+ }));
515
+ function setupBeforeProdMiddleware() {
516
+ return _setupBeforeProdMiddleware.apply(this, arguments);
517
+ }
518
+ return setupBeforeProdMiddleware;
519
+ }()
520
+ }, {
521
+ key: "handleAPI",
522
+ value: function () {
523
+ var _handleAPI = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(context) {
524
+ var req, res;
525
+ return _regeneratorRuntime().wrap(function _callee10$(_context10) {
526
+ while (1) {
527
+ switch (_context10.prev = _context10.next) {
528
+ case 0:
529
+ req = context.req, res = context.res;
530
+ if (this.frameAPIHandler) {
531
+ _context10.next = 3;
532
+ break;
533
+ }
534
+ throw new Error('can not found api handler');
535
+ case 3:
536
+ _context10.next = 5;
537
+ return this.frameAPIHandler(req, res);
538
+ case 5:
539
+ case "end":
540
+ return _context10.stop();
541
+ }
542
+ }
543
+ }, _callee10, this);
544
+ }));
545
+ function handleAPI(_x14) {
546
+ return _handleAPI.apply(this, arguments);
547
+ }
548
+ return handleAPI;
549
+ }()
550
+ }, {
551
+ key: "handleWeb",
552
+ value: function () {
553
+ var _handleWeb = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(context, route) {
554
+ return _regeneratorRuntime().wrap(function _callee11$(_context11) {
555
+ while (1) {
556
+ switch (_context11.prev = _context11.next) {
557
+ case 0:
558
+ return _context11.abrupt("return", this.routeRenderHandler({
559
+ ctx: context,
560
+ route: route,
561
+ runner: this.runner
562
+ }));
563
+ case 1:
564
+ case "end":
565
+ return _context11.stop();
566
+ }
567
+ }
568
+ }, _callee11, this);
569
+ }));
570
+ function handleWeb(_x15, _x16) {
571
+ return _handleWeb.apply(this, arguments);
572
+ }
573
+ return handleWeb;
574
+ }()
575
+ }, {
576
+ key: "proxy",
577
+ value: function () {
578
+ var _proxy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12() {
579
+ return _regeneratorRuntime().wrap(function _callee12$(_context12) {
580
+ while (1) {
581
+ switch (_context12.prev = _context12.next) {
582
+ case 0:
583
+ return _context12.abrupt("return", null);
584
+ case 1:
585
+ case "end":
586
+ return _context12.stop();
587
+ }
588
+ }
589
+ }, _callee12);
590
+ }));
591
+ function proxy() {
592
+ return _proxy.apply(this, arguments);
593
+ }
594
+ return proxy;
595
+ }() // warmup ssr function
596
+ }, {
597
+ key: "warmupSSRBundle",
598
+ value: function warmupSSRBundle() {
599
+ var distDir = this.distDir;
600
+ var bundles = this.router.getBundles();
601
+ bundles.forEach(function (bundle) {
602
+ var filepath = path.join(distDir, bundle);
603
+ // if error, just throw and let process die
604
+ require(filepath);
605
+ });
606
+ }
607
+ }, {
608
+ key: "createContext",
609
+ value: function createContext(req, res) {
610
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
611
+ return _createContext(req, res, options);
612
+ }
613
+
614
+ /* —————————————————————— private function —————————————————————— */
615
+ // handler route.json, include api / csr / ssr
616
+ }, {
617
+ key: "routeHandler",
618
+ value: function () {
619
+ var _routeHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee13(context) {
620
+ var res, matched, route, afterMatchContext, _afterMatchContext$ro, current, url, status, _matched, middlewareContext, renderResult, contentStream, response, afterRenderContext;
621
+ return _regeneratorRuntime().wrap(function _callee13$(_context13) {
622
+ while (1) {
623
+ switch (_context13.prev = _context13.next) {
624
+ case 0:
625
+ res = context.res; // match routes in the route spec
626
+ matched = this.router.match(context.path);
627
+ if (matched) {
628
+ _context13.next = 5;
629
+ break;
630
+ }
631
+ this.render404(context);
632
+ return _context13.abrupt("return");
633
+ case 5:
634
+ // route is api service
635
+ route = matched.generate(context.url);
636
+ if (!route.isApi) {
637
+ _context13.next = 10;
638
+ break;
639
+ }
640
+ _context13.next = 9;
641
+ return this.handleAPI(context);
642
+ case 9:
643
+ return _context13.abrupt("return");
644
+ case 10:
645
+ afterMatchContext = createAfterMatchContext(context, route.entryName); // only full mode run server hook
646
+ if (!(this.runMode === RUN_MODE.FULL)) {
647
+ _context13.next = 14;
648
+ break;
649
+ }
650
+ _context13.next = 14;
651
+ return this.runner.afterMatch(afterMatchContext, {
652
+ onLast: noop
653
+ });
654
+ case 14:
655
+ if (!this.isSend(res)) {
656
+ _context13.next = 16;
657
+ break;
658
+ }
659
+ return _context13.abrupt("return");
660
+ case 16:
661
+ _afterMatchContext$ro = afterMatchContext.router, current = _afterMatchContext$ro.current, url = _afterMatchContext$ro.url, status = _afterMatchContext$ro.status; // redirect to another url
662
+ if (!url) {
663
+ _context13.next = 20;
664
+ break;
665
+ }
666
+ this.redirect(res, url, status);
667
+ return _context13.abrupt("return");
668
+ case 20:
669
+ if (!(route.entryName !== current)) {
670
+ _context13.next = 26;
671
+ break;
672
+ }
673
+ _matched = this.router.matchEntry(current);
674
+ if (_matched) {
675
+ _context13.next = 25;
676
+ break;
677
+ }
678
+ this.render404(context);
679
+ return _context13.abrupt("return");
680
+ case 25:
681
+ route = _matched.generate(context.url);
682
+ case 26:
683
+ context.setParams(route.params);
684
+ context.setServerData('router', {
685
+ baseUrl: route.urlPath,
686
+ params: route.params
687
+ });
688
+ if (!this.frameWebHandler) {
689
+ _context13.next = 34;
690
+ break;
691
+ }
692
+ res.locals = res.locals || {};
693
+ middlewareContext = createMiddlewareContext(context);
694
+ _context13.next = 33;
695
+ return this.frameWebHandler(middlewareContext);
696
+ case 33:
697
+ res.locals = _objectSpread(_objectSpread({}, res.locals), middlewareContext.response.locals);
698
+ case 34:
699
+ if (!this.isSend(res)) {
700
+ _context13.next = 36;
701
+ break;
702
+ }
703
+ return _context13.abrupt("return");
704
+ case 36:
705
+ if (route.responseHeaders) {
706
+ Object.keys(route.responseHeaders).forEach(function (key) {
707
+ var value = route.responseHeaders[key];
708
+ if (value) {
709
+ context.res.setHeader(key, value);
710
+ }
711
+ });
712
+ }
713
+ _context13.next = 39;
714
+ return this.handleWeb(context, route);
715
+ case 39:
716
+ renderResult = _context13.sent;
717
+ if (renderResult) {
718
+ _context13.next = 43;
719
+ break;
720
+ }
721
+ this.render404(context);
722
+ return _context13.abrupt("return");
723
+ case 43:
724
+ if (!renderResult.redirect) {
725
+ _context13.next = 46;
726
+ break;
727
+ }
728
+ this.redirect(res, renderResult.content, renderResult.statusCode);
729
+ return _context13.abrupt("return");
730
+ case 46:
731
+ if (!this.isSend(res)) {
732
+ _context13.next = 48;
733
+ break;
734
+ }
735
+ return _context13.abrupt("return");
736
+ case 48:
737
+ res.setHeader('content-type', renderResult.contentType);
738
+ contentStream = renderResult.contentStream;
739
+ if (!contentStream) {
740
+ _context13.next = 53;
741
+ break;
742
+ }
743
+ contentStream.pipe(templateInjectableStream({
744
+ prependHead: route.entryName ? "<script>window._SERVER_DATA=".concat(JSON.stringify(context.serverData), "</script>") : undefined
745
+ })).pipe(res);
746
+ return _context13.abrupt("return");
747
+ case 53:
748
+ response = renderResult.content;
749
+ if (!route.entryName) {
750
+ _context13.next = 63;
751
+ break;
752
+ }
753
+ afterRenderContext = createAfterRenderContext(context, response.toString()); // only full mode run server hook
754
+ // FIXME: how to run server hook in streaming
755
+ if (!(this.runMode === RUN_MODE.FULL)) {
756
+ _context13.next = 59;
757
+ break;
758
+ }
759
+ _context13.next = 59;
760
+ return this.runner.afterRender(afterRenderContext, {
761
+ onLast: noop
762
+ });
763
+ case 59:
764
+ if (!this.isSend(res)) {
765
+ _context13.next = 61;
766
+ break;
767
+ }
768
+ return _context13.abrupt("return");
769
+ case 61:
770
+ // It will inject _SERVER_DATA twice, when SSG mode.
771
+ // The first time was in ssg html created, the seoncd time was in prod-server start.
772
+ // but the second wound causes route error.
773
+ // To ensure that the second injection fails, the _SERVER_DATA inject at the front of head,
774
+ afterRenderContext.template.prependHead("<script>window._SERVER_DATA=".concat(JSON.stringify(context.serverData), "</script>"));
775
+ response = afterRenderContext.template.get();
776
+ case 63:
777
+ res.end(response);
778
+ case 64:
779
+ case "end":
780
+ return _context13.stop();
781
+ }
782
+ }
783
+ }, _callee13, this);
784
+ }));
785
+ function routeHandler(_x17) {
786
+ return _routeHandler.apply(this, arguments);
787
+ }
788
+ return routeHandler;
789
+ }()
790
+ }, {
791
+ key: "isSend",
792
+ value: function isSend(res) {
793
+ if (res.headersSent) {
794
+ return true;
795
+ }
796
+ if (res.getHeader('Location') && isRedirect(res.statusCode)) {
797
+ res.end();
798
+ return true;
799
+ }
800
+ return false;
801
+ }
802
+
803
+ // compose handlers and create the final handler
804
+ }, {
805
+ key: "compose",
806
+ value: function compose() {
807
+ var _this4 = this;
808
+ var handlers = this.handlers;
809
+ if (!Array.isArray(handlers)) {
810
+ throw new TypeError('Middleware stack must be an array!');
811
+ }
812
+ var _iterator = _createForOfIteratorHelper(handlers),
813
+ _step;
814
+ try {
815
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
816
+ var fn = _step.value;
817
+ if (typeof fn !== 'function') {
818
+ throw new TypeError('Middleware must be composed of functions!');
819
+ }
820
+ }
821
+ } catch (err) {
822
+ _iterator.e(err);
823
+ } finally {
824
+ _iterator.f();
825
+ }
826
+ this._handler = function (context, next) {
827
+ var i = 0;
828
+ var dispatch = function dispatch(error) {
829
+ if (error) {
830
+ return _this4.onError(context, error);
831
+ }
832
+ var handler = handlers[i++];
833
+ if (!handler) {
834
+ return next();
835
+ }
836
+ return handler(context, dispatch)["catch"](onError);
837
+ };
838
+ var onError = function onError(err) {
839
+ _this4.onError(context, err);
840
+ };
841
+ return dispatch();
842
+ };
843
+ }
844
+ }, {
845
+ key: "requestHandler",
846
+ value: function requestHandler(req, res) {
847
+ var next = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {
848
+ // empty
849
+ };
850
+ res.statusCode = 200;
851
+ req.logger = this.logger;
852
+ req.metrics = this.metrics;
853
+ var context;
854
+ try {
855
+ context = this.createContext(req, res);
856
+ } catch (e) {
857
+ this.logger.error(e);
858
+ res.statusCode = 500;
859
+ res.setHeader('content-type', mime.contentType('html'));
860
+ return res.end(createErrorDocument(500, ERROR_PAGE_TEXT[500]));
861
+ }
862
+ try {
863
+ return this._handler(context, next);
864
+ } catch (err) {
865
+ return this.onError(context, err);
866
+ }
867
+ }
868
+ }, {
869
+ key: "redirect",
870
+ value: function redirect(res, url) {
871
+ var status = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 302;
872
+ res.setHeader('Location', url);
873
+ res.statusCode = status;
874
+ res.end();
875
+ }
876
+ }, {
877
+ key: "onError",
878
+ value: function onError(context, err) {
879
+ context.error(ERROR_DIGEST.EINTER, err);
880
+ this.renderErrorPage(context, 500);
881
+ }
882
+ }, {
883
+ key: "renderErrorPage",
884
+ value: function () {
885
+ var _renderErrorPage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee14(context, status) {
886
+ var res, statusPage, customErrorPage, matched, route, entryName, file, text;
887
+ return _regeneratorRuntime().wrap(function _callee14$(_context14) {
888
+ while (1) {
889
+ switch (_context14.prev = _context14.next) {
890
+ case 0:
891
+ res = context.res;
892
+ context.status = status;
893
+ res.setHeader('content-type', mime.contentType('html'));
894
+ statusPage = "/".concat(status);
895
+ customErrorPage = "/_error";
896
+ matched = this.router.match(statusPage) || this.router.match(customErrorPage); // if no custom status page find
897
+ if (!matched) {
898
+ _context14.next = 21;
899
+ break;
900
+ }
901
+ route = matched.generate(context.url);
902
+ entryName = route.entryName; // check entryName, avoid matched '/' route
903
+ if (!(entryName === status.toString() || entryName === '_error')) {
904
+ _context14.next = 21;
905
+ break;
906
+ }
907
+ _context14.prev = 10;
908
+ _context14.next = 13;
909
+ return this.routeRenderHandler({
910
+ route: route,
911
+ ctx: context,
912
+ runner: this.runner
913
+ });
914
+ case 13:
915
+ file = _context14.sent;
916
+ if (!file) {
917
+ _context14.next = 17;
918
+ break;
919
+ }
920
+ context.res.end(file.content);
921
+ return _context14.abrupt("return");
922
+ case 17:
923
+ _context14.next = 21;
924
+ break;
925
+ case 19:
926
+ _context14.prev = 19;
927
+ _context14.t0 = _context14["catch"](10);
928
+ case 21:
929
+ text = ERROR_PAGE_TEXT[status] || ERROR_PAGE_TEXT[500];
930
+ context.res.end(createErrorDocument(status, text));
931
+ case 23:
932
+ case "end":
933
+ return _context14.stop();
934
+ }
935
+ }
936
+ }, _callee14, this, [[10, 19]]);
937
+ }));
938
+ function renderErrorPage(_x18, _x19) {
939
+ return _renderErrorPage.apply(this, arguments);
940
+ }
941
+ return renderErrorPage;
942
+ }()
943
+ }]);
944
+ return ModernServer;
945
+ }();
946
+ /* eslint-enable max-lines */