@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.
- package/CHANGELOG.md +55 -0
- package/dist/js/modern/constants.js +0 -2
- package/dist/js/modern/index.js +0 -1
- package/dist/js/modern/libs/context/context.js +10 -56
- package/dist/js/modern/libs/hook-api/index.js +0 -31
- package/dist/js/modern/libs/hook-api/route.js +0 -8
- package/dist/js/modern/libs/hook-api/template.js +0 -16
- package/dist/js/modern/libs/loadConfig.js +3 -10
- package/dist/js/modern/libs/metrics.js +6 -6
- package/dist/js/modern/libs/proxy.js +7 -12
- package/dist/js/modern/libs/render/cache/__tests__/cache.fun.test.js +0 -1
- package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +0 -9
- package/dist/js/modern/libs/render/cache/index.js +8 -16
- package/dist/js/modern/libs/render/cache/page-caches/lru.js +0 -10
- package/dist/js/modern/libs/render/cache/spr.js +12 -62
- package/dist/js/modern/libs/render/cache/util.js +0 -6
- package/dist/js/modern/libs/render/index.js +6 -11
- package/dist/js/modern/libs/render/measure.js +1 -11
- package/dist/js/modern/libs/render/modern/index.js +2 -13
- package/dist/js/modern/libs/render/reader.js +13 -24
- package/dist/js/modern/libs/render/ssr.js +5 -6
- package/dist/js/modern/libs/render/static.js +6 -9
- package/dist/js/modern/libs/render/type.js +0 -1
- package/dist/js/modern/libs/route/index.js +8 -19
- package/dist/js/modern/libs/route/matcher.js +21 -29
- package/dist/js/modern/libs/route/route.js +0 -13
- package/dist/js/modern/libs/serve-file.js +5 -6
- package/dist/js/modern/server/index.js +19 -41
- package/dist/js/modern/server/modern-server-split.js +0 -11
- package/dist/js/modern/server/modern-server.js +83 -164
- package/dist/js/modern/utils.js +2 -21
- package/dist/js/modern/worker-server.js +34 -0
- package/dist/js/node/constants.js +0 -2
- package/dist/js/node/index.js +0 -10
- package/dist/js/node/libs/context/context.js +10 -65
- package/dist/js/node/libs/context/index.js +0 -3
- package/dist/js/node/libs/hook-api/index.js +0 -42
- package/dist/js/node/libs/hook-api/route.js +0 -10
- package/dist/js/node/libs/hook-api/template.js +0 -22
- package/dist/js/node/libs/loadConfig.js +3 -22
- package/dist/js/node/libs/metrics.js +6 -6
- package/dist/js/node/libs/proxy.js +7 -17
- package/dist/js/node/libs/render/cache/__tests__/cache.fun.test.js +0 -5
- package/dist/js/node/libs/render/cache/__tests__/cache.test.js +0 -12
- package/dist/js/node/libs/render/cache/index.js +8 -22
- package/dist/js/node/libs/render/cache/page-caches/index.js +0 -2
- package/dist/js/node/libs/render/cache/page-caches/lru.js +0 -14
- package/dist/js/node/libs/render/cache/spr.js +12 -71
- package/dist/js/node/libs/render/cache/util.js +0 -18
- package/dist/js/node/libs/render/index.js +6 -26
- package/dist/js/node/libs/render/measure.js +0 -17
- package/dist/js/node/libs/render/modern/index.js +2 -20
- package/dist/js/node/libs/render/reader.js +12 -39
- package/dist/js/node/libs/render/ssr.js +4 -16
- package/dist/js/node/libs/render/static.js +6 -18
- package/dist/js/node/libs/render/type.js +0 -1
- package/dist/js/node/libs/route/index.js +8 -22
- package/dist/js/node/libs/route/matcher.js +18 -34
- package/dist/js/node/libs/route/route.js +0 -15
- package/dist/js/node/libs/serve-file.js +5 -13
- package/dist/js/node/server/index.js +19 -61
- package/dist/js/node/server/modern-server-split.js +0 -13
- package/dist/js/node/server/modern-server.js +83 -193
- package/dist/js/node/utils.js +3 -46
- package/dist/js/node/worker-server.js +41 -0
- package/dist/js/treeshaking/constants.js +28 -0
- package/dist/js/treeshaking/index.js +13 -0
- package/dist/js/treeshaking/libs/context/context.js +243 -0
- package/dist/js/treeshaking/libs/context/index.js +5 -0
- package/dist/js/treeshaking/libs/hook-api/index.js +157 -0
- package/dist/js/treeshaking/libs/hook-api/route.js +33 -0
- package/dist/js/treeshaking/libs/hook-api/template.js +91 -0
- package/dist/js/treeshaking/libs/loadConfig.js +39 -0
- package/dist/js/treeshaking/libs/metrics.js +12 -0
- package/dist/js/treeshaking/libs/proxy.js +80 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/cache.fun.test.js +124 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/cache.test.js +464 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/cacheable.js +53 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/error-configuration.js +35 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/matched-cache.js +121 -0
- package/dist/js/treeshaking/libs/render/cache/index.js +184 -0
- package/dist/js/treeshaking/libs/render/cache/page-caches/index.js +30 -0
- package/dist/js/treeshaking/libs/render/cache/page-caches/lru.js +46 -0
- package/dist/js/treeshaking/libs/render/cache/spr.js +362 -0
- package/dist/js/treeshaking/libs/render/cache/type.js +1 -0
- package/dist/js/treeshaking/libs/render/cache/util.js +101 -0
- package/dist/js/treeshaking/libs/render/index.js +100 -0
- package/dist/js/treeshaking/libs/render/measure.js +61 -0
- package/dist/js/treeshaking/libs/render/modern/browser-list.js +7 -0
- package/dist/js/treeshaking/libs/render/modern/index.js +39 -0
- package/dist/js/treeshaking/libs/render/reader.js +191 -0
- package/dist/js/treeshaking/libs/render/ssr.js +98 -0
- package/dist/js/treeshaking/libs/render/static.js +84 -0
- package/dist/js/treeshaking/libs/render/type.js +6 -0
- package/dist/js/treeshaking/libs/route/index.js +94 -0
- package/dist/js/treeshaking/libs/route/matcher.js +113 -0
- package/dist/js/treeshaking/libs/route/route.js +26 -0
- package/dist/js/treeshaking/libs/serve-file.js +75 -0
- package/dist/js/treeshaking/server/index.js +343 -0
- package/dist/js/treeshaking/server/modern-server-split.js +152 -0
- package/dist/js/treeshaking/server/modern-server.js +945 -0
- package/dist/js/treeshaking/type.js +1 -0
- package/dist/js/treeshaking/utils.js +87 -0
- package/dist/js/treeshaking/worker-server.js +56 -0
- package/dist/types/index.d.ts +0 -2
- package/dist/types/libs/context/context.d.ts +0 -3
- package/dist/types/libs/loadConfig.d.ts +0 -1
- package/dist/types/libs/render/cache/index.d.ts +0 -2
- package/dist/types/libs/render/cache/spr.d.ts +0 -2
- package/dist/types/server/index.d.ts +0 -3
- package/dist/types/utils.d.ts +0 -1
- package/dist/types/worker-server.d.ts +16 -0
- 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;
|
|
129
|
-
|
|
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);
|
|
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
|
-
}
|
|
150
|
-
|
|
103
|
+
}
|
|
151
104
|
|
|
105
|
+
// start file reader
|
|
152
106
|
this.reader.init();
|
|
153
107
|
app.on('close', () => {
|
|
154
108
|
this.reader.close();
|
|
155
|
-
});
|
|
109
|
+
});
|
|
156
110
|
|
|
111
|
+
// use preset routes priority
|
|
157
112
|
const usageRoutes = this.filterRoutes(this.getRoutes());
|
|
158
|
-
this.router.reset(usageRoutes);
|
|
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);
|
|
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);
|
|
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));
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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 || {};
|
|
256
|
+
} = options || {};
|
|
315
257
|
|
|
258
|
+
// server hook, gather plugin inject
|
|
316
259
|
const _createMiddlewareColl = (0, _utils2.createMiddlewareCollecter)(),
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
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);
|
|
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;
|
|
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
|
-
}
|
|
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
|
-
|
|
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;
|
|
475
|
-
|
|
398
|
+
} = afterMatchContext.router;
|
|
399
|
+
// redirect to another url
|
|
476
400
|
if (url) {
|
|
477
401
|
this.redirect(res, url, status);
|
|
478
402
|
return;
|
|
479
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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());
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
|
|
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);
|
|
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;
|
|
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) {
|
|
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;
|