@modern-js/prod-server 1.21.2 → 2.0.0-beta.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/dist/js/modern/libs/hook-api/index.js +156 -0
  3. package/dist/js/modern/libs/hook-api/route.js +14 -29
  4. package/dist/js/modern/libs/hook-api/template.js +43 -4
  5. package/dist/js/modern/libs/render/cache/index.js +33 -16
  6. package/dist/js/modern/libs/render/measure.js +8 -1
  7. package/dist/js/modern/libs/render/ssr.js +20 -7
  8. package/dist/js/modern/libs/serve-file.js +8 -0
  9. package/dist/js/modern/server/index.js +9 -3
  10. package/dist/js/modern/server/modern-server-split.js +5 -44
  11. package/dist/js/modern/server/modern-server.js +140 -130
  12. package/dist/js/node/libs/hook-api/index.js +178 -0
  13. package/dist/js/node/libs/hook-api/route.js +14 -29
  14. package/dist/js/node/libs/hook-api/template.js +48 -4
  15. package/dist/js/node/libs/render/cache/index.js +34 -16
  16. package/dist/js/node/libs/render/measure.js +7 -0
  17. package/dist/js/node/libs/render/ssr.js +20 -7
  18. package/dist/js/node/libs/serve-file.js +12 -1
  19. package/dist/js/node/server/index.js +8 -2
  20. package/dist/js/node/server/modern-server-split.js +5 -45
  21. package/dist/js/node/server/modern-server.js +140 -132
  22. package/dist/types/libs/hook-api/index.d.ts +5 -0
  23. package/dist/types/libs/hook-api/route.d.ts +9 -14
  24. package/dist/types/libs/hook-api/template.d.ts +19 -9
  25. package/dist/types/libs/render/cache/index.d.ts +4 -2
  26. package/dist/types/libs/render/type.d.ts +3 -1
  27. package/dist/types/libs/serve-file.d.ts +2 -1
  28. package/dist/types/server/index.d.ts +2 -0
  29. package/dist/types/server/modern-server.d.ts +11 -11
  30. package/dist/types/type.d.ts +8 -10
  31. package/package.json +9 -32
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.createTemplateAPI = void 0;
6
+ exports.templateInjectableStream = exports.TemplateAPI = void 0;
7
+
8
+ var _stream = require("stream");
7
9
 
8
10
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
11
 
@@ -63,11 +65,53 @@ class TemplateAPI {
63
65
 
64
66
  replace(reg, text) {
65
67
  this.content = this.content.replace(reg, text);
66
- return this;
67
68
  }
68
69
 
69
70
  }
70
71
 
71
- const createTemplateAPI = content => new TemplateAPI(content);
72
+ exports.TemplateAPI = TemplateAPI;
73
+
74
+ const templateInjectableStream = ({
75
+ prependHead,
76
+ appendHead,
77
+ prependBody,
78
+ appendBody
79
+ }) => new _stream.Transform({
80
+ write(chunk, _, callback) {
81
+ let chunk_str = chunk.toString();
82
+
83
+ if (prependHead) {
84
+ const {
85
+ head
86
+ } = RegList.before;
87
+ chunk_str = chunk_str.replace(head, `${head}${prependHead}`);
88
+ }
89
+
90
+ if (appendHead) {
91
+ const {
92
+ head
93
+ } = RegList.after;
94
+ chunk_str = chunk_str.replace(head, `${appendHead}${head}`);
95
+ }
96
+
97
+ if (prependBody) {
98
+ const {
99
+ body
100
+ } = RegList.before;
101
+ chunk_str = chunk_str.replace(body, `${body}${prependBody}`);
102
+ }
103
+
104
+ if (appendBody) {
105
+ const {
106
+ body
107
+ } = RegList.after;
108
+ chunk_str = chunk_str.replace(body, `${appendBody}${body}`);
109
+ }
110
+
111
+ this.push(chunk_str);
112
+ callback();
113
+ }
114
+
115
+ });
72
116
 
73
- exports.createTemplateAPI = createTemplateAPI;
117
+ exports.templateInjectableStream = templateInjectableStream;
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
+ var _stream = require("stream");
9
+
8
10
  var _constants = require("../../../constants");
9
11
 
10
12
  var _spr = require("./spr");
@@ -25,10 +27,28 @@ var _default = (renderFn, ctx) => {
25
27
  entry: context.entryName
26
28
  }, context.request);
27
29
 
28
- const cacheFile = await sprCache.get(cacheContext); // no cache, render sync
30
+ const cacheFile = await sprCache.get(cacheContext);
31
+
32
+ async function afterRender(source, onAfterRender) {
33
+ if (typeof source === 'string') {
34
+ await onAfterRender(source);
35
+ return source;
36
+ } else {
37
+ let htmlForStream = '';
38
+ const cacheStream = new _stream.Transform({
39
+ write(chunk, _, callback) {
40
+ htmlForStream += chunk.toString();
41
+ this.push(chunk);
42
+ callback();
43
+ }
29
44
 
30
- if (!cacheFile) {
31
- const html = await renderFn(context);
45
+ });
46
+ cacheStream.on('close', () => onAfterRender(htmlForStream));
47
+ return source(cacheStream);
48
+ }
49
+ }
50
+
51
+ async function saveHtmlIntoCache(html) {
32
52
  const {
33
53
  cacheConfig
34
54
  } = context;
@@ -36,34 +56,32 @@ var _default = (renderFn, ctx) => {
36
56
  if (html && cacheConfig) {
37
57
  await sprCache.set(cacheContext, html, cacheConfig);
38
58
  }
59
+ } // no cache, render sync
39
60
 
40
- return html;
61
+
62
+ if (!cacheFile) {
63
+ const renderResult = await renderFn(context);
64
+ return afterRender(renderResult, saveHtmlIntoCache);
41
65
  }
42
66
 
43
67
  const cacheHash = cacheFile === null || cacheFile === void 0 ? void 0 : cacheFile.hash; // completely expired
44
68
 
45
69
  if (cacheFile.isGarbage) {
46
- const html = await renderFn(context);
47
- const {
48
- cacheConfig
49
- } = context;
50
-
51
- if (html && cacheConfig) {
52
- await sprCache.set(cacheContext, html, cacheConfig);
53
- }
54
-
55
- return html;
70
+ const renderResult = await renderFn(context);
71
+ return afterRender(renderResult, saveHtmlIntoCache);
56
72
  } else if (cacheFile.isStale) {
57
73
  // if file is stale, request async
58
74
  const render = (0, _util.withCoalescedInvoke)(() => renderFn(context)).bind(null, (0, _util.namespaceHash)('render', cacheFile.hash), []);
59
- render().then(res => {
75
+ render().then(async res => {
60
76
  if (res.value && res.isOrigin) {
61
77
  const {
62
78
  cacheConfig
63
79
  } = context;
64
80
 
65
81
  if (cacheConfig) {
66
- sprCache.set(cacheContext, res.value, cacheConfig);
82
+ afterRender(res.value, async html => {
83
+ sprCache.set(cacheContext, html, cacheConfig);
84
+ });
67
85
  } else {
68
86
  sprCache.del(cacheContext, cacheHash);
69
87
  }
@@ -60,6 +60,11 @@ const createLogger = (serverContext, logger) => {
60
60
  };
61
61
 
62
62
  const error = (message, e) => {
63
+ if (!e) {
64
+ e = message;
65
+ message = '';
66
+ }
67
+
63
68
  logger.error(`SSR Error - ${message}, error = %s, req.url = %s, req.headers = %o`, e instanceof Error ? e.stack || e.message : e, pathname, (0, _utils.headersWithoutCookie)(headers));
64
69
  };
65
70
 
@@ -69,5 +74,7 @@ const createLogger = (serverContext, logger) => {
69
74
  debug
70
75
  };
71
76
  };
77
+ /* eslint-enable no-param-reassign */
78
+
72
79
 
73
80
  exports.createLogger = createLogger;
@@ -18,6 +18,8 @@ var _measure = require("./measure");
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
19
 
20
20
  const render = async (ctx, renderOptions, runner) => {
21
+ var _ctx$res;
22
+
21
23
  const {
22
24
  urlPath,
23
25
  bundle,
@@ -49,7 +51,8 @@ const render = async (ctx, renderOptions, runner) => {
49
51
  },
50
52
  status: code => {
51
53
  ctx.res.statusCode = code;
52
- }
54
+ },
55
+ locals: ((_ctx$res = ctx.res) === null || _ctx$res === void 0 ? void 0 : _ctx$res.locals) || {}
53
56
  },
54
57
  redirection: {},
55
58
  template,
@@ -57,7 +60,9 @@ const render = async (ctx, renderOptions, runner) => {
57
60
  entryName,
58
61
  staticGenerate,
59
62
  logger: undefined,
60
- metrics: undefined
63
+ metrics: undefined,
64
+ req: ctx.req,
65
+ res: ctx.res
61
66
  };
62
67
  context.logger = (0, _measure.createLogger)(context, ctx.logger);
63
68
  context.metrics = (0, _measure.createMetrics)(context, ctx.metrics);
@@ -65,7 +70,7 @@ const render = async (ctx, renderOptions, runner) => {
65
70
 
66
71
  const serverRender = require(bundleJS)[_utils.SERVER_RENDER_FUNCTION_NAME];
67
72
 
68
- const html = await (0, _cache.default)(serverRender, ctx)(context);
73
+ const content = await (0, _cache.default)(serverRender, ctx)(context);
69
74
  const {
70
75
  url,
71
76
  status = 302
@@ -80,10 +85,18 @@ const render = async (ctx, renderOptions, runner) => {
80
85
  };
81
86
  }
82
87
 
83
- return {
84
- content: html,
85
- contentType: _utils.mime.contentType('html')
86
- };
88
+ if (typeof content === 'string') {
89
+ return {
90
+ content,
91
+ contentType: _utils.mime.contentType('html')
92
+ };
93
+ } else {
94
+ return {
95
+ content: '',
96
+ contentStream: content,
97
+ contentType: _utils.mime.contentType('html')
98
+ };
99
+ }
87
100
  };
88
101
 
89
102
  exports.render = render;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.createStaticFileHandler = void 0;
6
+ exports.faviconFallbackHandler = exports.createStaticFileHandler = void 0;
7
7
 
8
8
  var _serveStatic = _interopRequireDefault(require("serve-static"));
9
9
 
@@ -26,6 +26,17 @@ const removedPrefix = (req, prefix) => {
26
26
  }
27
27
  };
28
28
 
29
+ const faviconFallbackHandler = (context, next) => {
30
+ if (context.url === '/favicon.ico') {
31
+ context.res.statusCode = 204;
32
+ context.res.end();
33
+ } else {
34
+ next();
35
+ }
36
+ };
37
+
38
+ exports.faviconFallbackHandler = faviconFallbackHandler;
39
+
29
40
  const createStaticFileHandler = (rules, output = {}) => // eslint-disable-next-line consistent-return
30
41
  async (context, next) => {
31
42
  const {
@@ -167,6 +167,10 @@ class Server {
167
167
  };
168
168
  }
169
169
 
170
+ async render(req, res, url) {
171
+ return this.server.render(req, res, url);
172
+ }
173
+
170
174
  async createHookRunner() {
171
175
  // clear server manager every create time
172
176
  _serverCore.serverManager.clear();
@@ -176,13 +180,15 @@ class Server {
176
180
  } = this; // TODO: 确认下这里是不是可以不从 options 中取插件,而是从 config 中取和过滤
177
181
 
178
182
  const {
179
- plugins = [],
183
+ internalPlugins = _utils.INTERNAL_SERVER_PLUGINS,
180
184
  pwd,
181
185
  config
182
186
  } = options;
183
187
  const serverPlugins = this.serverConfig.plugins || []; // server app context for serve plugin
184
188
 
185
- const loadedPlugins = (0, _serverCore.loadPlugins)(plugins.concat(serverPlugins), pwd);
189
+ const loadedPlugins = (0, _serverCore.loadPlugins)(pwd, serverPlugins, {
190
+ internalPlugins
191
+ });
186
192
  (0, _utils2.debug)('plugins', config.plugins, loadedPlugins);
187
193
  loadedPlugins.forEach(p => {
188
194
  _serverCore.serverManager.usePlugin(p);
@@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createProdServer = void 0;
7
7
 
8
- var _constants = require("../constants");
9
-
10
8
  var _modernServer = require("./modern-server");
11
9
 
12
10
  class ModernSSRServer extends _modernServer.ModernServer {
@@ -14,20 +12,8 @@ class ModernSSRServer extends _modernServer.ModernServer {
14
12
  return null;
15
13
  }
16
14
 
17
- filterRoutes(routes) {
18
- return routes.filter(route => !route.isApi);
19
- }
20
-
21
- async setupBeforeProdMiddleware() {
22
- if (this.runMode === _constants.RUN_MODE.FULL) {
23
- await super.setupBeforeProdMiddleware();
24
- }
25
- }
26
-
27
- async emitRouteHook(_, _input) {
28
- if (this.runMode === _constants.RUN_MODE.FULL) {
29
- await super.emitRouteHook(_, _input);
30
- }
15
+ async handleAPI(context) {
16
+ return this.render404(context);
31
17
  }
32
18
 
33
19
  }
@@ -41,15 +27,6 @@ class ModernAPIServer extends _modernServer.ModernServer {
41
27
  return routes.filter(route => route.isApi);
42
28
  }
43
29
 
44
- async setupBeforeProdMiddleware() {
45
- if (this.runMode === _constants.RUN_MODE.FULL) {
46
- await super.setupBeforeProdMiddleware();
47
- }
48
- }
49
-
50
- async emitRouteHook(_, _input) {// empty
51
- }
52
-
53
30
  }
54
31
 
55
32
  class ModernWebServer extends _modernServer.ModernServer {
@@ -58,29 +35,12 @@ class ModernWebServer extends _modernServer.ModernServer {
58
35
  }
59
36
 
60
37
  async handleAPI(context) {
61
- const {
62
- proxyTarget
63
- } = this;
64
-
65
- if (proxyTarget !== null && proxyTarget !== void 0 && proxyTarget.api) {
66
- return this.proxy();
67
- } else {
68
- return this.render404(context);
69
- }
38
+ return this.render404(context);
70
39
  }
71
40
 
72
41
  async handleWeb(context, route) {
73
- const {
74
- proxyTarget
75
- } = this;
76
-
77
- if (route.isSSR && proxyTarget !== null && proxyTarget !== void 0 && proxyTarget.ssr) {
78
- return this.proxy();
79
- } else {
80
- // if no proxyTarget but access web server, degradation to csr
81
- route.isSSR = false;
82
- return super.handleWeb(context, route);
83
- }
42
+ route.isSSR = false;
43
+ return super.handleWeb(context, route);
84
44
  }
85
45
 
86
46
  }