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