@modern-js/prod-server 2.27.0 → 2.29.0
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 +36 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/libs/context/context.js +10 -4
- package/dist/cjs/libs/hook-api/index.js +2 -1
- package/dist/cjs/libs/hook-api/index.worker.js +2 -1
- package/dist/cjs/libs/render/cache/__tests__/cache.test.js +12 -7
- package/dist/cjs/libs/render/cache/index.js +2 -1
- package/dist/cjs/libs/render/cache/spr.js +2 -1
- package/dist/cjs/libs/render/index.js +12 -3
- package/dist/cjs/libs/render/reader.js +2 -1
- package/dist/cjs/libs/render/ssr.js +3 -20
- package/dist/cjs/libs/reporter.js +22 -0
- package/dist/cjs/libs/route/matcher.js +2 -2
- package/dist/cjs/libs/serverTiming.js +27 -0
- package/dist/cjs/server/index.js +6 -4
- package/dist/cjs/server/modernServer.js +44 -16
- package/dist/cjs/utils.js +33 -0
- package/dist/cjs/workerServer.js +15 -6
- package/dist/esm/index.js +1 -0
- package/dist/esm/libs/context/context.js +8 -2
- package/dist/esm/libs/hook-api/index.js +2 -1
- package/dist/esm/libs/hook-api/index.worker.js +2 -1
- package/dist/esm/libs/render/cache/__tests__/cache.test.js +12 -12
- package/dist/esm/libs/render/cache/index.js +2 -2
- package/dist/esm/libs/render/cache/spr.js +2 -2
- package/dist/esm/libs/render/index.js +12 -3
- package/dist/esm/libs/render/reader.js +2 -2
- package/dist/esm/libs/render/ssr.js +6 -28
- package/dist/esm/libs/reporter.js +12 -0
- package/dist/esm/libs/route/matcher.js +2 -2
- package/dist/esm/libs/serverTiming.js +27 -0
- package/dist/esm/renderHtml.js +6 -6
- package/dist/esm/server/index.js +6 -4
- package/dist/esm/server/modernServer.js +84 -44
- package/dist/esm/server/modernServerSplit.js +6 -6
- package/dist/esm/utils.js +57 -0
- package/dist/esm/workerServer.js +14 -5
- package/dist/esm-node/index.js +1 -0
- package/dist/esm-node/libs/context/context.js +8 -2
- package/dist/esm-node/libs/hook-api/index.js +2 -1
- package/dist/esm-node/libs/hook-api/index.worker.js +2 -1
- package/dist/esm-node/libs/render/cache/__tests__/cache.test.js +12 -7
- package/dist/esm-node/libs/render/cache/index.js +2 -1
- package/dist/esm-node/libs/render/cache/spr.js +2 -1
- package/dist/esm-node/libs/render/index.js +12 -3
- package/dist/esm-node/libs/render/reader.js +2 -1
- package/dist/esm-node/libs/render/ssr.js +3 -20
- package/dist/esm-node/libs/reporter.js +12 -0
- package/dist/esm-node/libs/route/matcher.js +2 -2
- package/dist/esm-node/libs/serverTiming.js +17 -0
- package/dist/esm-node/server/index.js +6 -4
- package/dist/esm-node/server/modernServer.js +45 -17
- package/dist/esm-node/utils.js +30 -0
- package/dist/esm-node/workerServer.js +15 -6
- package/dist/types/index.d.ts +1 -0
- package/dist/types/libs/context/context.d.ts +5 -2
- package/dist/types/libs/hook-api/index.worker.d.ts +2 -1
- package/dist/types/libs/render/index.d.ts +13 -18
- package/dist/types/libs/reporter.d.ts +2 -0
- package/dist/types/libs/serverTiming.d.ts +12 -0
- package/dist/types/server/modernServer.d.ts +6 -4
- package/dist/types/type.d.ts +1 -0
- package/dist/types/utils.d.ts +3 -2
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @modern-js/prod-server
|
|
2
2
|
|
|
3
|
+
## 2.29.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 16e5195: feat(prod-server): add body parser
|
|
8
|
+
feat(prod-server): 增加 body 解析器
|
|
9
|
+
- cba7675: feat: add a server reporter that report server cost, logger about error, info etc.
|
|
10
|
+
feat: 添加一个 server 端 reporter,来报告 server 端耗时,报错等
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 76ace5d: fix(prod-server): bff may run bodyParser by themself, so we need't to run
|
|
15
|
+
fix(prod-server): bff 可能会在内部运行, 所以我们不需要运行
|
|
16
|
+
- Updated dependencies [e6b5355]
|
|
17
|
+
- Updated dependencies [93db783]
|
|
18
|
+
- Updated dependencies [cba7675]
|
|
19
|
+
- Updated dependencies [99052ea]
|
|
20
|
+
- Updated dependencies [1d71d2e]
|
|
21
|
+
- @modern-js/utils@2.29.0
|
|
22
|
+
- @modern-js/server-core@2.29.0
|
|
23
|
+
- @modern-js/plugin@2.29.0
|
|
24
|
+
|
|
25
|
+
## 2.28.0
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- 6eae1e7: feat: support worker hmr using dev-server
|
|
30
|
+
feat: 借用 dev-server 支持 wokrer hmr
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Updated dependencies [00b58a7]
|
|
35
|
+
- @modern-js/utils@2.28.0
|
|
36
|
+
- @modern-js/server-core@2.28.0
|
|
37
|
+
- @modern-js/plugin@2.28.0
|
|
38
|
+
|
|
3
39
|
## 2.27.0
|
|
4
40
|
|
|
5
41
|
### Patch Changes
|
package/dist/cjs/index.js
CHANGED
|
@@ -19,6 +19,9 @@ _export(exports, {
|
|
|
19
19
|
createProxyHandler: function() {
|
|
20
20
|
return _proxy.createProxyHandler;
|
|
21
21
|
},
|
|
22
|
+
createRenderHandler: function() {
|
|
23
|
+
return _render.createRenderHandler;
|
|
24
|
+
},
|
|
22
25
|
default: function() {
|
|
23
26
|
return _default;
|
|
24
27
|
}
|
|
@@ -29,6 +32,7 @@ const _modernServer = require("./server/modernServer");
|
|
|
29
32
|
const _proxy = require("./libs/proxy");
|
|
30
33
|
_export_star._(require("./type"), exports);
|
|
31
34
|
_export_star._(require("./constants"), exports);
|
|
35
|
+
const _render = require("./libs/render");
|
|
32
36
|
const _default = (options) => {
|
|
33
37
|
if (options == null) {
|
|
34
38
|
throw new Error("can not start mserver without options");
|
|
@@ -15,7 +15,10 @@ const _querystring = /* @__PURE__ */ _interop_require_default._(require("queryst
|
|
|
15
15
|
const _buffer = require("buffer");
|
|
16
16
|
const _etag = /* @__PURE__ */ _interop_require_default._(require("etag"));
|
|
17
17
|
const _fresh = /* @__PURE__ */ _interop_require_default._(require("fresh"));
|
|
18
|
-
const _utils = require("
|
|
18
|
+
const _utils = require("@modern-js/utils");
|
|
19
|
+
const _serverTiming = require("../serverTiming");
|
|
20
|
+
const _reporter = require("../reporter");
|
|
21
|
+
const _utils1 = require("../../utils");
|
|
19
22
|
const MOCK_URL_BASE = "https://modernjs.dev/";
|
|
20
23
|
class ModernServerContext {
|
|
21
24
|
get logger() {
|
|
@@ -157,18 +160,21 @@ class ModernServerContext {
|
|
|
157
160
|
return this.res.writableEnded;
|
|
158
161
|
}
|
|
159
162
|
error(dig, e = "") {
|
|
160
|
-
this.logger.error(`Web Server Error - ${dig}, error = %s, req.url = %s, req.headers = %o`, e instanceof Error ? e.stack || e.message : e, this.path, (0,
|
|
163
|
+
this.logger.error(`Web Server Error - ${dig}, error = %s, req.url = %s, req.headers = %o`, e instanceof Error ? e.stack || e.message : e, this.path, (0, _utils1.headersWithoutCookie)(this.headers));
|
|
161
164
|
}
|
|
162
165
|
constructor(req, res, options) {
|
|
166
|
+
var _options;
|
|
163
167
|
_define_property._(this, "req", void 0);
|
|
164
168
|
_define_property._(this, "res", void 0);
|
|
165
169
|
_define_property._(this, "params", {});
|
|
166
|
-
_define_property._(this, "
|
|
170
|
+
_define_property._(this, "reporter", _reporter.defaultReporter);
|
|
171
|
+
_define_property._(this, "serverTiming", void 0);
|
|
172
|
+
_define_property._(this, "serverData", {});
|
|
167
173
|
_define_property._(this, "options", {});
|
|
168
174
|
this.req = req;
|
|
169
175
|
this.res = res;
|
|
170
176
|
this.options = options || {};
|
|
171
|
-
this.
|
|
177
|
+
this.serverTiming = new _serverTiming.ServerTiming(res, (0, _utils.cutNameByHyphen)(((_options = options) === null || _options === void 0 ? void 0 : _options.metaName) || "modern-js"));
|
|
172
178
|
this.bind();
|
|
173
179
|
}
|
|
174
180
|
}
|
|
@@ -27,10 +27,11 @@ const _route = require("./route");
|
|
|
27
27
|
const _template = require("./template");
|
|
28
28
|
const _base = require("./base");
|
|
29
29
|
const base = (context) => {
|
|
30
|
-
const { res } = context;
|
|
30
|
+
const { res, reporter } = context;
|
|
31
31
|
return {
|
|
32
32
|
response: new _base.BaseResponse(res),
|
|
33
33
|
request: new _base.BaseRequest(context),
|
|
34
|
+
reporter,
|
|
34
35
|
logger: context.logger,
|
|
35
36
|
metrics: context.metrics
|
|
36
37
|
};
|
|
@@ -56,7 +56,7 @@ class ServerResponse {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
const base = (context) => {
|
|
59
|
-
const { req, res, logger, metrics } = context;
|
|
59
|
+
const { req, res, logger, metrics, reporter } = context;
|
|
60
60
|
const serverResponse = new ServerResponse(res);
|
|
61
61
|
const { host, pathname, searchParams } = new URL(req.url);
|
|
62
62
|
const headers = {};
|
|
@@ -65,6 +65,7 @@ const base = (context) => {
|
|
|
65
65
|
});
|
|
66
66
|
return {
|
|
67
67
|
response: new _base.BaseResponse(serverResponse),
|
|
68
|
+
reporter,
|
|
68
69
|
request: new _base.BaseRequest({
|
|
69
70
|
url: req.url,
|
|
70
71
|
host,
|
|
@@ -19,6 +19,7 @@ const createCacheConfig = (config = {}) => ({
|
|
|
19
19
|
jest.setTimeout(6e4);
|
|
20
20
|
describe("cache", () => {
|
|
21
21
|
it("should cache correctly", async () => {
|
|
22
|
+
var _cacheResult;
|
|
22
23
|
(0, _spr.destroyCache)();
|
|
23
24
|
const cache = (0, _spr.createCache)();
|
|
24
25
|
const context = {
|
|
@@ -32,7 +33,7 @@ describe("cache", () => {
|
|
|
32
33
|
await cache.set(context, content, cacheConfig, true);
|
|
33
34
|
const cacheResult = await cache.get(context);
|
|
34
35
|
expect(cacheResult).not.toBe(null);
|
|
35
|
-
expect(cacheResult === null ||
|
|
36
|
+
expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe("hello");
|
|
36
37
|
});
|
|
37
38
|
it("should ignore cache set when cache config not exist", async () => {
|
|
38
39
|
(0, _spr.destroyCache)();
|
|
@@ -127,6 +128,7 @@ describe("cache", () => {
|
|
|
127
128
|
(0, _spr.destroyCache)();
|
|
128
129
|
const cache = (0, _spr.createCache)();
|
|
129
130
|
for (const cacheable of _cacheable.cacheabelAry) {
|
|
131
|
+
var _cacheResult;
|
|
130
132
|
const context = {
|
|
131
133
|
entry: "",
|
|
132
134
|
pathname: cacheable.requestOpt.url,
|
|
@@ -136,13 +138,14 @@ describe("cache", () => {
|
|
|
136
138
|
const cacheConfig = createCacheConfig(cacheable.cacheConfig || {});
|
|
137
139
|
await cache.set(context, cacheable.content, cacheConfig, true);
|
|
138
140
|
const cacheResult = await cache.get(context);
|
|
139
|
-
expect(cacheResult === null ||
|
|
141
|
+
expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe(cacheable.content);
|
|
140
142
|
}
|
|
141
143
|
});
|
|
142
144
|
it("should match cache correctly", async () => {
|
|
143
145
|
(0, _spr.destroyCache)();
|
|
144
146
|
const cache = (0, _spr.createCache)();
|
|
145
147
|
for (const cacheable of _matchedcache.matchedCacheableAry) {
|
|
148
|
+
var _cacheResult;
|
|
146
149
|
const [baseCacheable, matchOne, ...other] = cacheable;
|
|
147
150
|
const { requestOpt = {}, cacheConfig, content } = baseCacheable;
|
|
148
151
|
const context = {
|
|
@@ -159,7 +162,7 @@ describe("cache", () => {
|
|
|
159
162
|
headers: matchOne.headers
|
|
160
163
|
};
|
|
161
164
|
const cacheResult = await cache.get(matchContext);
|
|
162
|
-
expect(cacheResult === null ||
|
|
165
|
+
expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe(content);
|
|
163
166
|
for (const notMatch of other) {
|
|
164
167
|
const notMatchContext = {
|
|
165
168
|
entry: "",
|
|
@@ -173,6 +176,7 @@ describe("cache", () => {
|
|
|
173
176
|
}
|
|
174
177
|
});
|
|
175
178
|
it("should stale cache correctly", async () => {
|
|
179
|
+
var _freshResult, _staleResult;
|
|
176
180
|
(0, _spr.destroyCache)();
|
|
177
181
|
const cache = (0, _spr.createCache)();
|
|
178
182
|
const context = {
|
|
@@ -188,16 +192,17 @@ describe("cache", () => {
|
|
|
188
192
|
const shouldCache = await cache.set(context, content, config, true);
|
|
189
193
|
expect(shouldCache.value).toBe(true);
|
|
190
194
|
const freshResult = await cache.get(context);
|
|
191
|
-
expect(freshResult === null ||
|
|
195
|
+
expect((_freshResult = freshResult) === null || _freshResult === void 0 ? void 0 : _freshResult.isStale).toBe(false);
|
|
192
196
|
await new Promise((resolve) => {
|
|
193
197
|
setTimeout(() => {
|
|
194
198
|
resolve();
|
|
195
199
|
}, 6e3);
|
|
196
200
|
});
|
|
197
201
|
const staleResult = await cache.get(context);
|
|
198
|
-
expect(staleResult === null ||
|
|
202
|
+
expect((_staleResult = staleResult) === null || _staleResult === void 0 ? void 0 : _staleResult.isStale).toBe(true);
|
|
199
203
|
});
|
|
200
204
|
it("should garbage cache correctly", async () => {
|
|
205
|
+
var _freshResult, _staleResult;
|
|
201
206
|
(0, _spr.destroyCache)();
|
|
202
207
|
const cache = (0, _spr.createCache)();
|
|
203
208
|
const context = {
|
|
@@ -214,13 +219,13 @@ describe("cache", () => {
|
|
|
214
219
|
const shouldCache = await cache.set(context, content, config, true);
|
|
215
220
|
expect(shouldCache.value).toBe(true);
|
|
216
221
|
const freshResult = await cache.get(context);
|
|
217
|
-
expect(freshResult === null ||
|
|
222
|
+
expect((_freshResult = freshResult) === null || _freshResult === void 0 ? void 0 : _freshResult.isGarbage).toBe(false);
|
|
218
223
|
await new Promise((resolve) => {
|
|
219
224
|
setTimeout(() => {
|
|
220
225
|
resolve();
|
|
221
226
|
}, 1e4);
|
|
222
227
|
});
|
|
223
228
|
const staleResult = await cache.get(context);
|
|
224
|
-
expect(staleResult === null ||
|
|
229
|
+
expect((_staleResult = staleResult) === null || _staleResult === void 0 ? void 0 : _staleResult.isGarbage).toBe(true);
|
|
225
230
|
});
|
|
226
231
|
});
|
|
@@ -15,6 +15,7 @@ const _util = require("./util");
|
|
|
15
15
|
const _default = (renderFn, ctx) => {
|
|
16
16
|
const sprCache = (0, _spr.createCache)();
|
|
17
17
|
const doRender = async (context) => {
|
|
18
|
+
var _cacheFile;
|
|
18
19
|
const cacheContext = {
|
|
19
20
|
entry: context.entryName,
|
|
20
21
|
...context.request
|
|
@@ -50,7 +51,7 @@ const _default = (renderFn, ctx) => {
|
|
|
50
51
|
const renderResult = await renderFn(context);
|
|
51
52
|
return afterRender(renderResult, saveHtmlIntoCache);
|
|
52
53
|
}
|
|
53
|
-
const cacheHash = cacheFile === null ||
|
|
54
|
+
const cacheHash = (_cacheFile = cacheFile) === null || _cacheFile === void 0 ? void 0 : _cacheFile.hash;
|
|
54
55
|
if (cacheFile.isGarbage) {
|
|
55
56
|
const renderResult = await renderFn(context);
|
|
56
57
|
return afterRender(renderResult, saveHtmlIntoCache);
|
|
@@ -161,9 +161,10 @@ class CacheManager {
|
|
|
161
161
|
return (0, _util.maybeSync)(doCache)(sync);
|
|
162
162
|
}
|
|
163
163
|
async del(context, cacheHash) {
|
|
164
|
+
var _data;
|
|
164
165
|
const cacheKey = this.generateRequestKey(context);
|
|
165
166
|
const data = this.cache.get(cacheKey);
|
|
166
|
-
data === null ||
|
|
167
|
+
(_data = data) === null || _data === void 0 ? void 0 : _data.caches.del(cacheHash);
|
|
167
168
|
}
|
|
168
169
|
constructor(cacheOptions) {
|
|
169
170
|
_define_property._(this, "cache", void 0);
|
|
@@ -17,7 +17,7 @@ const _static = require("./static");
|
|
|
17
17
|
const _reader = require("./reader");
|
|
18
18
|
const _ssr = /* @__PURE__ */ _interop_require_wildcard._(require("./ssr"));
|
|
19
19
|
const _utils1 = require("./utils");
|
|
20
|
-
const createRenderHandler = ({ distDir, staticGenerate, forceCSR, nonce, metaName = "modern-js" }) => async function render({ ctx, route, runner }) {
|
|
20
|
+
const createRenderHandler = ({ distDir, staticGenerate, forceCSR, nonce, ssrRender, metaName = "modern-js" }) => async function render({ ctx, route, runner }) {
|
|
21
21
|
if (ctx.resHasHandled()) {
|
|
22
22
|
return null;
|
|
23
23
|
}
|
|
@@ -35,7 +35,7 @@ const createRenderHandler = ({ distDir, staticGenerate, forceCSR, nonce, metaNam
|
|
|
35
35
|
const useCSR = forceCSR && (ctx.query.csr || ctx.headers[`x-${(0, _utils.cutNameByHyphen)(metaName)}-ssr-fallback`]);
|
|
36
36
|
if (route.isSSR && !useCSR) {
|
|
37
37
|
try {
|
|
38
|
-
const
|
|
38
|
+
const ssrRenderOptions = {
|
|
39
39
|
distDir,
|
|
40
40
|
entryName: route.entryName,
|
|
41
41
|
urlPath: route.urlPath,
|
|
@@ -43,7 +43,16 @@ const createRenderHandler = ({ distDir, staticGenerate, forceCSR, nonce, metaNam
|
|
|
43
43
|
template: content.toString(),
|
|
44
44
|
staticGenerate,
|
|
45
45
|
nonce
|
|
46
|
-
}
|
|
46
|
+
};
|
|
47
|
+
const result = await (ssrRender ? ssrRender(ctx, ssrRenderOptions, runner) : _ssr.render(ctx, {
|
|
48
|
+
distDir,
|
|
49
|
+
entryName: route.entryName,
|
|
50
|
+
urlPath: route.urlPath,
|
|
51
|
+
bundle: route.bundle,
|
|
52
|
+
template: content.toString(),
|
|
53
|
+
staticGenerate,
|
|
54
|
+
nonce
|
|
55
|
+
}, runner));
|
|
47
56
|
return result;
|
|
48
57
|
} catch (err) {
|
|
49
58
|
ctx.error(_constants.ERROR_DIGEST.ERENDER, err.stack || err.message);
|
|
@@ -101,8 +101,9 @@ class LruReader {
|
|
|
101
101
|
}
|
|
102
102
|
const reader = new LruReader();
|
|
103
103
|
const readFile = async (filepath) => {
|
|
104
|
+
var _file;
|
|
104
105
|
const file = await reader.read(filepath);
|
|
105
|
-
return file === null ||
|
|
106
|
+
return (_file = file) === null || _file === void 0 ? void 0 : _file.content;
|
|
106
107
|
};
|
|
107
108
|
const updateFile = () => {
|
|
108
109
|
reader.update();
|
|
@@ -22,7 +22,6 @@ const render = async (ctx, renderOptions, runner) => {
|
|
|
22
22
|
const loadableStats = _utils.fs.existsSync(loadableUri) ? require(loadableUri) : "";
|
|
23
23
|
const routesManifestUri = _path.default.join(distDir, _utils.ROUTE_MANIFEST_FILE);
|
|
24
24
|
const routeManifest = _utils.fs.existsSync(routesManifestUri) ? require(routesManifestUri) : void 0;
|
|
25
|
-
const body = await getRequestBody(ctx.req);
|
|
26
25
|
const context = {
|
|
27
26
|
request: {
|
|
28
27
|
baseUrl: urlPath,
|
|
@@ -32,7 +31,7 @@ const render = async (ctx, renderOptions, runner) => {
|
|
|
32
31
|
query: ctx.query,
|
|
33
32
|
url: ctx.href,
|
|
34
33
|
headers: ctx.headers,
|
|
35
|
-
body
|
|
34
|
+
body: ctx.req.body
|
|
36
35
|
},
|
|
37
36
|
response: {
|
|
38
37
|
setHeader: (key, value) => {
|
|
@@ -51,6 +50,8 @@ const render = async (ctx, renderOptions, runner) => {
|
|
|
51
50
|
staticGenerate,
|
|
52
51
|
logger: void 0,
|
|
53
52
|
metrics: void 0,
|
|
53
|
+
reporter: ctx.reporter,
|
|
54
|
+
serverTiming: ctx.serverTiming,
|
|
54
55
|
req: ctx.req,
|
|
55
56
|
res: ctx.res,
|
|
56
57
|
enableUnsafeCtx,
|
|
@@ -84,21 +85,3 @@ const render = async (ctx, renderOptions, runner) => {
|
|
|
84
85
|
};
|
|
85
86
|
}
|
|
86
87
|
};
|
|
87
|
-
const getRequestBody = (req) => {
|
|
88
|
-
return new Promise((resolve, reject) => {
|
|
89
|
-
if ((req === null || req === void 0 ? void 0 : req.method) && req.method.toLowerCase() !== "get") {
|
|
90
|
-
let body = "";
|
|
91
|
-
req.on("data", (chunk) => {
|
|
92
|
-
body += chunk.toString();
|
|
93
|
-
});
|
|
94
|
-
req.on("end", () => {
|
|
95
|
-
resolve(body);
|
|
96
|
-
});
|
|
97
|
-
req.on("error", (err) => {
|
|
98
|
-
reject(err);
|
|
99
|
-
});
|
|
100
|
-
} else {
|
|
101
|
-
resolve(void 0);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "defaultReporter", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return defaultReporter;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const defaultReporter = {
|
|
12
|
+
init() {
|
|
13
|
+
},
|
|
14
|
+
reportError() {
|
|
15
|
+
},
|
|
16
|
+
reportTiming() {
|
|
17
|
+
},
|
|
18
|
+
reportInfo() {
|
|
19
|
+
},
|
|
20
|
+
reportWarn() {
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -49,9 +49,9 @@ class RouteMatcher {
|
|
|
49
49
|
if (!this.urlReg) {
|
|
50
50
|
return this.urlPath.length;
|
|
51
51
|
} else {
|
|
52
|
-
var _result_;
|
|
52
|
+
var _result_, _result;
|
|
53
53
|
const result = this.urlReg.exec(pathname);
|
|
54
|
-
return (result === null ||
|
|
54
|
+
return ((_result = result) === null || _result === void 0 ? void 0 : (_result_ = _result[0]) === null || _result_ === void 0 ? void 0 : _result_.length) || null;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
// if match url path
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "ServerTiming", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return ServerTiming;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _define_property = require("@swc/helpers/_/_define_property");
|
|
12
|
+
const SERVER_TIMING = "Server-Timing";
|
|
13
|
+
class ServerTiming {
|
|
14
|
+
addServeTiming(name, dur, desc) {
|
|
15
|
+
const _name = `bd-${this.meta}-${name}`;
|
|
16
|
+
const serverTiming = this.res.getHeader(SERVER_TIMING) || this.res.getHeader(SERVER_TIMING.toLocaleLowerCase());
|
|
17
|
+
const value = `${_name};${desc ? `decs="${desc}";` : ""} dur=${dur}`;
|
|
18
|
+
this.res.setHeader(SERVER_TIMING, serverTiming ? `${serverTiming}, ${value}` : value);
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
constructor(res, meta) {
|
|
22
|
+
_define_property._(this, "meta", void 0);
|
|
23
|
+
_define_property._(this, "res", void 0);
|
|
24
|
+
this.meta = meta;
|
|
25
|
+
this.res = res;
|
|
26
|
+
}
|
|
27
|
+
}
|
package/dist/cjs/server/index.js
CHANGED
|
@@ -89,7 +89,8 @@ class Server {
|
|
|
89
89
|
}
|
|
90
90
|
listen(options, listener) {
|
|
91
91
|
const callback = () => {
|
|
92
|
-
|
|
92
|
+
var _listener;
|
|
93
|
+
(_listener = listener) === null || _listener === void 0 ? void 0 : _listener();
|
|
93
94
|
};
|
|
94
95
|
if (typeof options === "object") {
|
|
95
96
|
if (process.env.PORT) {
|
|
@@ -139,6 +140,7 @@ class Server {
|
|
|
139
140
|
});
|
|
140
141
|
}
|
|
141
142
|
initAppContext() {
|
|
143
|
+
var _appContext, _appContext1, _appContext2;
|
|
142
144
|
const { options } = this;
|
|
143
145
|
const { pwd: appDirectory, plugins = [], config, appContext } = options;
|
|
144
146
|
const serverPlugins = plugins.map((p) => ({
|
|
@@ -146,9 +148,9 @@ class Server {
|
|
|
146
148
|
}));
|
|
147
149
|
return {
|
|
148
150
|
appDirectory,
|
|
149
|
-
apiDirectory: appContext === null ||
|
|
150
|
-
lambdaDirectory: appContext === null ||
|
|
151
|
-
sharedDirectory: (appContext === null ||
|
|
151
|
+
apiDirectory: (_appContext = appContext) === null || _appContext === void 0 ? void 0 : _appContext.apiDirectory,
|
|
152
|
+
lambdaDirectory: (_appContext1 = appContext) === null || _appContext1 === void 0 ? void 0 : _appContext1.lambdaDirectory,
|
|
153
|
+
sharedDirectory: ((_appContext2 = appContext) === null || _appContext2 === void 0 ? void 0 : _appContext2.sharedDirectory) || _path.default.resolve(appDirectory, _utils.SHARED_DIR),
|
|
152
154
|
distDirectory: _path.default.join(appDirectory, config.output.path || "dist"),
|
|
153
155
|
plugins: serverPlugins
|
|
154
156
|
};
|
|
@@ -14,6 +14,7 @@ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildc
|
|
|
14
14
|
const _http = require("http");
|
|
15
15
|
const _path = /* @__PURE__ */ _interop_require_default._(require("path"));
|
|
16
16
|
const _utils = require("@modern-js/utils");
|
|
17
|
+
const _time = require("@modern-js/utils/universal/time");
|
|
17
18
|
const _route = require("../libs/route");
|
|
18
19
|
const _render = require("../libs/render");
|
|
19
20
|
const _serveFile = require("../libs/serveFile");
|
|
@@ -27,9 +28,9 @@ const SERVER_DIR = "./server";
|
|
|
27
28
|
class ModernServer {
|
|
28
29
|
// server prepare
|
|
29
30
|
async onInit(runner, app) {
|
|
30
|
-
var _conf_bff,
|
|
31
|
+
var _conf_bff, _app, _this_conf_output;
|
|
31
32
|
this.runner = runner;
|
|
32
|
-
const { distDir,
|
|
33
|
+
const { distDir, conf } = this;
|
|
33
34
|
this.initReader();
|
|
34
35
|
(0, _utils1.debug)("final server conf", this.conf);
|
|
35
36
|
this.proxyHandler = (0, _proxy.createProxyHandler)((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
|
|
@@ -38,7 +39,7 @@ class ModernServer {
|
|
|
38
39
|
this.addHandler(handler);
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
|
-
app === null ||
|
|
42
|
+
(_app = app) === null || _app === void 0 ? void 0 : _app.on("close", () => {
|
|
42
43
|
this.reader.close();
|
|
43
44
|
});
|
|
44
45
|
const usageRoutes = this.filterRoutes(this.getRoutes());
|
|
@@ -46,20 +47,25 @@ class ModernServer {
|
|
|
46
47
|
this.warmupSSRBundle();
|
|
47
48
|
await this.prepareFrameHandler();
|
|
48
49
|
await this.prepareLoaderHandler(usageRoutes, distDir);
|
|
50
|
+
this.routeRenderHandler = this.getRenderHandler();
|
|
51
|
+
await this.setupBeforeProdMiddleware();
|
|
52
|
+
this.addHandler(this.setupStaticMiddleware((_this_conf_output = this.conf.output) === null || _this_conf_output === void 0 ? void 0 : _this_conf_output.assetPrefix));
|
|
53
|
+
this.addHandler(_serveFile.faviconFallbackHandler);
|
|
54
|
+
this.addHandler(this.routeHandler.bind(this));
|
|
55
|
+
this.compose();
|
|
56
|
+
}
|
|
57
|
+
getRenderHandler() {
|
|
58
|
+
var _this_conf_server, _conf_security;
|
|
59
|
+
const { distDir, staticGenerate, conf, metaName } = this;
|
|
49
60
|
const ssrConfig = (_this_conf_server = this.conf.server) === null || _this_conf_server === void 0 ? void 0 : _this_conf_server.ssr;
|
|
50
61
|
const forceCSR = typeof ssrConfig === "object" ? ssrConfig.forceCSR : false;
|
|
51
|
-
|
|
62
|
+
return (0, _render.createRenderHandler)({
|
|
52
63
|
distDir,
|
|
53
64
|
staticGenerate,
|
|
54
65
|
forceCSR,
|
|
55
66
|
nonce: (_conf_security = conf.security) === null || _conf_security === void 0 ? void 0 : _conf_security.nonce,
|
|
56
67
|
metaName
|
|
57
68
|
});
|
|
58
|
-
await this.setupBeforeProdMiddleware();
|
|
59
|
-
this.addHandler(this.setupStaticMiddleware((_this_conf_output = this.conf.output) === null || _this_conf_output === void 0 ? void 0 : _this_conf_output.assetPrefix));
|
|
60
|
-
this.addHandler(_serveFile.faviconFallbackHandler);
|
|
61
|
-
this.addHandler(this.routeHandler.bind(this));
|
|
62
|
-
this.compose();
|
|
63
69
|
}
|
|
64
70
|
// server ready
|
|
65
71
|
onRepack(_) {
|
|
@@ -71,7 +77,9 @@ class ModernServer {
|
|
|
71
77
|
async render(req, res, url) {
|
|
72
78
|
req.logger = req.logger || this.logger;
|
|
73
79
|
req.metrics = req.metrics || this.metrics;
|
|
74
|
-
const context = (0, _context.createContext)(req, res
|
|
80
|
+
const context = (0, _context.createContext)(req, res, {
|
|
81
|
+
metaName: this.metaName
|
|
82
|
+
});
|
|
75
83
|
const matched = this.router.match(url || context.path);
|
|
76
84
|
if (!matched) {
|
|
77
85
|
return null;
|
|
@@ -165,9 +173,10 @@ class ModernServer {
|
|
|
165
173
|
return handler;
|
|
166
174
|
}
|
|
167
175
|
async prepareAPIHandler(extension) {
|
|
176
|
+
var _bff, _bff1;
|
|
168
177
|
const { workDir, runner, conf } = this;
|
|
169
178
|
const { bff } = conf;
|
|
170
|
-
const prefix = (bff === null ||
|
|
179
|
+
const prefix = ((_bff = bff) === null || _bff === void 0 ? void 0 : _bff.prefix) || "/api";
|
|
171
180
|
const webOnly = await (0, _utils.isWebOnly)();
|
|
172
181
|
if (webOnly && process.env.NODE_ENV === "development") {
|
|
173
182
|
return (req, res) => {
|
|
@@ -179,7 +188,7 @@ class ModernServer {
|
|
|
179
188
|
pwd: workDir,
|
|
180
189
|
config: extension,
|
|
181
190
|
prefix: Array.isArray(prefix) ? prefix[0] : prefix,
|
|
182
|
-
httpMethodDecider: bff === null ||
|
|
191
|
+
httpMethodDecider: (_bff1 = bff) === null || _bff1 === void 0 ? void 0 : _bff1.httpMethodDecider,
|
|
183
192
|
render: this.render.bind(this)
|
|
184
193
|
}, {
|
|
185
194
|
onLast: () => null
|
|
@@ -271,23 +280,35 @@ class ModernServer {
|
|
|
271
280
|
/* —————————————————————— private function —————————————————————— */
|
|
272
281
|
// handler route.json, include api / csr / ssr
|
|
273
282
|
async routeHandler(context) {
|
|
274
|
-
const { res } = context;
|
|
283
|
+
const { res, req, reporter } = context;
|
|
275
284
|
const matched = this.router.match(context.path);
|
|
276
285
|
if (!matched) {
|
|
277
286
|
this.render404(context);
|
|
278
287
|
return;
|
|
279
288
|
}
|
|
289
|
+
await reporter.init({
|
|
290
|
+
match: matched
|
|
291
|
+
});
|
|
292
|
+
const end = (0, _time.time)();
|
|
293
|
+
res.on("finish", () => {
|
|
294
|
+
const cost = end();
|
|
295
|
+
reporter.reportTiming("server_handle_request", cost);
|
|
296
|
+
});
|
|
280
297
|
let route = matched.generate(context.url);
|
|
281
298
|
if (route.isApi) {
|
|
282
299
|
await this.handleAPI(context);
|
|
283
300
|
return;
|
|
284
301
|
}
|
|
302
|
+
await (0, _utils1.bodyParser)(req);
|
|
285
303
|
if (route.entryName) {
|
|
286
304
|
const afterMatchContext = (0, _hookapi.createAfterMatchContext)(context, route.entryName);
|
|
287
305
|
if (this.runMode === _constants.RUN_MODE.FULL) {
|
|
306
|
+
const end2 = (0, _time.time)();
|
|
288
307
|
await this.runner.afterMatch(afterMatchContext, {
|
|
289
308
|
onLast: _utils1.noop
|
|
290
309
|
});
|
|
310
|
+
const cost = end2();
|
|
311
|
+
reporter.reportTiming("server_hook_after_render", cost);
|
|
291
312
|
}
|
|
292
313
|
if (this.isSend(res)) {
|
|
293
314
|
return;
|
|
@@ -309,7 +330,10 @@ class ModernServer {
|
|
|
309
330
|
if (this.frameWebHandler) {
|
|
310
331
|
res.locals = res.locals || {};
|
|
311
332
|
const middlewareContext = (0, _hookapi.createMiddlewareContext)(context);
|
|
333
|
+
const end2 = (0, _time.time)();
|
|
312
334
|
await this.frameWebHandler(middlewareContext);
|
|
335
|
+
const cost = end2();
|
|
336
|
+
reporter.reportTiming("server_middleware", cost);
|
|
313
337
|
res.locals = {
|
|
314
338
|
...res.locals,
|
|
315
339
|
...middlewareContext.response.locals
|
|
@@ -331,9 +355,12 @@ class ModernServer {
|
|
|
331
355
|
if (route.entryName) {
|
|
332
356
|
const afterRenderContext = (0, _hookapi.createAfterRenderContext)(context, response.toString());
|
|
333
357
|
if (this.runMode === _constants.RUN_MODE.FULL) {
|
|
358
|
+
const end2 = (0, _time.time)();
|
|
334
359
|
await this.runner.afterRender(afterRenderContext, {
|
|
335
360
|
onLast: _utils1.noop
|
|
336
361
|
});
|
|
362
|
+
const cost = end2();
|
|
363
|
+
reporter.reportTiming("server_hook_after_render", cost);
|
|
337
364
|
}
|
|
338
365
|
if (this.isSend(res)) {
|
|
339
366
|
return;
|
|
@@ -446,6 +473,7 @@ class ModernServer {
|
|
|
446
473
|
context.res.end((0, _utils1.createErrorDocument)(status, text));
|
|
447
474
|
}
|
|
448
475
|
constructor({ pwd, config, routes, staticGenerate, logger, metrics, runMode, proxyTarget, appContext }) {
|
|
476
|
+
var _appContext;
|
|
449
477
|
_define_property._(this, "pwd", void 0);
|
|
450
478
|
_define_property._(this, "distDir", void 0);
|
|
451
479
|
_define_property._(this, "workDir", void 0);
|
|
@@ -460,13 +488,13 @@ class ModernServer {
|
|
|
460
488
|
_define_property._(this, "reader", _reader);
|
|
461
489
|
_define_property._(this, "proxyTarget", void 0);
|
|
462
490
|
_define_property._(this, "routeRenderHandler", void 0);
|
|
491
|
+
_define_property._(this, "staticGenerate", void 0);
|
|
492
|
+
_define_property._(this, "metaName", void 0);
|
|
463
493
|
_define_property._(this, "loaderHandler", null);
|
|
464
494
|
_define_property._(this, "frameWebHandler", null);
|
|
465
495
|
_define_property._(this, "frameAPIHandler", null);
|
|
466
496
|
_define_property._(this, "proxyHandler", null);
|
|
467
497
|
_define_property._(this, "_handler", void 0);
|
|
468
|
-
_define_property._(this, "staticGenerate", void 0);
|
|
469
|
-
_define_property._(this, "metaName", void 0);
|
|
470
498
|
require("ignore-styles");
|
|
471
499
|
this.pwd = pwd;
|
|
472
500
|
this.distDir = _path.default.resolve(pwd, config.output.path || "dist");
|
|
@@ -480,6 +508,6 @@ class ModernServer {
|
|
|
480
508
|
this.proxyTarget = proxyTarget;
|
|
481
509
|
this.staticGenerate = staticGenerate || false;
|
|
482
510
|
this.runMode = runMode || _constants.RUN_MODE.FULL;
|
|
483
|
-
this.metaName = appContext === null ||
|
|
511
|
+
this.metaName = (_appContext = appContext) === null || _appContext === void 0 ? void 0 : _appContext.metaName;
|
|
484
512
|
}
|
|
485
513
|
}
|
package/dist/cjs/utils.js
CHANGED
|
@@ -36,6 +36,9 @@ _export(exports, {
|
|
|
36
36
|
},
|
|
37
37
|
isRedirect: function() {
|
|
38
38
|
return isRedirect;
|
|
39
|
+
},
|
|
40
|
+
bodyParser: function() {
|
|
41
|
+
return bodyParser;
|
|
39
42
|
}
|
|
40
43
|
});
|
|
41
44
|
const _utils = require("@modern-js/utils");
|
|
@@ -159,3 +162,33 @@ const isRedirect = (code) => {
|
|
|
159
162
|
308
|
|
160
163
|
].includes(code);
|
|
161
164
|
};
|
|
165
|
+
function parseBodyTypes(headers, body) {
|
|
166
|
+
switch (headers["content-type"]) {
|
|
167
|
+
case "application/json":
|
|
168
|
+
return JSON.parse(body);
|
|
169
|
+
default:
|
|
170
|
+
return body;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const getRequestBody = (req) => new Promise((resolve, reject) => {
|
|
174
|
+
var _req;
|
|
175
|
+
if (((_req = req) === null || _req === void 0 ? void 0 : _req.method) && req.method.toLowerCase() !== "get") {
|
|
176
|
+
let body = "";
|
|
177
|
+
req.on("data", (chunk) => {
|
|
178
|
+
body += chunk.toString();
|
|
179
|
+
});
|
|
180
|
+
req.on("end", () => {
|
|
181
|
+
resolve(parseBodyTypes(req.headers, body));
|
|
182
|
+
});
|
|
183
|
+
req.on("error", (err) => {
|
|
184
|
+
reject(err);
|
|
185
|
+
});
|
|
186
|
+
} else {
|
|
187
|
+
resolve(void 0);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
const bodyParser = async (req) => {
|
|
191
|
+
if (!req.body) {
|
|
192
|
+
req.body = await getRequestBody(req);
|
|
193
|
+
}
|
|
194
|
+
};
|