@modern-js/prod-server 2.4.1-beta.0 → 2.5.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 +18 -3
- package/dist/{js/node → cjs}/constants.js +0 -0
- package/dist/{js/node → cjs}/index.js +0 -0
- package/dist/{js/node → cjs}/libs/context/context.js +0 -0
- package/dist/{js/node → cjs}/libs/context/index.js +0 -0
- package/dist/{js/node → cjs}/libs/hook-api/index.js +12 -25
- package/dist/{js/node → cjs}/libs/hook-api/route.js +0 -0
- package/dist/{js/node → cjs}/libs/hook-api/template.js +0 -0
- package/dist/{js/node → cjs}/libs/loadConfig.js +6 -21
- package/dist/{js/node → cjs}/libs/logger.js +5 -16
- package/dist/{js/node → cjs}/libs/metrics.js +0 -0
- package/dist/{js/node → cjs}/libs/proxy.js +6 -39
- package/dist/{js/node → cjs}/libs/render/cache/__tests__/cache.fun.test.js +12 -34
- package/dist/{js/node → cjs}/libs/render/cache/__tests__/cache.test.js +43 -78
- package/dist/{js/node → cjs}/libs/render/cache/__tests__/cacheable.js +0 -0
- package/dist/{js/node → cjs}/libs/render/cache/__tests__/error-configuration.js +0 -0
- package/dist/{js/node → cjs}/libs/render/cache/__tests__/matched-cache.js +0 -0
- package/dist/cjs/libs/render/cache/index.js +97 -0
- package/dist/cjs/libs/render/cache/page-caches/index.js +33 -0
- package/dist/{js/node → cjs}/libs/render/cache/page-caches/lru.js +0 -0
- package/dist/{js/node → cjs}/libs/render/cache/spr.js +69 -97
- package/dist/{js/node → cjs}/libs/render/cache/type.js +0 -0
- package/dist/{js/node → cjs}/libs/render/cache/util.js +19 -41
- package/dist/cjs/libs/render/index.js +93 -0
- package/dist/{js/node → cjs}/libs/render/measure.js +6 -21
- package/dist/{js/node → cjs}/libs/render/reader.js +24 -46
- package/dist/{js/node → cjs}/libs/render/ssr.js +3 -23
- package/dist/{js/node → cjs}/libs/render/static.js +22 -44
- package/dist/{js/node → cjs}/libs/render/type.js +0 -0
- package/dist/{js/node → cjs}/libs/route/index.js +0 -0
- package/dist/{js/node → cjs}/libs/route/matcher.js +0 -0
- package/dist/{js/node → cjs}/libs/route/route.js +0 -0
- package/dist/{js/node → cjs}/libs/serve-file.js +2 -22
- package/dist/{js/node → cjs}/server/index.js +56 -106
- package/dist/{js/node → cjs}/server/modern-server-split.js +9 -40
- package/dist/cjs/server/modern-server.js +490 -0
- package/dist/{js/node → cjs}/type.js +0 -0
- package/dist/{js/node → cjs}/utils.js +1 -15
- package/dist/{js/node → cjs}/worker-server.js +3 -23
- package/dist/{js/treeshaking → esm}/constants.js +0 -0
- package/dist/{js/treeshaking → esm}/index.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/context/context.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/context/index.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/hook-api/index.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/hook-api/route.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/hook-api/template.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/loadConfig.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/logger.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/metrics.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/proxy.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/__tests__/cache.fun.test.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/__tests__/cache.test.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/__tests__/cacheable.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/__tests__/error-configuration.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/__tests__/matched-cache.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/index.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/page-caches/index.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/page-caches/lru.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/spr.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/type.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/cache/util.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/index.js +4 -3
- package/dist/{js/treeshaking → esm}/libs/render/measure.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/reader.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/ssr.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/static.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/render/type.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/route/index.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/route/matcher.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/route/route.js +0 -0
- package/dist/{js/treeshaking → esm}/libs/serve-file.js +0 -0
- package/dist/{js/treeshaking → esm}/server/index.js +0 -0
- package/dist/{js/treeshaking → esm}/server/modern-server-split.js +0 -0
- package/dist/{js/treeshaking → esm}/server/modern-server.js +14 -8
- package/dist/{js/treeshaking → esm}/type.js +0 -0
- package/dist/{js/treeshaking → esm}/utils.js +0 -0
- package/dist/{js/treeshaking → esm}/worker-server.js +0 -0
- package/dist/{js/modern → esm-node}/constants.js +0 -0
- package/dist/{js/modern → esm-node}/index.js +0 -0
- package/dist/{js/modern → esm-node}/libs/context/context.js +0 -0
- package/dist/{js/modern → esm-node}/libs/context/index.js +0 -0
- package/dist/{js/modern → esm-node}/libs/hook-api/index.js +12 -27
- package/dist/{js/modern → esm-node}/libs/hook-api/route.js +0 -0
- package/dist/{js/modern → esm-node}/libs/hook-api/template.js +0 -0
- package/dist/esm-node/libs/loadConfig.js +45 -0
- package/dist/{js/modern → esm-node}/libs/logger.js +5 -18
- package/dist/{js/modern → esm-node}/libs/metrics.js +0 -0
- package/dist/{js/modern → esm-node}/libs/proxy.js +6 -41
- package/dist/esm-node/libs/render/cache/__tests__/cache.fun.test.js +83 -0
- package/dist/esm-node/libs/render/cache/__tests__/cache.test.js +210 -0
- package/dist/{js/modern → esm-node}/libs/render/cache/__tests__/cacheable.js +0 -0
- package/dist/{js/modern → esm-node}/libs/render/cache/__tests__/error-configuration.js +0 -0
- package/dist/{js/modern → esm-node}/libs/render/cache/__tests__/matched-cache.js +0 -0
- package/dist/esm-node/libs/render/cache/index.js +76 -0
- package/dist/esm-node/libs/render/cache/page-caches/index.js +10 -0
- package/dist/{js/modern → esm-node}/libs/render/cache/page-caches/lru.js +0 -0
- package/dist/{js/modern → esm-node}/libs/render/cache/spr.js +69 -97
- package/dist/{js/modern → esm-node}/libs/render/cache/type.js +0 -0
- package/dist/{js/modern → esm-node}/libs/render/cache/util.js +19 -41
- package/dist/esm-node/libs/render/index.js +64 -0
- package/dist/{js/modern → esm-node}/libs/render/measure.js +6 -23
- package/dist/esm-node/libs/render/reader.js +85 -0
- package/dist/{js/modern → esm-node}/libs/render/ssr.js +3 -23
- package/dist/esm-node/libs/render/static.js +38 -0
- package/dist/{js/modern → esm-node}/libs/render/type.js +0 -0
- package/dist/{js/modern → esm-node}/libs/route/index.js +0 -0
- package/dist/{js/modern → esm-node}/libs/route/matcher.js +0 -0
- package/dist/{js/modern → esm-node}/libs/route/route.js +0 -0
- package/dist/{js/modern → esm-node}/libs/serve-file.js +2 -22
- package/dist/esm-node/server/index.js +156 -0
- package/dist/esm-node/server/modern-server-split.js +43 -0
- package/dist/esm-node/server/modern-server.js +483 -0
- package/dist/{js/modern → esm-node}/type.js +0 -0
- package/dist/{js/modern → esm-node}/utils.js +1 -17
- package/dist/{js/modern → esm-node}/worker-server.js +3 -23
- package/dist/types/libs/context/context.d.ts +1 -1
- package/dist/types/libs/render/index.d.ts +3 -1
- package/dist/types/utils.d.ts +1 -1
- package/package.json +15 -16
- package/dist/js/modern/libs/loadConfig.js +0 -62
- package/dist/js/modern/libs/render/cache/__tests__/cache.fun.test.js +0 -114
- package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +0 -254
- package/dist/js/modern/libs/render/cache/index.js +0 -115
- package/dist/js/modern/libs/render/cache/page-caches/index.js +0 -32
- package/dist/js/modern/libs/render/index.js +0 -84
- package/dist/js/modern/libs/render/reader.js +0 -107
- package/dist/js/modern/libs/render/static.js +0 -60
- package/dist/js/modern/server/index.js +0 -208
- package/dist/js/modern/server/modern-server-split.js +0 -74
- package/dist/js/modern/server/modern-server.js +0 -548
- package/dist/js/node/libs/render/cache/index.js +0 -134
- package/dist/js/node/libs/render/cache/page-caches/index.js +0 -55
- package/dist/js/node/libs/render/index.js +0 -113
- package/dist/js/node/server/modern-server.js +0 -553
|
@@ -257,7 +257,7 @@ var ModernServer = /*#__PURE__*/ function() {
|
|
|
257
257
|
value: function onInit(runner, app) {
|
|
258
258
|
var _this = this;
|
|
259
259
|
return _asyncToGenerator(function() {
|
|
260
|
-
var _conf_bff, distDir, staticGenerate, conf, usageRoutes, staticPathRegExp;
|
|
260
|
+
var _conf_bff, _this_conf_server, distDir, staticGenerate, conf, usageRoutes, staticPathRegExp, ssrConfig, forceCSR;
|
|
261
261
|
return __generator(this, function(_state) {
|
|
262
262
|
switch(_state.label){
|
|
263
263
|
case 0:
|
|
@@ -296,9 +296,12 @@ var ModernServer = /*#__PURE__*/ function() {
|
|
|
296
296
|
target: distDir
|
|
297
297
|
}
|
|
298
298
|
], _this.conf.output);
|
|
299
|
+
ssrConfig = (_this_conf_server = _this.conf.server) === null || _this_conf_server === void 0 ? void 0 : _this_conf_server.ssr;
|
|
300
|
+
forceCSR = typeof ssrConfig === "object" ? ssrConfig.forceCSR : false;
|
|
299
301
|
_this.routeRenderHandler = createRenderHandler({
|
|
300
302
|
distDir: distDir,
|
|
301
|
-
staticGenerate: staticGenerate
|
|
303
|
+
staticGenerate: staticGenerate,
|
|
304
|
+
forceCSR: forceCSR
|
|
302
305
|
});
|
|
303
306
|
return [
|
|
304
307
|
4,
|
|
@@ -393,8 +396,8 @@ var ModernServer = /*#__PURE__*/ function() {
|
|
|
393
396
|
return __generator(this, function(_state) {
|
|
394
397
|
switch(_state.label){
|
|
395
398
|
case 0:
|
|
396
|
-
req.logger = _this.logger;
|
|
397
|
-
req.metrics = _this.metrics;
|
|
399
|
+
req.logger = req.logger || _this.logger;
|
|
400
|
+
req.metrics = req.metrics || _this.metrics;
|
|
398
401
|
context = createContext(req, res);
|
|
399
402
|
matched = _this.router.match(url || context.path);
|
|
400
403
|
if (!matched) {
|
|
@@ -606,7 +609,8 @@ var ModernServer = /*#__PURE__*/ function() {
|
|
|
606
609
|
runner.prepareApiServer({
|
|
607
610
|
pwd: workDir,
|
|
608
611
|
config: extension,
|
|
609
|
-
prefix: Array.isArray(prefix) ? prefix[0] : prefix
|
|
612
|
+
prefix: Array.isArray(prefix) ? prefix[0] : prefix,
|
|
613
|
+
render: _this.render.bind(_this)
|
|
610
614
|
}, {
|
|
611
615
|
onLast: function() {
|
|
612
616
|
return null;
|
|
@@ -715,7 +719,9 @@ var ModernServer = /*#__PURE__*/ function() {
|
|
|
715
719
|
var bundles = this.router.getBundles();
|
|
716
720
|
bundles.forEach(function(bundle) {
|
|
717
721
|
var filepath = path.join(distDir, bundle);
|
|
718
|
-
|
|
722
|
+
if (fs.existsSync(filepath)) {
|
|
723
|
+
require(filepath);
|
|
724
|
+
}
|
|
719
725
|
});
|
|
720
726
|
}
|
|
721
727
|
},
|
|
@@ -973,8 +979,8 @@ var ModernServer = /*#__PURE__*/ function() {
|
|
|
973
979
|
value: function requestHandler(req, res) {
|
|
974
980
|
var next = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : function() {};
|
|
975
981
|
res.statusCode = 200;
|
|
976
|
-
req.logger = this.logger;
|
|
977
|
-
req.metrics = this.metrics;
|
|
982
|
+
req.logger = req.logger || this.logger;
|
|
983
|
+
req.metrics = req.metrics || this.metrics;
|
|
978
984
|
var context;
|
|
979
985
|
try {
|
|
980
986
|
context = this.createContext(req, res);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __defProps = Object.defineProperties;
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
1
|
import cookie from "cookie";
|
|
21
2
|
import { RouteAPI } from "./route";
|
|
22
3
|
import { TemplateAPI } from "./template";
|
|
@@ -104,27 +85,31 @@ const base = (context) => {
|
|
|
104
85
|
};
|
|
105
86
|
const createAfterMatchContext = (context, entryName) => {
|
|
106
87
|
const baseContext = base(context);
|
|
107
|
-
return
|
|
88
|
+
return {
|
|
89
|
+
...baseContext,
|
|
108
90
|
router: new RouteAPI(entryName)
|
|
109
|
-
}
|
|
91
|
+
};
|
|
110
92
|
};
|
|
111
93
|
const createAfterRenderContext = (context, content) => {
|
|
112
94
|
const baseContext = base(context);
|
|
113
|
-
return
|
|
95
|
+
return {
|
|
96
|
+
...baseContext,
|
|
114
97
|
template: new TemplateAPI(content)
|
|
115
|
-
}
|
|
98
|
+
};
|
|
116
99
|
};
|
|
117
100
|
const createMiddlewareContext = (context) => {
|
|
118
101
|
const baseContext = base(context);
|
|
119
|
-
return
|
|
120
|
-
|
|
102
|
+
return {
|
|
103
|
+
...baseContext,
|
|
104
|
+
response: {
|
|
105
|
+
...baseContext.response,
|
|
121
106
|
locals: context.res.locals || {}
|
|
122
|
-
}
|
|
107
|
+
},
|
|
123
108
|
source: {
|
|
124
109
|
req: context.req,
|
|
125
110
|
res: context.res
|
|
126
111
|
}
|
|
127
|
-
}
|
|
112
|
+
};
|
|
128
113
|
};
|
|
129
114
|
export {
|
|
130
115
|
base,
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as path from "path";
|
|
2
|
+
import { compatRequire, fs, DEFAULT_SERVER_CONFIG } from "@modern-js/utils";
|
|
3
|
+
import mergeDeep from "merge-deep";
|
|
4
|
+
const getServerConfigPath = (distDirectory, serverConfigFile = DEFAULT_SERVER_CONFIG) => {
|
|
5
|
+
const serverConfigPath = path.join(distDirectory, serverConfigFile);
|
|
6
|
+
return `${serverConfigPath}.js`;
|
|
7
|
+
};
|
|
8
|
+
const requireConfig = (serverConfigPath) => {
|
|
9
|
+
if (fs.pathExistsSync(serverConfigPath)) {
|
|
10
|
+
return compatRequire(serverConfigPath);
|
|
11
|
+
}
|
|
12
|
+
return {};
|
|
13
|
+
};
|
|
14
|
+
const loadConfig = ({
|
|
15
|
+
cliConfig,
|
|
16
|
+
serverConfig,
|
|
17
|
+
resolvedConfigPath
|
|
18
|
+
}) => {
|
|
19
|
+
let config = null;
|
|
20
|
+
if (process.env.NODE_ENV === "production") {
|
|
21
|
+
const resolvedConfig = requireConfig(resolvedConfigPath);
|
|
22
|
+
config = mergeDeep(
|
|
23
|
+
{
|
|
24
|
+
...resolvedConfig,
|
|
25
|
+
plugins: []
|
|
26
|
+
},
|
|
27
|
+
serverConfig,
|
|
28
|
+
cliConfig
|
|
29
|
+
);
|
|
30
|
+
} else {
|
|
31
|
+
config = mergeDeep(
|
|
32
|
+
{
|
|
33
|
+
...cliConfig,
|
|
34
|
+
plugins: []
|
|
35
|
+
},
|
|
36
|
+
serverConfig
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return config;
|
|
40
|
+
};
|
|
41
|
+
export {
|
|
42
|
+
getServerConfigPath,
|
|
43
|
+
loadConfig,
|
|
44
|
+
requireConfig
|
|
45
|
+
};
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
-
var __spreadValues = (a, b) => {
|
|
7
|
-
for (var prop in b || (b = {}))
|
|
8
|
-
if (__hasOwnProp.call(b, prop))
|
|
9
|
-
__defNormalProp(a, prop, b[prop]);
|
|
10
|
-
if (__getOwnPropSymbols)
|
|
11
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
-
if (__propIsEnum.call(b, prop))
|
|
13
|
-
__defNormalProp(a, prop, b[prop]);
|
|
14
|
-
}
|
|
15
|
-
return a;
|
|
16
|
-
};
|
|
17
1
|
const LOG_LEVEL = {
|
|
18
2
|
error: 0,
|
|
19
3
|
warn: 1,
|
|
@@ -56,8 +40,11 @@ const DEFAULT_CONFIG = {
|
|
|
56
40
|
class Logger {
|
|
57
41
|
constructor(options = {}) {
|
|
58
42
|
this.level = options.level || LOG_TYPES.log.level;
|
|
59
|
-
this.config =
|
|
60
|
-
this.types =
|
|
43
|
+
this.config = { ...DEFAULT_CONFIG, ...options.config || {} };
|
|
44
|
+
this.types = {
|
|
45
|
+
...LOG_TYPES,
|
|
46
|
+
...options.types || {}
|
|
47
|
+
};
|
|
61
48
|
this.longestLabel = this.getLongestLabel();
|
|
62
49
|
Object.keys(this.types).forEach((type) => {
|
|
63
50
|
this[type] = this._log.bind(this, type);
|
|
File without changes
|
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
-
var __spreadValues = (a, b) => {
|
|
7
|
-
for (var prop in b || (b = {}))
|
|
8
|
-
if (__hasOwnProp.call(b, prop))
|
|
9
|
-
__defNormalProp(a, prop, b[prop]);
|
|
10
|
-
if (__getOwnPropSymbols)
|
|
11
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
-
if (__propIsEnum.call(b, prop))
|
|
13
|
-
__defNormalProp(a, prop, b[prop]);
|
|
14
|
-
}
|
|
15
|
-
return a;
|
|
16
|
-
};
|
|
17
|
-
var __async = (__this, __arguments, generator) => {
|
|
18
|
-
return new Promise((resolve, reject) => {
|
|
19
|
-
var fulfilled = (value) => {
|
|
20
|
-
try {
|
|
21
|
-
step(generator.next(value));
|
|
22
|
-
} catch (e) {
|
|
23
|
-
reject(e);
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
var rejected = (value) => {
|
|
27
|
-
try {
|
|
28
|
-
step(generator.throw(value));
|
|
29
|
-
} catch (e) {
|
|
30
|
-
reject(e);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
34
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
35
|
-
});
|
|
36
|
-
};
|
|
37
1
|
import { createProxyMiddleware } from "http-proxy-middleware";
|
|
38
2
|
import { debug } from "../utils";
|
|
39
3
|
function formatProxyOptions(proxyOptions) {
|
|
@@ -47,11 +11,12 @@ function formatProxyOptions(proxyOptions) {
|
|
|
47
11
|
Object.keys(proxyOptions).reduce(
|
|
48
12
|
(total, source) => {
|
|
49
13
|
const option = proxyOptions[source];
|
|
50
|
-
total.push(
|
|
14
|
+
total.push({
|
|
51
15
|
context: source,
|
|
52
16
|
changeOrigin: true,
|
|
53
|
-
logLevel: "warn"
|
|
54
|
-
|
|
17
|
+
logLevel: "warn",
|
|
18
|
+
...typeof option === "string" ? { target: option } : option
|
|
19
|
+
});
|
|
55
20
|
return total;
|
|
56
21
|
},
|
|
57
22
|
[]
|
|
@@ -71,7 +36,7 @@ const createProxyHandler = (proxyOptions) => {
|
|
|
71
36
|
const formattedProxy = formatProxyOptions(proxyOptions);
|
|
72
37
|
const middlewares = formattedProxy.map((option) => {
|
|
73
38
|
const middleware = createProxyMiddleware(option.context, option);
|
|
74
|
-
return (ctx, next) =>
|
|
39
|
+
return async (ctx, next) => {
|
|
75
40
|
const { req, res } = ctx;
|
|
76
41
|
const bypassUrl = typeof option.bypass === "function" ? option.bypass(req, res, option) : null;
|
|
77
42
|
if (typeof bypassUrl === "boolean") {
|
|
@@ -82,7 +47,7 @@ const createProxyHandler = (proxyOptions) => {
|
|
|
82
47
|
return next();
|
|
83
48
|
}
|
|
84
49
|
middleware(req, res, next);
|
|
85
|
-
}
|
|
50
|
+
};
|
|
86
51
|
});
|
|
87
52
|
return middlewares;
|
|
88
53
|
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import url from "url";
|
|
2
|
+
import { createCache, destroyCache } from "../spr";
|
|
3
|
+
import {
|
|
4
|
+
cacheAddition,
|
|
5
|
+
connectFactor,
|
|
6
|
+
fname,
|
|
7
|
+
maybeSync,
|
|
8
|
+
namespaceHash,
|
|
9
|
+
valueFactory,
|
|
10
|
+
withCoalescedInvoke
|
|
11
|
+
} from "../util";
|
|
12
|
+
describe("test spr util functions", () => {
|
|
13
|
+
it("should return value correctly", () => {
|
|
14
|
+
expect(connectFactor("bar", "foo")).toBe("bar-foo");
|
|
15
|
+
expect(fname(1)).toBe("f1");
|
|
16
|
+
expect(namespaceHash("modern", "!@#$%^&")).toBe("modern/!@#$%^&");
|
|
17
|
+
});
|
|
18
|
+
it("should create or destroy instance correctly", () => {
|
|
19
|
+
const ins1 = createCache();
|
|
20
|
+
const ins2 = createCache();
|
|
21
|
+
expect(ins1 === ins2).toBe(true);
|
|
22
|
+
destroyCache();
|
|
23
|
+
const ins3 = createCache();
|
|
24
|
+
expect(ins1 === ins3).toBe(false);
|
|
25
|
+
expect(ins2 === ins3).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
it("should return function correctly", () => {
|
|
28
|
+
const urlParams = (() => new url.URLSearchParams())();
|
|
29
|
+
urlParams.set("name", "modern");
|
|
30
|
+
const getParam = valueFactory(urlParams);
|
|
31
|
+
expect(getParam("name")).toBe("modern");
|
|
32
|
+
const headers = { age: "12345" };
|
|
33
|
+
const getHeader = valueFactory(headers);
|
|
34
|
+
expect(getHeader("age")).toBe("12345");
|
|
35
|
+
});
|
|
36
|
+
it("should add target html content", () => {
|
|
37
|
+
const contentNoHead = "<div>123</div>";
|
|
38
|
+
const html = cacheAddition(contentNoHead, Math.random().toString());
|
|
39
|
+
expect(html).toBe(contentNoHead);
|
|
40
|
+
const contentWithHead = "<head></head><div>123</div>";
|
|
41
|
+
const hash = Math.random().toString();
|
|
42
|
+
const htmlWithHead = cacheAddition(contentWithHead, hash);
|
|
43
|
+
expect(htmlWithHead).toBe(
|
|
44
|
+
`<head><meta name="x-moden-spr" content="${hash}"></head><div>123</div>`
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
it("should only invoke func one time", async () => {
|
|
48
|
+
let index = 0;
|
|
49
|
+
const fn = withCoalescedInvoke(
|
|
50
|
+
async () => new Promise((resolve) => {
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
index += 1;
|
|
53
|
+
resolve(index);
|
|
54
|
+
}, 500);
|
|
55
|
+
})
|
|
56
|
+
);
|
|
57
|
+
const key = "test";
|
|
58
|
+
const [res1, res2] = await Promise.all([fn(key, []), fn(key, [])]);
|
|
59
|
+
expect(res1.isOrigin && res2.isOrigin).toBe(false);
|
|
60
|
+
expect(res1.isOrigin || res2.isOrigin).toBe(true);
|
|
61
|
+
expect(res1.value).toBe(1);
|
|
62
|
+
expect(res2.value).toBe(1);
|
|
63
|
+
});
|
|
64
|
+
it("should invoke sync or async", async () => {
|
|
65
|
+
const foo = "";
|
|
66
|
+
const async = await maybeSync(
|
|
67
|
+
() => new Promise((resolve) => {
|
|
68
|
+
setTimeout(() => {
|
|
69
|
+
resolve(foo);
|
|
70
|
+
}, 100);
|
|
71
|
+
})
|
|
72
|
+
)(false);
|
|
73
|
+
expect(async).toBeUndefined();
|
|
74
|
+
const sync = await maybeSync(
|
|
75
|
+
() => new Promise((resolve) => {
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
resolve(foo);
|
|
78
|
+
}, 100);
|
|
79
|
+
})
|
|
80
|
+
)(true);
|
|
81
|
+
expect(sync).toBe(foo);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { createCache, destroyCache } from "../spr";
|
|
2
|
+
import { errorConfiguration } from "./error-configuration";
|
|
3
|
+
import { cacheabelAry } from "./cacheable";
|
|
4
|
+
import { matchedCacheableAry } from "./matched-cache";
|
|
5
|
+
const createCacheConfig = (config = {}) => ({
|
|
6
|
+
excludes: null,
|
|
7
|
+
includes: null,
|
|
8
|
+
interval: 10,
|
|
9
|
+
staleLimit: false,
|
|
10
|
+
level: 0,
|
|
11
|
+
fallback: false,
|
|
12
|
+
matches: null,
|
|
13
|
+
...config
|
|
14
|
+
});
|
|
15
|
+
jest.setTimeout(6e4);
|
|
16
|
+
describe("cache", () => {
|
|
17
|
+
it("should cache correctly", async () => {
|
|
18
|
+
destroyCache();
|
|
19
|
+
const cache = createCache();
|
|
20
|
+
const context = {
|
|
21
|
+
entry: "",
|
|
22
|
+
pathname: "",
|
|
23
|
+
query: {},
|
|
24
|
+
headers: {}
|
|
25
|
+
};
|
|
26
|
+
const content = "hello";
|
|
27
|
+
const cacheConfig = createCacheConfig();
|
|
28
|
+
await cache.set(context, content, cacheConfig, true);
|
|
29
|
+
const cacheResult = await cache.get(context);
|
|
30
|
+
expect(cacheResult).not.toBe(null);
|
|
31
|
+
expect(cacheResult == null ? void 0 : cacheResult.content).toBe("hello");
|
|
32
|
+
});
|
|
33
|
+
it("should ignore cache set when cache config not exist", async () => {
|
|
34
|
+
destroyCache();
|
|
35
|
+
destroyCache();
|
|
36
|
+
const cache = createCache();
|
|
37
|
+
const context = {
|
|
38
|
+
entry: "",
|
|
39
|
+
pathname: "",
|
|
40
|
+
query: {},
|
|
41
|
+
headers: {}
|
|
42
|
+
};
|
|
43
|
+
const content = "hello";
|
|
44
|
+
const shouldCache = await cache.set(context, content, null, true);
|
|
45
|
+
expect(shouldCache).toBe(false);
|
|
46
|
+
});
|
|
47
|
+
it("should calcual cache key error", async () => {
|
|
48
|
+
destroyCache();
|
|
49
|
+
const cache = createCache();
|
|
50
|
+
const content = "hello";
|
|
51
|
+
for (const config of errorConfiguration) {
|
|
52
|
+
const cacheConfig = createCacheConfig(config);
|
|
53
|
+
const tmpEntry = Math.random().toString();
|
|
54
|
+
const context = {
|
|
55
|
+
entry: tmpEntry,
|
|
56
|
+
pathname: "",
|
|
57
|
+
query: {},
|
|
58
|
+
headers: {}
|
|
59
|
+
};
|
|
60
|
+
const shouldCache = await cache.set(context, content, cacheConfig);
|
|
61
|
+
expect(shouldCache).toBe(false);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
it("should get nothing for diff requestKey", async () => {
|
|
65
|
+
destroyCache();
|
|
66
|
+
const cache = createCache();
|
|
67
|
+
const context = {
|
|
68
|
+
entry: "",
|
|
69
|
+
pathname: "",
|
|
70
|
+
query: {},
|
|
71
|
+
headers: {}
|
|
72
|
+
};
|
|
73
|
+
const content = "hello";
|
|
74
|
+
const cacheConfig = createCacheConfig({
|
|
75
|
+
level: 1,
|
|
76
|
+
includes: { query: ["name"] }
|
|
77
|
+
});
|
|
78
|
+
await cache.set(context, content, cacheConfig, true);
|
|
79
|
+
const context_req = {
|
|
80
|
+
entry: "",
|
|
81
|
+
pathname: "/home",
|
|
82
|
+
query: {},
|
|
83
|
+
headers: {}
|
|
84
|
+
};
|
|
85
|
+
const cacheResult = await cache.get(context_req);
|
|
86
|
+
expect(cacheResult).toBe(null);
|
|
87
|
+
});
|
|
88
|
+
it("should get nothing for diff cacheHash", async () => {
|
|
89
|
+
destroyCache();
|
|
90
|
+
const cache = createCache();
|
|
91
|
+
const context = {
|
|
92
|
+
entry: "",
|
|
93
|
+
pathname: "",
|
|
94
|
+
query: {},
|
|
95
|
+
headers: {}
|
|
96
|
+
};
|
|
97
|
+
const content = "hello";
|
|
98
|
+
const cacheConfig = createCacheConfig({
|
|
99
|
+
level: 1,
|
|
100
|
+
includes: { query: ["name"] }
|
|
101
|
+
});
|
|
102
|
+
await cache.set(context, content, cacheConfig, true);
|
|
103
|
+
const context_req = {
|
|
104
|
+
entry: "",
|
|
105
|
+
pathname: "",
|
|
106
|
+
query: { name: "zll" },
|
|
107
|
+
headers: {}
|
|
108
|
+
};
|
|
109
|
+
const cacheResult = await cache.get(context_req);
|
|
110
|
+
expect(cacheResult).toBe(null);
|
|
111
|
+
});
|
|
112
|
+
it("should get cache correctly", async () => {
|
|
113
|
+
destroyCache();
|
|
114
|
+
const cache = createCache();
|
|
115
|
+
for (const cacheable of cacheabelAry) {
|
|
116
|
+
const context = {
|
|
117
|
+
entry: "",
|
|
118
|
+
pathname: cacheable.requestOpt.url,
|
|
119
|
+
query: cacheable.requestOpt.query || {},
|
|
120
|
+
headers: cacheable.requestOpt.headers || {}
|
|
121
|
+
};
|
|
122
|
+
const cacheConfig = createCacheConfig(cacheable.cacheConfig || {});
|
|
123
|
+
await cache.set(context, cacheable.content, cacheConfig, true);
|
|
124
|
+
const cacheResult = await cache.get(context);
|
|
125
|
+
expect(cacheResult == null ? void 0 : cacheResult.content).toBe(cacheable.content);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
it("should match cache correctly", async () => {
|
|
129
|
+
destroyCache();
|
|
130
|
+
const cache = createCache();
|
|
131
|
+
for (const cacheable of matchedCacheableAry) {
|
|
132
|
+
const [baseCacheable, matchOne, ...other] = cacheable;
|
|
133
|
+
const { requestOpt = {}, cacheConfig, content } = baseCacheable;
|
|
134
|
+
const context = {
|
|
135
|
+
entry: "",
|
|
136
|
+
pathname: requestOpt.url,
|
|
137
|
+
query: requestOpt.query,
|
|
138
|
+
headers: requestOpt.headers
|
|
139
|
+
};
|
|
140
|
+
await cache.set(context, content, createCacheConfig(cacheConfig), true);
|
|
141
|
+
const matchContext = {
|
|
142
|
+
entry: "",
|
|
143
|
+
pathname: matchOne.url,
|
|
144
|
+
query: matchOne.query,
|
|
145
|
+
headers: matchOne.headers
|
|
146
|
+
};
|
|
147
|
+
const cacheResult = await cache.get(matchContext);
|
|
148
|
+
expect(cacheResult == null ? void 0 : cacheResult.content).toBe(content);
|
|
149
|
+
for (const notMatch of other) {
|
|
150
|
+
const notMatchContext = {
|
|
151
|
+
entry: "",
|
|
152
|
+
pathname: notMatch.url,
|
|
153
|
+
query: notMatch.query,
|
|
154
|
+
headers: notMatch.headers
|
|
155
|
+
};
|
|
156
|
+
const nothing = await cache.get(notMatchContext);
|
|
157
|
+
expect(nothing).toBe(null);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
it("should stale cache correctly", async () => {
|
|
162
|
+
destroyCache();
|
|
163
|
+
const cache = createCache();
|
|
164
|
+
const context = {
|
|
165
|
+
entry: "",
|
|
166
|
+
pathname: "",
|
|
167
|
+
query: {},
|
|
168
|
+
headers: {}
|
|
169
|
+
};
|
|
170
|
+
const config = createCacheConfig({ interval: 5 });
|
|
171
|
+
const content = "hello";
|
|
172
|
+
const shouldCache = await cache.set(context, content, config, true);
|
|
173
|
+
expect(shouldCache.value).toBe(true);
|
|
174
|
+
const freshResult = await cache.get(context);
|
|
175
|
+
expect(freshResult == null ? void 0 : freshResult.isStale).toBe(false);
|
|
176
|
+
await new Promise((resolve) => {
|
|
177
|
+
setTimeout(() => {
|
|
178
|
+
resolve();
|
|
179
|
+
}, 6e3);
|
|
180
|
+
});
|
|
181
|
+
const staleResult = await cache.get(context);
|
|
182
|
+
expect(staleResult == null ? void 0 : staleResult.isStale).toBe(true);
|
|
183
|
+
});
|
|
184
|
+
it("should garbage cache correctly", async () => {
|
|
185
|
+
destroyCache();
|
|
186
|
+
const cache = createCache();
|
|
187
|
+
const context = {
|
|
188
|
+
entry: "",
|
|
189
|
+
pathname: "",
|
|
190
|
+
query: {},
|
|
191
|
+
headers: {}
|
|
192
|
+
};
|
|
193
|
+
const config = createCacheConfig({
|
|
194
|
+
interval: 3,
|
|
195
|
+
staleLimit: 8
|
|
196
|
+
});
|
|
197
|
+
const content = "hello";
|
|
198
|
+
const shouldCache = await cache.set(context, content, config, true);
|
|
199
|
+
expect(shouldCache.value).toBe(true);
|
|
200
|
+
const freshResult = await cache.get(context);
|
|
201
|
+
expect(freshResult == null ? void 0 : freshResult.isGarbage).toBe(false);
|
|
202
|
+
await new Promise((resolve) => {
|
|
203
|
+
setTimeout(() => {
|
|
204
|
+
resolve();
|
|
205
|
+
}, 1e4);
|
|
206
|
+
});
|
|
207
|
+
const staleResult = await cache.get(context);
|
|
208
|
+
expect(staleResult == null ? void 0 : staleResult.isGarbage).toBe(true);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Transform } from "stream";
|
|
2
|
+
import { ERROR_DIGEST } from "../../../constants";
|
|
3
|
+
import { createCache } from "./spr";
|
|
4
|
+
import { namespaceHash, withCoalescedInvoke } from "./util";
|
|
5
|
+
var cache_default = (renderFn, ctx) => {
|
|
6
|
+
const sprCache = createCache();
|
|
7
|
+
const doRender = async (context) => {
|
|
8
|
+
const cacheContext = {
|
|
9
|
+
entry: context.entryName,
|
|
10
|
+
...context.request
|
|
11
|
+
};
|
|
12
|
+
const cacheFile = await sprCache.get(cacheContext);
|
|
13
|
+
async function afterRender(source, onAfterRender) {
|
|
14
|
+
if (!source) {
|
|
15
|
+
return "";
|
|
16
|
+
}
|
|
17
|
+
if (typeof source === "string") {
|
|
18
|
+
await onAfterRender(source);
|
|
19
|
+
return source;
|
|
20
|
+
} else {
|
|
21
|
+
let htmlForStream = "";
|
|
22
|
+
const cacheStream = new Transform({
|
|
23
|
+
write(chunk, _, callback) {
|
|
24
|
+
htmlForStream += chunk.toString();
|
|
25
|
+
this.push(chunk);
|
|
26
|
+
callback();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
cacheStream.on("close", () => onAfterRender(htmlForStream));
|
|
30
|
+
return source(cacheStream);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function saveHtmlIntoCache(html) {
|
|
34
|
+
const { cacheConfig } = context;
|
|
35
|
+
if (html && cacheConfig) {
|
|
36
|
+
await sprCache.set(cacheContext, html, cacheConfig);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!cacheFile) {
|
|
40
|
+
const renderResult = await renderFn(context);
|
|
41
|
+
return afterRender(renderResult, saveHtmlIntoCache);
|
|
42
|
+
}
|
|
43
|
+
const cacheHash = cacheFile == null ? void 0 : cacheFile.hash;
|
|
44
|
+
if (cacheFile.isGarbage) {
|
|
45
|
+
const renderResult = await renderFn(context);
|
|
46
|
+
return afterRender(renderResult, saveHtmlIntoCache);
|
|
47
|
+
} else if (cacheFile.isStale) {
|
|
48
|
+
const render = withCoalescedInvoke(() => renderFn(context)).bind(
|
|
49
|
+
null,
|
|
50
|
+
namespaceHash("render", cacheFile.hash),
|
|
51
|
+
[]
|
|
52
|
+
);
|
|
53
|
+
render().then(async (res) => {
|
|
54
|
+
if (res.value && res.isOrigin) {
|
|
55
|
+
const { cacheConfig } = context;
|
|
56
|
+
if (cacheConfig) {
|
|
57
|
+
afterRender(res.value, async (html) => {
|
|
58
|
+
sprCache.set(cacheContext, html, cacheConfig);
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
sprCache.del(cacheContext, cacheHash);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}).catch((e) => {
|
|
65
|
+
sprCache.del(cacheContext, cacheHash);
|
|
66
|
+
ctx.error(ERROR_DIGEST.ERENDER, e);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
ctx.res.setHeader("x-modern-spr", "1");
|
|
70
|
+
return cacheFile.content;
|
|
71
|
+
};
|
|
72
|
+
return doRender;
|
|
73
|
+
};
|
|
74
|
+
export {
|
|
75
|
+
cache_default as default
|
|
76
|
+
};
|