@modern-js/prod-server 2.0.0-beta.0 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/dist/js/modern/constants.js +0 -2
- package/dist/js/modern/index.js +0 -1
- package/dist/js/modern/libs/context/context.js +10 -56
- package/dist/js/modern/libs/hook-api/index.js +0 -31
- package/dist/js/modern/libs/hook-api/route.js +0 -8
- package/dist/js/modern/libs/hook-api/template.js +0 -16
- package/dist/js/modern/libs/loadConfig.js +3 -10
- package/dist/js/modern/libs/metrics.js +6 -6
- package/dist/js/modern/libs/proxy.js +7 -12
- package/dist/js/modern/libs/render/cache/__tests__/cache.fun.test.js +0 -1
- package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +0 -9
- package/dist/js/modern/libs/render/cache/index.js +8 -16
- package/dist/js/modern/libs/render/cache/page-caches/lru.js +0 -10
- package/dist/js/modern/libs/render/cache/spr.js +12 -62
- package/dist/js/modern/libs/render/cache/util.js +0 -6
- package/dist/js/modern/libs/render/index.js +6 -11
- package/dist/js/modern/libs/render/measure.js +1 -11
- package/dist/js/modern/libs/render/modern/index.js +2 -13
- package/dist/js/modern/libs/render/reader.js +13 -24
- package/dist/js/modern/libs/render/ssr.js +5 -6
- package/dist/js/modern/libs/render/static.js +6 -9
- package/dist/js/modern/libs/render/type.js +0 -1
- package/dist/js/modern/libs/route/index.js +8 -19
- package/dist/js/modern/libs/route/matcher.js +21 -29
- package/dist/js/modern/libs/route/route.js +0 -13
- package/dist/js/modern/libs/serve-file.js +5 -6
- package/dist/js/modern/server/index.js +19 -41
- package/dist/js/modern/server/modern-server-split.js +0 -11
- package/dist/js/modern/server/modern-server.js +83 -164
- package/dist/js/modern/utils.js +2 -21
- package/dist/js/modern/worker-server.js +34 -0
- package/dist/js/node/constants.js +0 -2
- package/dist/js/node/index.js +0 -10
- package/dist/js/node/libs/context/context.js +10 -65
- package/dist/js/node/libs/context/index.js +0 -3
- package/dist/js/node/libs/hook-api/index.js +0 -42
- package/dist/js/node/libs/hook-api/route.js +0 -10
- package/dist/js/node/libs/hook-api/template.js +0 -22
- package/dist/js/node/libs/loadConfig.js +3 -22
- package/dist/js/node/libs/metrics.js +6 -6
- package/dist/js/node/libs/proxy.js +7 -17
- package/dist/js/node/libs/render/cache/__tests__/cache.fun.test.js +0 -5
- package/dist/js/node/libs/render/cache/__tests__/cache.test.js +0 -12
- package/dist/js/node/libs/render/cache/index.js +8 -22
- package/dist/js/node/libs/render/cache/page-caches/index.js +0 -2
- package/dist/js/node/libs/render/cache/page-caches/lru.js +0 -14
- package/dist/js/node/libs/render/cache/spr.js +12 -71
- package/dist/js/node/libs/render/cache/util.js +0 -18
- package/dist/js/node/libs/render/index.js +6 -26
- package/dist/js/node/libs/render/measure.js +0 -17
- package/dist/js/node/libs/render/modern/index.js +2 -20
- package/dist/js/node/libs/render/reader.js +12 -39
- package/dist/js/node/libs/render/ssr.js +4 -16
- package/dist/js/node/libs/render/static.js +6 -18
- package/dist/js/node/libs/render/type.js +0 -1
- package/dist/js/node/libs/route/index.js +8 -22
- package/dist/js/node/libs/route/matcher.js +18 -34
- package/dist/js/node/libs/route/route.js +0 -15
- package/dist/js/node/libs/serve-file.js +5 -13
- package/dist/js/node/server/index.js +19 -61
- package/dist/js/node/server/modern-server-split.js +0 -13
- package/dist/js/node/server/modern-server.js +83 -193
- package/dist/js/node/utils.js +3 -46
- package/dist/js/node/worker-server.js +41 -0
- package/dist/js/treeshaking/constants.js +28 -0
- package/dist/js/treeshaking/index.js +13 -0
- package/dist/js/treeshaking/libs/context/context.js +243 -0
- package/dist/js/treeshaking/libs/context/index.js +5 -0
- package/dist/js/treeshaking/libs/hook-api/index.js +157 -0
- package/dist/js/treeshaking/libs/hook-api/route.js +33 -0
- package/dist/js/treeshaking/libs/hook-api/template.js +91 -0
- package/dist/js/treeshaking/libs/loadConfig.js +39 -0
- package/dist/js/treeshaking/libs/metrics.js +12 -0
- package/dist/js/treeshaking/libs/proxy.js +80 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/cache.fun.test.js +124 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/cache.test.js +464 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/cacheable.js +53 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/error-configuration.js +35 -0
- package/dist/js/treeshaking/libs/render/cache/__tests__/matched-cache.js +121 -0
- package/dist/js/treeshaking/libs/render/cache/index.js +184 -0
- package/dist/js/treeshaking/libs/render/cache/page-caches/index.js +30 -0
- package/dist/js/treeshaking/libs/render/cache/page-caches/lru.js +46 -0
- package/dist/js/treeshaking/libs/render/cache/spr.js +362 -0
- package/dist/js/treeshaking/libs/render/cache/type.js +1 -0
- package/dist/js/treeshaking/libs/render/cache/util.js +101 -0
- package/dist/js/treeshaking/libs/render/index.js +100 -0
- package/dist/js/treeshaking/libs/render/measure.js +61 -0
- package/dist/js/treeshaking/libs/render/modern/browser-list.js +7 -0
- package/dist/js/treeshaking/libs/render/modern/index.js +39 -0
- package/dist/js/treeshaking/libs/render/reader.js +191 -0
- package/dist/js/treeshaking/libs/render/ssr.js +98 -0
- package/dist/js/treeshaking/libs/render/static.js +84 -0
- package/dist/js/treeshaking/libs/render/type.js +6 -0
- package/dist/js/treeshaking/libs/route/index.js +94 -0
- package/dist/js/treeshaking/libs/route/matcher.js +113 -0
- package/dist/js/treeshaking/libs/route/route.js +26 -0
- package/dist/js/treeshaking/libs/serve-file.js +75 -0
- package/dist/js/treeshaking/server/index.js +343 -0
- package/dist/js/treeshaking/server/modern-server-split.js +152 -0
- package/dist/js/treeshaking/server/modern-server.js +945 -0
- package/dist/js/treeshaking/type.js +1 -0
- package/dist/js/treeshaking/utils.js +87 -0
- package/dist/js/treeshaking/worker-server.js +56 -0
- package/dist/types/index.d.ts +0 -2
- package/dist/types/libs/context/context.d.ts +0 -3
- package/dist/types/libs/loadConfig.d.ts +0 -1
- package/dist/types/libs/render/cache/index.d.ts +0 -2
- package/dist/types/libs/render/cache/spr.d.ts +0 -2
- package/dist/types/server/index.d.ts +0 -3
- package/dist/types/utils.d.ts +0 -1
- package/dist/types/worker-server.d.ts +16 -0
- package/package.json +28 -12
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
2
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
3
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
4
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
5
|
+
import url from 'url';
|
|
6
|
+
export function namespaceHash(namespace, hash) {
|
|
7
|
+
return "".concat(namespace, "/").concat(hash);
|
|
8
|
+
}
|
|
9
|
+
export function fname(lv) {
|
|
10
|
+
return "f".concat(lv);
|
|
11
|
+
}
|
|
12
|
+
export function connectFactor() {
|
|
13
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
14
|
+
args[_key] = arguments[_key];
|
|
15
|
+
}
|
|
16
|
+
return args.join('-');
|
|
17
|
+
}
|
|
18
|
+
export function valueFactory(obj) {
|
|
19
|
+
if (obj instanceof url.URLSearchParams) {
|
|
20
|
+
return function (key) {
|
|
21
|
+
return obj.get(key);
|
|
22
|
+
};
|
|
23
|
+
} else {
|
|
24
|
+
return function (key) {
|
|
25
|
+
var value = obj[key];
|
|
26
|
+
if (Array.isArray(value)) {
|
|
27
|
+
return value.join(',');
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function getTime(_ref) {
|
|
34
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
35
|
+
s = _ref2[0],
|
|
36
|
+
ns = _ref2[1];
|
|
37
|
+
return Math.floor(s * 1e3 + ns / 1e6);
|
|
38
|
+
}
|
|
39
|
+
var RE_START_IN_HEAD = /<head>/;
|
|
40
|
+
export function cacheAddition(html, hash) {
|
|
41
|
+
var additionHtml = html.replace(RE_START_IN_HEAD, "<head><meta name=\"x-moden-spr\" content=\"".concat(hash, "\">"));
|
|
42
|
+
return additionHtml;
|
|
43
|
+
}
|
|
44
|
+
var globalInvokeCache = new Map();
|
|
45
|
+
export function withCoalescedInvoke(func) {
|
|
46
|
+
return /*#__PURE__*/function () {
|
|
47
|
+
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(key, args) {
|
|
48
|
+
var entry, __wrapper, future;
|
|
49
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
50
|
+
while (1) {
|
|
51
|
+
switch (_context.prev = _context.next) {
|
|
52
|
+
case 0:
|
|
53
|
+
__wrapper = function _wrapper() {
|
|
54
|
+
return func.apply(void 0, _toConsumableArray(args));
|
|
55
|
+
};
|
|
56
|
+
entry = globalInvokeCache.get(key);
|
|
57
|
+
if (!entry) {
|
|
58
|
+
_context.next = 4;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
return _context.abrupt("return", entry.then(function (res) {
|
|
62
|
+
return {
|
|
63
|
+
isOrigin: false,
|
|
64
|
+
value: res.value
|
|
65
|
+
};
|
|
66
|
+
}));
|
|
67
|
+
case 4:
|
|
68
|
+
future = __wrapper().then(function (res) {
|
|
69
|
+
globalInvokeCache["delete"](key);
|
|
70
|
+
return {
|
|
71
|
+
isOrigin: true,
|
|
72
|
+
value: res
|
|
73
|
+
};
|
|
74
|
+
})["catch"](function (err) {
|
|
75
|
+
globalInvokeCache["delete"](key);
|
|
76
|
+
throw err;
|
|
77
|
+
});
|
|
78
|
+
globalInvokeCache.set(key, future);
|
|
79
|
+
return _context.abrupt("return", future);
|
|
80
|
+
case 7:
|
|
81
|
+
case "end":
|
|
82
|
+
return _context.stop();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, _callee);
|
|
86
|
+
}));
|
|
87
|
+
return function (_x, _x2) {
|
|
88
|
+
return _ref3.apply(this, arguments);
|
|
89
|
+
};
|
|
90
|
+
}();
|
|
91
|
+
}
|
|
92
|
+
export function maybeSync(fn) {
|
|
93
|
+
return function (sync) {
|
|
94
|
+
if (sync) {
|
|
95
|
+
return fn();
|
|
96
|
+
} else {
|
|
97
|
+
fn();
|
|
98
|
+
return Promise.resolve();
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fs, mime } from '@modern-js/utils';
|
|
5
|
+
import { ERROR_DIGEST } from "../../constants";
|
|
6
|
+
import { handleDirectory } from "./static";
|
|
7
|
+
import { readFile } from "./reader";
|
|
8
|
+
import * as ssr from "./ssr";
|
|
9
|
+
import { supportModern, getModernEntry } from "./modern";
|
|
10
|
+
export var createRenderHandler = function createRenderHandler(_ref) {
|
|
11
|
+
var distDir = _ref.distDir,
|
|
12
|
+
staticGenerate = _ref.staticGenerate;
|
|
13
|
+
return /*#__PURE__*/function () {
|
|
14
|
+
var _render = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref2) {
|
|
15
|
+
var ctx, route, runner, entryPath, urlPath, entry, result, modernEntry, useModern, templatePath, content, _result;
|
|
16
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
17
|
+
while (1) {
|
|
18
|
+
switch (_context.prev = _context.next) {
|
|
19
|
+
case 0:
|
|
20
|
+
ctx = _ref2.ctx, route = _ref2.route, runner = _ref2.runner;
|
|
21
|
+
if (!ctx.resHasHandled()) {
|
|
22
|
+
_context.next = 3;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
return _context.abrupt("return", null);
|
|
26
|
+
case 3:
|
|
27
|
+
entryPath = route.entryPath, urlPath = route.urlPath;
|
|
28
|
+
entry = path.join(distDir, entryPath);
|
|
29
|
+
if (route.isSPA) {
|
|
30
|
+
_context.next = 10;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
_context.next = 8;
|
|
34
|
+
return handleDirectory(ctx, entry, urlPath);
|
|
35
|
+
case 8:
|
|
36
|
+
result = _context.sent;
|
|
37
|
+
return _context.abrupt("return", result);
|
|
38
|
+
case 10:
|
|
39
|
+
// only spa can use es6-html
|
|
40
|
+
modernEntry = getModernEntry(entry);
|
|
41
|
+
useModern =
|
|
42
|
+
// route.enableModernMode &&
|
|
43
|
+
supportModern(ctx) && fs.existsSync(modernEntry);
|
|
44
|
+
templatePath = useModern ? modernEntry : entry;
|
|
45
|
+
if (fs.existsSync(templatePath)) {
|
|
46
|
+
_context.next = 15;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
throw new Error("Could not find template file: ".concat(templatePath));
|
|
50
|
+
case 15:
|
|
51
|
+
_context.next = 17;
|
|
52
|
+
return readFile(templatePath);
|
|
53
|
+
case 17:
|
|
54
|
+
content = _context.sent;
|
|
55
|
+
if (content) {
|
|
56
|
+
_context.next = 20;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
return _context.abrupt("return", null);
|
|
60
|
+
case 20:
|
|
61
|
+
if (!route.isSSR) {
|
|
62
|
+
_context.next = 32;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
_context.prev = 21;
|
|
66
|
+
_context.next = 24;
|
|
67
|
+
return ssr.render(ctx, {
|
|
68
|
+
distDir: distDir,
|
|
69
|
+
entryName: route.entryName,
|
|
70
|
+
urlPath: route.urlPath,
|
|
71
|
+
bundle: route.bundle,
|
|
72
|
+
template: content.toString(),
|
|
73
|
+
staticGenerate: staticGenerate
|
|
74
|
+
}, runner);
|
|
75
|
+
case 24:
|
|
76
|
+
_result = _context.sent;
|
|
77
|
+
return _context.abrupt("return", _result);
|
|
78
|
+
case 28:
|
|
79
|
+
_context.prev = 28;
|
|
80
|
+
_context.t0 = _context["catch"](21);
|
|
81
|
+
ctx.error(ERROR_DIGEST.ERENDER, _context.t0.stack || _context.t0.message);
|
|
82
|
+
ctx.res.setHeader('x-modern-ssr-fallback', '1');
|
|
83
|
+
case 32:
|
|
84
|
+
return _context.abrupt("return", {
|
|
85
|
+
content: content,
|
|
86
|
+
contentType: mime.contentType(path.extname(templatePath))
|
|
87
|
+
});
|
|
88
|
+
case 33:
|
|
89
|
+
case "end":
|
|
90
|
+
return _context.stop();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}, _callee, null, [[21, 28]]);
|
|
94
|
+
}));
|
|
95
|
+
function render(_x) {
|
|
96
|
+
return _render.apply(this, arguments);
|
|
97
|
+
}
|
|
98
|
+
return render;
|
|
99
|
+
}();
|
|
100
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
/* eslint-disable no-param-reassign */
|
|
3
|
+
|
|
4
|
+
import { headersWithoutCookie } from "../../utils";
|
|
5
|
+
export var createMetrics = function createMetrics(context, metrics) {
|
|
6
|
+
var entry = context.entryName,
|
|
7
|
+
request = context.request;
|
|
8
|
+
var _ref = request || {},
|
|
9
|
+
_ref$pathname = _ref.pathname,
|
|
10
|
+
pathname = _ref$pathname === void 0 ? '' : _ref$pathname;
|
|
11
|
+
var emitTimer = function emitTimer(name, cost) {
|
|
12
|
+
var tags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
13
|
+
metrics.emitTimer(name, cost, _objectSpread(_objectSpread({}, tags), {}, {
|
|
14
|
+
pathname: pathname,
|
|
15
|
+
entry: entry
|
|
16
|
+
}));
|
|
17
|
+
};
|
|
18
|
+
var emitCounter = function emitCounter(name, counter) {
|
|
19
|
+
var tags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
20
|
+
metrics.emitCounter(name, counter, _objectSpread(_objectSpread({}, tags), {}, {
|
|
21
|
+
pathname: pathname,
|
|
22
|
+
entry: entry
|
|
23
|
+
}));
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
emitTimer: emitTimer,
|
|
27
|
+
emitCounter: emitCounter
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export var createLogger = function createLogger(serverContext, logger) {
|
|
31
|
+
var request = serverContext.request || {};
|
|
32
|
+
var _request$headers = request.headers,
|
|
33
|
+
headers = _request$headers === void 0 ? {} : _request$headers,
|
|
34
|
+
_request$pathname = request.pathname,
|
|
35
|
+
pathname = _request$pathname === void 0 ? '' : _request$pathname;
|
|
36
|
+
var debug = function debug(message) {
|
|
37
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
38
|
+
args[_key - 1] = arguments[_key];
|
|
39
|
+
}
|
|
40
|
+
logger.debug.apply(logger, ["SSR Debug - ".concat(message, ", req.url = %s")].concat(args, [pathname]));
|
|
41
|
+
};
|
|
42
|
+
var info = function info(message) {
|
|
43
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
44
|
+
args[_key2 - 1] = arguments[_key2];
|
|
45
|
+
}
|
|
46
|
+
logger.info.apply(logger, ["SSR Info - ".concat(message, ", req.url = %s")].concat(args, [pathname]));
|
|
47
|
+
};
|
|
48
|
+
var error = function error(message, e) {
|
|
49
|
+
if (!e) {
|
|
50
|
+
e = message;
|
|
51
|
+
message = '';
|
|
52
|
+
}
|
|
53
|
+
logger.error("SSR Error - ".concat(message, ", error = %s, req.url = %s, req.headers = %o"), e instanceof Error ? e.stack || e.message : e, pathname, headersWithoutCookie(headers));
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
error: error,
|
|
57
|
+
info: info,
|
|
58
|
+
debug: debug
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
/* eslint-enable no-param-reassign */
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Parser from 'ua-parser-js';
|
|
2
|
+
import compareVersions from 'compare-versions';
|
|
3
|
+
import { NativeModuleNameMap } from "./browser-list";
|
|
4
|
+
var nativeModules = require('@babel/compat-data/native-modules');
|
|
5
|
+
export var supportModern = function supportModern(context) {
|
|
6
|
+
var _context$query;
|
|
7
|
+
if ((_context$query = context.query) !== null && _context$query !== void 0 && _context$query.modern_es6) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// no ua in request headers
|
|
12
|
+
var userAgent = context.headers['user-agent'];
|
|
13
|
+
if (!userAgent || typeof userAgent !== 'string') {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
var parsedUA = Parser(userAgent);
|
|
17
|
+
var browserName = parsedUA.browser.name;
|
|
18
|
+
var browserVersion = parsedUA.browser.version;
|
|
19
|
+
if (!browserName || !browserVersion) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
var nativeUAName = NativeModuleNameMap[browserName];
|
|
23
|
+
if (!nativeUAName) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
var version = nativeModules['es6.module'][nativeUAName];
|
|
27
|
+
if (!version) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
var result = compareVersions(browserVersion, version);
|
|
32
|
+
return result >= 0;
|
|
33
|
+
} catch (err) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
export var getModernEntry = function getModernEntry(filepath) {
|
|
38
|
+
return filepath.replace(/\.html$/, '-es6.html');
|
|
39
|
+
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
3
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
4
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
5
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
6
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
7
|
+
import { fs } from '@modern-js/utils';
|
|
8
|
+
import LRU from 'lru-cache';
|
|
9
|
+
var Byte = 1;
|
|
10
|
+
var KB = 1024 * Byte;
|
|
11
|
+
var MB = 1024 * KB;
|
|
12
|
+
var getContentLength = function getContentLength(cache) {
|
|
13
|
+
return cache.content.length;
|
|
14
|
+
};
|
|
15
|
+
var createCacheItem = /*#__PURE__*/function () {
|
|
16
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(filepath, mtime) {
|
|
17
|
+
var content;
|
|
18
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
19
|
+
while (1) {
|
|
20
|
+
switch (_context.prev = _context.next) {
|
|
21
|
+
case 0:
|
|
22
|
+
_context.next = 2;
|
|
23
|
+
return fs.readFile(filepath);
|
|
24
|
+
case 2:
|
|
25
|
+
content = _context.sent;
|
|
26
|
+
return _context.abrupt("return", {
|
|
27
|
+
content: content,
|
|
28
|
+
mtime: mtime
|
|
29
|
+
});
|
|
30
|
+
case 4:
|
|
31
|
+
case "end":
|
|
32
|
+
return _context.stop();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}, _callee);
|
|
36
|
+
}));
|
|
37
|
+
return function createCacheItem(_x, _x2) {
|
|
38
|
+
return _ref.apply(this, arguments);
|
|
39
|
+
};
|
|
40
|
+
}();
|
|
41
|
+
export var LruReader = /*#__PURE__*/function () {
|
|
42
|
+
// private timer?: NodeJS.Timeout;
|
|
43
|
+
|
|
44
|
+
function LruReader() {
|
|
45
|
+
_classCallCheck(this, LruReader);
|
|
46
|
+
_defineProperty(this, "cache", void 0);
|
|
47
|
+
this.cache = new LRU({
|
|
48
|
+
max: 256 * MB,
|
|
49
|
+
length: getContentLength,
|
|
50
|
+
maxAge: 5 * 60 * 5000 // 60s
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
_createClass(LruReader, [{
|
|
54
|
+
key: "init",
|
|
55
|
+
value: function init() {
|
|
56
|
+
// this.timeTask();
|
|
57
|
+
}
|
|
58
|
+
}, {
|
|
59
|
+
key: "close",
|
|
60
|
+
value: function close() {
|
|
61
|
+
// if (this.timer) {
|
|
62
|
+
// clearInterval(this.timer);
|
|
63
|
+
// }
|
|
64
|
+
}
|
|
65
|
+
}, {
|
|
66
|
+
key: "read",
|
|
67
|
+
value: function () {
|
|
68
|
+
var _read = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(filepath) {
|
|
69
|
+
var _ref2, content, stat, item;
|
|
70
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
71
|
+
while (1) {
|
|
72
|
+
switch (_context2.prev = _context2.next) {
|
|
73
|
+
case 0:
|
|
74
|
+
if (!this.cache.has(filepath)) {
|
|
75
|
+
_context2.next = 3;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
_ref2 = this.cache.get(filepath), content = _ref2.content;
|
|
79
|
+
return _context2.abrupt("return", {
|
|
80
|
+
content: content
|
|
81
|
+
});
|
|
82
|
+
case 3:
|
|
83
|
+
if (fs.existsSync(filepath)) {
|
|
84
|
+
_context2.next = 5;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
return _context2.abrupt("return", null);
|
|
88
|
+
case 5:
|
|
89
|
+
stat = fs.statSync(filepath);
|
|
90
|
+
if (!stat.isDirectory()) {
|
|
91
|
+
_context2.next = 8;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
return _context2.abrupt("return", null);
|
|
95
|
+
case 8:
|
|
96
|
+
if (!(stat.size > 20 * MB)) {
|
|
97
|
+
_context2.next = 10;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
return _context2.abrupt("return", null);
|
|
101
|
+
case 10:
|
|
102
|
+
_context2.next = 12;
|
|
103
|
+
return createCacheItem(filepath, stat.mtime);
|
|
104
|
+
case 12:
|
|
105
|
+
item = _context2.sent;
|
|
106
|
+
this.cache.set(filepath, item);
|
|
107
|
+
return _context2.abrupt("return", item);
|
|
108
|
+
case 15:
|
|
109
|
+
case "end":
|
|
110
|
+
return _context2.stop();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}, _callee2, this);
|
|
114
|
+
}));
|
|
115
|
+
function read(_x3) {
|
|
116
|
+
return _read.apply(this, arguments);
|
|
117
|
+
}
|
|
118
|
+
return read;
|
|
119
|
+
}()
|
|
120
|
+
}, {
|
|
121
|
+
key: "update",
|
|
122
|
+
value: function update() {
|
|
123
|
+
var cache = this.cache;
|
|
124
|
+
var files = cache.keys();
|
|
125
|
+
var _iterator = _createForOfIteratorHelper(files),
|
|
126
|
+
_step;
|
|
127
|
+
try {
|
|
128
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
129
|
+
var filepath = _step.value;
|
|
130
|
+
if (!fs.existsSync(filepath)) {
|
|
131
|
+
cache.del(filepath);
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
var item = cache.get(filepath);
|
|
135
|
+
var stat = fs.statSync(filepath);
|
|
136
|
+
var mtime = stat.mtime;
|
|
137
|
+
// file is modify
|
|
138
|
+
if (item.mtime < mtime) {
|
|
139
|
+
cache.del(filepath);
|
|
140
|
+
}
|
|
141
|
+
} catch (e) {
|
|
142
|
+
// for safe
|
|
143
|
+
cache.del(filepath);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch (err) {
|
|
147
|
+
_iterator.e(err);
|
|
148
|
+
} finally {
|
|
149
|
+
_iterator.f();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// private timeTask() {
|
|
154
|
+
// this.timer = setInterval(() => this.update, 5 * 60 * 1000).unref();
|
|
155
|
+
// }
|
|
156
|
+
}]);
|
|
157
|
+
return LruReader;
|
|
158
|
+
}();
|
|
159
|
+
var reader = new LruReader();
|
|
160
|
+
export var readFile = /*#__PURE__*/function () {
|
|
161
|
+
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(filepath) {
|
|
162
|
+
var file;
|
|
163
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
164
|
+
while (1) {
|
|
165
|
+
switch (_context3.prev = _context3.next) {
|
|
166
|
+
case 0:
|
|
167
|
+
_context3.next = 2;
|
|
168
|
+
return reader.read(filepath);
|
|
169
|
+
case 2:
|
|
170
|
+
file = _context3.sent;
|
|
171
|
+
return _context3.abrupt("return", file === null || file === void 0 ? void 0 : file.content);
|
|
172
|
+
case 4:
|
|
173
|
+
case "end":
|
|
174
|
+
return _context3.stop();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}, _callee3);
|
|
178
|
+
}));
|
|
179
|
+
return function readFile(_x4) {
|
|
180
|
+
return _ref3.apply(this, arguments);
|
|
181
|
+
};
|
|
182
|
+
}();
|
|
183
|
+
export var updateFile = function updateFile() {
|
|
184
|
+
reader.update();
|
|
185
|
+
};
|
|
186
|
+
export var init = function init() {
|
|
187
|
+
reader.init();
|
|
188
|
+
};
|
|
189
|
+
export var close = function close() {
|
|
190
|
+
reader.close();
|
|
191
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fs, LOADABLE_STATS_FILE, mime, ROUTE_MINIFEST_FILE, SERVER_RENDER_FUNCTION_NAME } from '@modern-js/utils';
|
|
5
|
+
import cookie from 'cookie';
|
|
6
|
+
import cache from "./cache";
|
|
7
|
+
import { createLogger, createMetrics } from "./measure";
|
|
8
|
+
export var render = /*#__PURE__*/function () {
|
|
9
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(ctx, renderOptions, runner) {
|
|
10
|
+
var _ctx$res;
|
|
11
|
+
var urlPath, bundle, distDir, template, entryName, staticGenerate, bundleJS, loadableUri, loadableStats, routesManifestUri, routeManifest, context, serverRender, content, _context$redirection, url, _context$redirection$, status;
|
|
12
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
13
|
+
while (1) {
|
|
14
|
+
switch (_context.prev = _context.next) {
|
|
15
|
+
case 0:
|
|
16
|
+
urlPath = renderOptions.urlPath, bundle = renderOptions.bundle, distDir = renderOptions.distDir, template = renderOptions.template, entryName = renderOptions.entryName, staticGenerate = renderOptions.staticGenerate;
|
|
17
|
+
bundleJS = path.join(distDir, bundle);
|
|
18
|
+
loadableUri = path.join(distDir, LOADABLE_STATS_FILE);
|
|
19
|
+
loadableStats = fs.existsSync(loadableUri) ? require(loadableUri) : '';
|
|
20
|
+
routesManifestUri = path.join(distDir, ROUTE_MINIFEST_FILE);
|
|
21
|
+
routeManifest = fs.existsSync(routesManifestUri) ? require(routesManifestUri) : undefined;
|
|
22
|
+
context = {
|
|
23
|
+
request: {
|
|
24
|
+
baseUrl: urlPath,
|
|
25
|
+
params: ctx.params,
|
|
26
|
+
pathname: ctx.path,
|
|
27
|
+
host: ctx.host,
|
|
28
|
+
query: ctx.query,
|
|
29
|
+
url: ctx.href,
|
|
30
|
+
cookieMap: cookie.parse(ctx.headers.cookie || ''),
|
|
31
|
+
headers: ctx.headers
|
|
32
|
+
},
|
|
33
|
+
response: {
|
|
34
|
+
setHeader: function setHeader(key, value) {
|
|
35
|
+
return ctx.res.setHeader(key, value);
|
|
36
|
+
},
|
|
37
|
+
status: function status(code) {
|
|
38
|
+
ctx.res.statusCode = code;
|
|
39
|
+
},
|
|
40
|
+
locals: ((_ctx$res = ctx.res) === null || _ctx$res === void 0 ? void 0 : _ctx$res.locals) || {}
|
|
41
|
+
},
|
|
42
|
+
redirection: {},
|
|
43
|
+
template: template,
|
|
44
|
+
loadableStats: loadableStats,
|
|
45
|
+
routeManifest: routeManifest,
|
|
46
|
+
// for streaming ssr
|
|
47
|
+
entryName: entryName,
|
|
48
|
+
staticGenerate: staticGenerate,
|
|
49
|
+
logger: undefined,
|
|
50
|
+
metrics: undefined,
|
|
51
|
+
req: ctx.req,
|
|
52
|
+
res: ctx.res
|
|
53
|
+
};
|
|
54
|
+
context.logger = createLogger(context, ctx.logger);
|
|
55
|
+
context.metrics = createMetrics(context, ctx.metrics);
|
|
56
|
+
runner.extendSSRContext(context);
|
|
57
|
+
serverRender = require(bundleJS)[SERVER_RENDER_FUNCTION_NAME];
|
|
58
|
+
_context.next = 13;
|
|
59
|
+
return cache(serverRender, ctx)(context);
|
|
60
|
+
case 13:
|
|
61
|
+
content = _context.sent;
|
|
62
|
+
_context$redirection = context.redirection, url = _context$redirection.url, _context$redirection$ = _context$redirection.status, status = _context$redirection$ === void 0 ? 302 : _context$redirection$;
|
|
63
|
+
if (!url) {
|
|
64
|
+
_context.next = 17;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
return _context.abrupt("return", {
|
|
68
|
+
content: url,
|
|
69
|
+
contentType: '',
|
|
70
|
+
statusCode: status,
|
|
71
|
+
redirect: true
|
|
72
|
+
});
|
|
73
|
+
case 17:
|
|
74
|
+
if (!(typeof content === 'string')) {
|
|
75
|
+
_context.next = 21;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
return _context.abrupt("return", {
|
|
79
|
+
content: content,
|
|
80
|
+
contentType: mime.contentType('html')
|
|
81
|
+
});
|
|
82
|
+
case 21:
|
|
83
|
+
return _context.abrupt("return", {
|
|
84
|
+
content: '',
|
|
85
|
+
contentStream: content,
|
|
86
|
+
contentType: mime.contentType('html')
|
|
87
|
+
});
|
|
88
|
+
case 22:
|
|
89
|
+
case "end":
|
|
90
|
+
return _context.stop();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}, _callee);
|
|
94
|
+
}));
|
|
95
|
+
return function render(_x, _x2, _x3) {
|
|
96
|
+
return _ref.apply(this, arguments);
|
|
97
|
+
};
|
|
98
|
+
}();
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { mime } from '@modern-js/utils';
|
|
5
|
+
import { readFile } from "./reader";
|
|
6
|
+
export function handleDirectory(_x, _x2, _x3) {
|
|
7
|
+
return _handleDirectory.apply(this, arguments);
|
|
8
|
+
}
|
|
9
|
+
function _handleDirectory() {
|
|
10
|
+
_handleDirectory = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(ctx, entryPath, urlPath) {
|
|
11
|
+
var pathname, filepath, content, contentType;
|
|
12
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
13
|
+
while (1) {
|
|
14
|
+
switch (_context.prev = _context.next) {
|
|
15
|
+
case 0:
|
|
16
|
+
pathname = ctx.path;
|
|
17
|
+
filepath = path.join(entryPath, trimLeft(pathname, urlPath)); // If can match accurately, always return the one that matches accurately
|
|
18
|
+
_context.next = 4;
|
|
19
|
+
return readFile(filepath);
|
|
20
|
+
case 4:
|
|
21
|
+
content = _context.sent;
|
|
22
|
+
contentType = mime.contentType(path.extname(filepath) || ''); // automatic addressing
|
|
23
|
+
if (content) {
|
|
24
|
+
_context.next = 22;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
if (!pathname.endsWith('/')) {
|
|
28
|
+
_context.next = 13;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
_context.next = 10;
|
|
32
|
+
return readFile("".concat(filepath, "index.html"));
|
|
33
|
+
case 10:
|
|
34
|
+
content = _context.sent;
|
|
35
|
+
_context.next = 21;
|
|
36
|
+
break;
|
|
37
|
+
case 13:
|
|
38
|
+
if (pathname.includes('.')) {
|
|
39
|
+
_context.next = 21;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
_context.next = 16;
|
|
43
|
+
return readFile("".concat(filepath, ".html"));
|
|
44
|
+
case 16:
|
|
45
|
+
content = _context.sent;
|
|
46
|
+
if (content) {
|
|
47
|
+
_context.next = 21;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
_context.next = 20;
|
|
51
|
+
return readFile("".concat(filepath, "/index.html"));
|
|
52
|
+
case 20:
|
|
53
|
+
content = _context.sent;
|
|
54
|
+
case 21:
|
|
55
|
+
// set content-type as html
|
|
56
|
+
if (content) {
|
|
57
|
+
contentType = mime.contentType('html');
|
|
58
|
+
}
|
|
59
|
+
case 22:
|
|
60
|
+
if (content) {
|
|
61
|
+
_context.next = 24;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
return _context.abrupt("return", null);
|
|
65
|
+
case 24:
|
|
66
|
+
return _context.abrupt("return", {
|
|
67
|
+
content: content,
|
|
68
|
+
contentType: contentType || ''
|
|
69
|
+
});
|
|
70
|
+
case 25:
|
|
71
|
+
case "end":
|
|
72
|
+
return _context.stop();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}, _callee);
|
|
76
|
+
}));
|
|
77
|
+
return _handleDirectory.apply(this, arguments);
|
|
78
|
+
}
|
|
79
|
+
var trimLeft = function trimLeft(str, prefix) {
|
|
80
|
+
if (str.startsWith(prefix)) {
|
|
81
|
+
return str.substring(prefix.length);
|
|
82
|
+
}
|
|
83
|
+
return str;
|
|
84
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export var RenderLevel;
|
|
2
|
+
(function (RenderLevel) {
|
|
3
|
+
RenderLevel[RenderLevel["CLIENT_RENDER"] = 0] = "CLIENT_RENDER";
|
|
4
|
+
RenderLevel[RenderLevel["SERVER_PREFETCH"] = 1] = "SERVER_PREFETCH";
|
|
5
|
+
RenderLevel[RenderLevel["SERVER_RENDER"] = 2] = "SERVER_RENDER";
|
|
6
|
+
})(RenderLevel || (RenderLevel = {}));
|