@modern-js/server 1.3.1-beta.0 → 1.4.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.
Files changed (126) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/dist/js/modern/dev-tools/babel/register.js +1 -0
  3. package/dist/js/modern/dev-tools/dev-server-plugin.js +1 -2
  4. package/dist/js/modern/dev-tools/mock/getMockData.js +24 -1
  5. package/dist/js/modern/dev-tools/mock/index.js +1 -26
  6. package/dist/js/modern/dev-tools/socket-server.js +4 -2
  7. package/dist/js/modern/dev-tools/watcher/index.js +4 -7
  8. package/dist/js/modern/dev-tools/watcher/stats-cache.js +32 -20
  9. package/dist/js/modern/libs/context/context.js +6 -0
  10. package/dist/js/modern/libs/hook-api/route.js +6 -4
  11. package/dist/js/modern/libs/render/index.js +1 -0
  12. package/dist/js/modern/libs/render/reader.js +1 -2
  13. package/dist/js/modern/libs/render/ssr.js +7 -2
  14. package/dist/js/modern/libs/route/index.js +0 -1
  15. package/dist/js/modern/libs/route/matcher.js +15 -3
  16. package/dist/js/modern/libs/route/route.js +1 -0
  17. package/dist/js/modern/server/dev-server/dev-server.js +3 -0
  18. package/dist/js/modern/server/index.js +5 -4
  19. package/dist/js/modern/server/modern-server-split.js +1 -1
  20. package/dist/js/modern/server/modern-server.js +13 -34
  21. package/dist/js/modern/utils.js +39 -0
  22. package/dist/js/node/dev-tools/babel/register.js +1 -0
  23. package/dist/js/node/dev-tools/dev-server-plugin.js +1 -2
  24. package/dist/js/node/dev-tools/mock/getMockData.js +29 -2
  25. package/dist/js/node/dev-tools/mock/index.js +5 -26
  26. package/dist/js/node/dev-tools/socket-server.js +4 -2
  27. package/dist/js/node/dev-tools/watcher/index.js +7 -5
  28. package/dist/js/node/dev-tools/watcher/stats-cache.js +33 -20
  29. package/dist/js/node/libs/context/context.js +6 -0
  30. package/dist/js/node/libs/hook-api/route.js +6 -4
  31. package/dist/js/node/libs/render/index.js +1 -0
  32. package/dist/js/node/libs/render/reader.js +2 -1
  33. package/dist/js/node/libs/render/ssr.js +8 -2
  34. package/dist/js/node/libs/route/index.js +0 -1
  35. package/dist/js/node/libs/route/matcher.js +16 -3
  36. package/dist/js/node/libs/route/route.js +1 -0
  37. package/dist/js/node/server/dev-server/dev-server.js +3 -0
  38. package/dist/js/node/server/index.js +9 -6
  39. package/dist/js/node/server/modern-server-split.js +1 -1
  40. package/dist/js/node/server/modern-server.js +12 -33
  41. package/dist/js/node/utils.js +51 -2
  42. package/dist/types/dev-tools/mock/getMockData.d.ts +2 -1
  43. package/dist/types/dev-tools/socket-server.d.ts +1 -2
  44. package/dist/types/dev-tools/watcher/index.d.ts +2 -1
  45. package/dist/types/dev-tools/watcher/stats-cache.d.ts +3 -2
  46. package/dist/types/libs/context/context.d.ts +2 -0
  47. package/dist/types/libs/hook-api/route.d.ts +3 -2
  48. package/dist/types/libs/render/reader.d.ts +13 -0
  49. package/dist/types/libs/render/ssr.d.ts +1 -0
  50. package/dist/types/libs/route/matcher.d.ts +1 -1
  51. package/dist/types/libs/route/route.d.ts +1 -0
  52. package/dist/types/server/dev-server/dev-server-split.d.ts +3 -3
  53. package/dist/types/server/modern-server-split.d.ts +3 -3
  54. package/dist/types/server/modern-server.d.ts +1 -2
  55. package/dist/types/type.d.ts +6 -4
  56. package/dist/types/utils.d.ts +5 -1
  57. package/package.json +13 -12
  58. package/tests/context.test.ts +12 -1
  59. package/tests/dev.test.ts +306 -7
  60. package/tests/fixtures/mock/exist/config/mock/index.ts +11 -0
  61. package/tests/fixtures/mock/zero/config/mock/index.ts +1 -0
  62. package/tests/fixtures/pure/tsconfig.json +0 -1
  63. package/tests/fixtures/reader/index.ts +3 -0
  64. package/tests/fixtures/route-spec/dynamic.json +13 -0
  65. package/tests/fixtures/ssr/bundle.js +5 -0
  66. package/tests/fixtures/static-dir/bar.html +11 -0
  67. package/tests/fixtures/static-dir/baz/index.html +11 -0
  68. package/tests/fixtures/static-dir/foo/index.html +11 -0
  69. package/tests/fixtures/watch/a.ts +3 -0
  70. package/tests/fixtures/watch/index.ts +5 -0
  71. package/tests/fixtures/watch/stats.txt +1 -0
  72. package/tests/hook.test.ts +1 -1
  73. package/tests/render.test.ts +102 -0
  74. package/tests/route.test.ts +26 -3
  75. package/tests/utils.test.ts +35 -0
  76. package/tests/watcher.test.ts +6 -4
  77. package/src/constants.ts +0 -26
  78. package/src/dev-tools/babel/register.ts +0 -37
  79. package/src/dev-tools/dev-server-plugin.ts +0 -48
  80. package/src/dev-tools/https/global.d.ts +0 -3
  81. package/src/dev-tools/https/index.ts +0 -12
  82. package/src/dev-tools/launch-editor/index.ts +0 -29
  83. package/src/dev-tools/mock/getMockData.ts +0 -109
  84. package/src/dev-tools/mock/index.ts +0 -63
  85. package/src/dev-tools/socket-server.ts +0 -192
  86. package/src/dev-tools/watcher/dependency-tree.ts +0 -94
  87. package/src/dev-tools/watcher/index.ts +0 -81
  88. package/src/dev-tools/watcher/stats-cache.ts +0 -53
  89. package/src/index.ts +0 -16
  90. package/src/libs/context/context.ts +0 -176
  91. package/src/libs/context/index.ts +0 -7
  92. package/src/libs/hook-api/route.ts +0 -38
  93. package/src/libs/hook-api/template.ts +0 -53
  94. package/src/libs/metrics.ts +0 -15
  95. package/src/libs/proxy.ts +0 -85
  96. package/src/libs/render/cache/__tests__/cache.fun.test.ts +0 -94
  97. package/src/libs/render/cache/__tests__/cache.test.ts +0 -240
  98. package/src/libs/render/cache/__tests__/cacheable.ts +0 -44
  99. package/src/libs/render/cache/__tests__/error-configuration.ts +0 -34
  100. package/src/libs/render/cache/__tests__/matched-cache.ts +0 -88
  101. package/src/libs/render/cache/index.ts +0 -75
  102. package/src/libs/render/cache/page-caches/index.ts +0 -11
  103. package/src/libs/render/cache/page-caches/lru.ts +0 -38
  104. package/src/libs/render/cache/spr.ts +0 -301
  105. package/src/libs/render/cache/type.ts +0 -59
  106. package/src/libs/render/cache/util.ts +0 -97
  107. package/src/libs/render/index.ts +0 -78
  108. package/src/libs/render/modern/browser-list.ts +0 -7
  109. package/src/libs/render/modern/index.ts +0 -41
  110. package/src/libs/render/modern/module.d.ts +0 -4
  111. package/src/libs/render/reader.ts +0 -119
  112. package/src/libs/render/ssr.ts +0 -62
  113. package/src/libs/render/static.ts +0 -52
  114. package/src/libs/render/type.ts +0 -38
  115. package/src/libs/route/index.ts +0 -77
  116. package/src/libs/route/matcher.ts +0 -93
  117. package/src/libs/route/route.ts +0 -32
  118. package/src/libs/serve-file.ts +0 -34
  119. package/src/server/dev-server/dev-server-split.ts +0 -41
  120. package/src/server/dev-server/dev-server.ts +0 -300
  121. package/src/server/dev-server/index.ts +0 -2
  122. package/src/server/index.ts +0 -163
  123. package/src/server/modern-server-split.ts +0 -97
  124. package/src/server/modern-server.ts +0 -636
  125. package/src/type.ts +0 -88
  126. package/src/utils.ts +0 -79
@@ -32,6 +32,7 @@ const enableRegister = (projectRoot, config) => {
32
32
  return require('@babel/register')(_objectSpread(_objectSpread({}, babelConfig), {}, {
33
33
  only: [function (filePath) {
34
34
  // TODO: wait params
35
+ // FIXME: 删除hardcode,根据 AppContext 中的 metaName 设置路径
35
36
  if (filePath.includes(`node_modules${_path.default.sep}.modern-js`)) {
36
37
  return true;
37
38
  }
@@ -25,8 +25,7 @@ class DevServerPlugin {
25
25
  } = this;
26
26
  const host = `&host=${options.client.host || 'localhost'}`;
27
27
  const path = `&path=${options.client.path}`;
28
- const port = `&port=${options.client.port}`; // Todo @songzhenwei
29
-
28
+ const port = `&port=${options.client.port}`;
30
29
  const clientEntry = `${require.resolve('@modern-js/hmr-client')}?${host}${path}${port}`;
31
30
 
32
31
  const hotEntry = require.resolve('webpack/hot/dev-server');
@@ -3,10 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.getMatched = exports.default = void 0;
7
7
 
8
8
  var _utils = require("@modern-js/utils");
9
9
 
10
+ var _pathToRegexp = require("path-to-regexp");
11
+
10
12
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
11
13
 
12
14
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -91,4 +93,29 @@ var _default = filepath => {
91
93
  return data;
92
94
  };
93
95
 
94
- exports.default = _default;
96
+ exports.default = _default;
97
+
98
+ const getMatched = (context, mockApiList) => {
99
+ const {
100
+ path: targetPathname,
101
+ method: targetMethod
102
+ } = context;
103
+ const matched = mockApiList.find(mockApi => {
104
+ const {
105
+ method,
106
+ path: pathname
107
+ } = mockApi;
108
+
109
+ if (method.toLowerCase() === targetMethod.toLowerCase()) {
110
+ return (0, _pathToRegexp.match)(pathname, {
111
+ encode: encodeURI,
112
+ decode: decodeURIComponent
113
+ })(targetPathname);
114
+ }
115
+
116
+ return false;
117
+ });
118
+ return matched;
119
+ };
120
+
121
+ exports.getMatched = getMatched;
@@ -9,36 +9,15 @@ var _path = _interopRequireDefault(require("path"));
9
9
 
10
10
  var _utils = require("@modern-js/utils");
11
11
 
12
- var _pathToRegexp = require("path-to-regexp");
13
-
14
12
  var _constants = require("../../constants");
15
13
 
16
- var _getMockData = _interopRequireDefault(require("./getMockData"));
14
+ var _getMockData = _interopRequireWildcard(require("./getMockData"));
17
15
 
18
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
19
17
 
20
- const getMatched = (context, mockApiList) => {
21
- const {
22
- path: targetPathname,
23
- method: targetMethod
24
- } = context;
25
- const matched = mockApiList.find(mockApi => {
26
- const {
27
- method,
28
- path: pathname
29
- } = mockApi;
30
-
31
- if (method.toLowerCase() === targetMethod.toLowerCase()) {
32
- return (0, _pathToRegexp.match)(pathname, {
33
- encode: encodeURI,
34
- decode: decodeURIComponent
35
- })(targetPathname);
36
- }
18
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
37
19
 
38
- return false;
39
- });
40
- return matched;
41
- };
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
42
21
 
43
22
  const createMockHandler = ({
44
23
  pwd
@@ -69,7 +48,7 @@ const createMockHandler = ({
69
48
  const {
70
49
  res
71
50
  } = context;
72
- const matched = getMatched(context, apiList);
51
+ const matched = (0, _getMockData.getMatched)(context, apiList);
73
52
 
74
53
  if (!matched) {
75
54
  return next();
@@ -118,8 +118,10 @@ class SocketServer {
118
118
  });
119
119
  }
120
120
 
121
- close(connection) {
122
- connection.close();
121
+ close() {
122
+ this.sockets.forEach(socket => {
123
+ socket.close();
124
+ });
123
125
  } // get standard stats
124
126
 
125
127
 
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.getWatchedFiles = exports.default = void 0;
7
+
8
+ var _path = _interopRequireDefault(require("path"));
7
9
 
8
10
  var _chokidar = _interopRequireDefault(require("chokidar"));
9
11
 
@@ -18,12 +20,14 @@ const getWatchedFiles = watcher => {
18
20
  const files = [];
19
21
  Object.keys(watched).forEach(dir => {
20
22
  watched[dir].forEach(fileName => {
21
- files.push(`${dir}/${fileName}`);
23
+ files.push(_path.default.join(dir, fileName));
22
24
  });
23
25
  });
24
26
  return files;
25
27
  };
26
28
 
29
+ exports.getWatchedFiles = getWatchedFiles;
30
+
27
31
  class Watcher {
28
32
  constructor() {
29
33
  this.dependencyTree = null;
@@ -32,9 +36,7 @@ class Watcher {
32
36
 
33
37
  listen(files, options, callback) {
34
38
  const watched = files.filter(Boolean);
35
- const filenames = watched.map(filename => filename.replace(/\\/g, '/')); // eslint-disable-next-line no-console
36
-
37
- console.log('watched files:', filenames);
39
+ const filenames = watched.map(filename => filename.replace(/\\/g, '/'));
38
40
  const cache = new _statsCache.StatsCache();
39
41
 
40
42
  const watcher = _chokidar.default.watch(filenames, options);
@@ -7,24 +7,29 @@ exports.StatsCache = void 0;
7
7
 
8
8
  var _fs = _interopRequireDefault(require("fs"));
9
9
 
10
+ var _crypto = _interopRequireDefault(require("crypto"));
11
+
10
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
13
 
12
14
  class StatsCache {
13
15
  constructor() {
14
- this.cachedStats = {};
16
+ this.cachedHash = {};
17
+ this.cachedSize = {};
15
18
  }
16
19
 
17
20
  add(files) {
18
21
  const {
19
- cachedStats
22
+ cachedHash,
23
+ cachedSize
20
24
  } = this;
21
25
 
22
26
  for (const filename of files) {
23
27
  if (_fs.default.existsSync(filename)) {
24
- const stat = _fs.default.statSync(filename);
28
+ const stats = _fs.default.statSync(filename);
25
29
 
26
- if (stat.isFile() && !cachedStats[filename]) {
27
- cachedStats[filename] = this.sign(stat);
30
+ if (stats.isFile() && !cachedHash[filename]) {
31
+ cachedHash[filename] = this.hash(stats, filename);
32
+ cachedSize[filename] = stats.size;
28
33
  }
29
34
  }
30
35
  }
@@ -32,34 +37,43 @@ class StatsCache {
32
37
 
33
38
  refresh(filename) {
34
39
  const {
35
- cachedStats
40
+ cachedHash,
41
+ cachedSize
36
42
  } = this;
37
43
 
38
44
  if (_fs.default.existsSync(filename)) {
39
- const stat = _fs.default.statSync(filename);
45
+ const stats = _fs.default.statSync(filename);
40
46
 
41
- if (stat.isFile()) {
42
- cachedStats[filename] = this.sign(stat);
47
+ if (stats.isFile()) {
48
+ cachedHash[filename] = this.hash(stats, filename);
49
+ cachedSize[filename] = stats.size;
43
50
  }
44
51
  }
45
52
  }
46
53
 
47
54
  del(filename) {
48
- if (this.cachedStats[filename]) {
49
- delete this.cachedStats[filename];
55
+ if (this.cachedHash[filename]) {
56
+ delete this.cachedHash[filename];
57
+ delete this.cachedSize[filename];
50
58
  }
51
59
  }
52
60
 
53
61
  isDiff(filename) {
54
62
  const {
55
- cachedStats
63
+ cachedHash,
64
+ cachedSize
56
65
  } = this;
57
66
 
58
- const stat = _fs.default.statSync(filename);
67
+ const stats = _fs.default.statSync(filename);
68
+
69
+ const hash = cachedHash[filename];
70
+ const size = cachedSize[filename];
59
71
 
60
- const cachedStat = cachedStats[filename];
72
+ if (stats.size !== size) {
73
+ return true;
74
+ }
61
75
 
62
- if (this.sign(stat) !== cachedStat) {
76
+ if (this.hash(stats, filename) !== hash) {
63
77
  return true;
64
78
  }
65
79
 
@@ -67,12 +81,11 @@ class StatsCache {
67
81
  }
68
82
 
69
83
  has(filename) {
70
- return Boolean(this.cachedStats[filename]);
71
- } // Todo size 其实有点问题,修改单个字符会导致触发不了 change
72
-
84
+ return Boolean(this.cachedHash[filename]);
85
+ }
73
86
 
74
- sign(stat) {
75
- return stat.size;
87
+ hash(stats, filename) {
88
+ return _crypto.default.createHash('md5').update(_fs.default.readFileSync(filename)).digest('hex');
76
89
  }
77
90
 
78
91
  }
@@ -31,10 +31,12 @@ class ModernServerContext {
31
31
  this.params = {};
32
32
  this.logger = void 0;
33
33
  this.metrics = void 0;
34
+ this.serverData = void 0;
34
35
  this.req = req;
35
36
  this.res = res;
36
37
  this.logger = req.logger;
37
38
  this.metrics = req.metrics;
39
+ this.serverData = {};
38
40
  this.bind();
39
41
  }
40
42
 
@@ -53,6 +55,10 @@ class ModernServerContext {
53
55
  this.params = params;
54
56
  }
55
57
 
58
+ setServerData(key, value) {
59
+ this.serverData[key] = value;
60
+ }
61
+
56
62
  getReqHeader(key) {
57
63
  const {
58
64
  req
@@ -6,15 +6,17 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createRouteAPI = void 0;
7
7
 
8
8
  class RouteAPI {
9
- constructor(matched, router) {
9
+ constructor(matched, router, url) {
10
10
  this.router = void 0;
11
11
  this.current = void 0;
12
+ this.url = void 0;
12
13
  this.current = matched;
13
14
  this.router = router;
15
+ this.url = url;
14
16
  }
15
17
 
16
18
  cur() {
17
- return this.current.generate();
19
+ return this.current.generate(this.url);
18
20
  }
19
21
 
20
22
  get(entryName) {
@@ -22,7 +24,7 @@ class RouteAPI {
22
24
  router
23
25
  } = this;
24
26
  const matched = router.matchEntry(entryName);
25
- return matched ? matched.generate() : null;
27
+ return matched ? matched.generate(this.url) : null;
26
28
  }
27
29
 
28
30
  use(entryName) {
@@ -41,6 +43,6 @@ class RouteAPI {
41
43
 
42
44
  }
43
45
 
44
- const createRouteAPI = (matched, router) => new RouteAPI(matched, router);
46
+ const createRouteAPI = (matched, router, url) => new RouteAPI(matched, router, url);
45
47
 
46
48
  exports.createRouteAPI = createRouteAPI;
@@ -64,6 +64,7 @@ const createRenderHandler = ({
64
64
  const result = await ssr.render(ctx, {
65
65
  distDir,
66
66
  entryName: route.entryName,
67
+ urlPath: route.urlPath,
67
68
  bundle: route.bundle,
68
69
  template: templateHTML,
69
70
  staticGenerate
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.updateFile = exports.readFile = exports.init = exports.close = void 0;
6
+ exports.updateFile = exports.readFile = exports.init = exports.close = exports.LruReader = void 0;
7
7
 
8
8
  var _utils = require("@modern-js/utils");
9
9
 
@@ -110,6 +110,7 @@ class LruReader {
110
110
 
111
111
  }
112
112
 
113
+ exports.LruReader = LruReader;
113
114
  const reader = new LruReader();
114
115
 
115
116
  const readFile = async filepath => {
@@ -11,12 +11,15 @@ var _utils = require("@modern-js/utils");
11
11
 
12
12
  var _mimeTypes = _interopRequireDefault(require("mime-types"));
13
13
 
14
+ var _cookie = _interopRequireDefault(require("cookie"));
15
+
14
16
  var _cache = _interopRequireDefault(require("./cache"));
15
17
 
16
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
19
 
18
20
  const render = async (ctx, renderOptions, runner) => {
19
21
  const {
22
+ urlPath,
20
23
  bundle,
21
24
  distDir,
22
25
  template,
@@ -28,11 +31,14 @@ const render = async (ctx, renderOptions, runner) => {
28
31
 
29
32
  const context = {
30
33
  request: {
34
+ baseUrl: urlPath,
31
35
  params: ctx.params,
32
36
  pathname: ctx.path,
37
+ host: ctx.host,
33
38
  query: ctx.query,
34
- headers: ctx.headers,
35
- cookie: ctx.headers.cookie
39
+ url: ctx.href,
40
+ cookieMap: _cookie.default.parse(ctx.headers.cookie || ''),
41
+ headers: ctx.headers
36
42
  },
37
43
  redirection: {},
38
44
  template,
@@ -23,7 +23,6 @@ class RouteMatchManager {
23
23
 
24
24
  filter(pathname) {
25
25
  return this.matchers.reduce((matches, matcher) => {
26
- // 非网关来的,或网关匹配上之后,内部再进行一次自己的匹配
27
26
  if (matcher.matchUrlPath(pathname)) {
28
27
  matches.push(matcher);
29
28
  }
@@ -9,6 +9,8 @@ var _utils = require("@modern-js/utils");
9
9
 
10
10
  var _pathToRegexp = require("path-to-regexp");
11
11
 
12
+ var _utils2 = require("../../utils");
13
+
12
14
  var _route = require("./route");
13
15
 
14
16
  // eslint-disable-next-line no-useless-escape
@@ -25,8 +27,16 @@ class RouteMatcher {
25
27
  } // generate modern route object
26
28
 
27
29
 
28
- generate() {
29
- return new _route.ModernRoute(this.spec);
30
+ generate(url) {
31
+ const route = new _route.ModernRoute(this.spec);
32
+
33
+ if (this.urlPath) {
34
+ const params = this.parseURLParams(url);
35
+ route.urlPath = (0, _utils2.toPath)(route.urlPath, params);
36
+ route.params = params;
37
+ }
38
+
39
+ return route;
30
40
  }
31
41
 
32
42
  parseURLParams(pathname) {
@@ -84,9 +94,12 @@ class RouteMatcher {
84
94
 
85
95
  if (useReg) {
86
96
  this.urlMatcher = (0, _pathToRegexp.match)(urlPath, {
97
+ end: false,
87
98
  decode: decodeURIComponent
88
99
  });
89
- this.urlReg = (0, _pathToRegexp.pathToRegexp)(urlPath);
100
+ this.urlReg = (0, _pathToRegexp.pathToRegexp)(urlPath, [], {
101
+ end: false
102
+ });
90
103
  }
91
104
  }
92
105
 
@@ -17,6 +17,7 @@ class ModernRoute {
17
17
  this.isSSR = void 0;
18
18
  this.isSPA = void 0;
19
19
  this.enableModernMode = void 0;
20
+ this.params = {};
20
21
  this.entryName = routeSpec.entryName || '';
21
22
  this.urlPath = routeSpec.urlPath;
22
23
  this.entryPath = routeSpec.entryPath || '';
@@ -147,6 +147,8 @@ class ModernDevServer extends _modernServer.ModernServer {
147
147
  }
148
148
 
149
149
  async close() {
150
+ var _this$socketServer2;
151
+
150
152
  super.close();
151
153
  await this.watcher.close();
152
154
  await new Promise(resolve => {
@@ -158,6 +160,7 @@ class ModernDevServer extends _modernServer.ModernServer {
158
160
  resolve();
159
161
  }
160
162
  });
163
+ (_this$socketServer2 = this.socketServer) === null || _this$socketServer2 === void 0 ? void 0 : _this$socketServer2.close();
161
164
  }
162
165
 
163
166
  async createHTTPServer(handler) {
@@ -7,7 +7,7 @@ exports.Server = void 0;
7
7
 
8
8
  var _path = _interopRequireDefault(require("path"));
9
9
 
10
- var _serverPlugin = require("@modern-js/server-plugin");
10
+ var _serverCore = require("@modern-js/server-core");
11
11
 
12
12
  var _utils = require("@modern-js/utils");
13
13
 
@@ -131,22 +131,25 @@ class Server {
131
131
  const {
132
132
  options
133
133
  } = this;
134
+
135
+ _serverCore.serverManager.clear();
136
+
134
137
  (_options$plugins = options.plugins) === null || _options$plugins === void 0 ? void 0 : _options$plugins.forEach(p => {
135
- _serverPlugin.serverManager.usePlugin(p);
138
+ _serverCore.serverManager.usePlugin((0, _utils.compatRequire)(p.pluginPath));
136
139
  });
137
140
  const appContext = await this.initAppContext();
138
141
 
139
- _serverPlugin.serverManager.run(() => {
142
+ _serverCore.serverManager.run(() => {
140
143
  var _options$config$outpu;
141
144
 
142
- _core.ConfigContext.set(this.options.config);
145
+ _serverCore.ConfigContext.set(this.options.config);
143
146
 
144
- _core.AppContext.set(_objectSpread(_objectSpread({}, appContext), {}, {
147
+ _serverCore.AppContext.set(_objectSpread(_objectSpread({}, appContext), {}, {
145
148
  distDirectory: _path.default.join(options.pwd, ((_options$config$outpu = options.config.output) === null || _options$config$outpu === void 0 ? void 0 : _options$config$outpu.path) || 'dist')
146
149
  }));
147
150
  });
148
151
 
149
- return _serverPlugin.serverManager.init({});
152
+ return _serverCore.serverManager.init({});
150
153
  }
151
154
 
152
155
  async initAppContext() {
@@ -13,7 +13,7 @@ class ModernSSRServer extends _modernServer.ModernServer {
13
13
  }
14
14
 
15
15
  verifyMatch(context, matched) {
16
- if (matched.generate().isApi) {
16
+ if (matched.generate(context.url).isApi) {
17
17
  this.render404(context);
18
18
  }
19
19
  }
@@ -156,15 +156,10 @@ class ModernServer {
156
156
  this.warmupSSRBundle();
157
157
  }
158
158
 
159
- await this.prepareFrameHandler();
160
- const {
161
- favicon,
162
- faviconByEntries
163
- } = this.conf.output || {};
164
- const favicons = this.prepareFavicons(favicon, faviconByEntries); // Only work when without setting `assetPrefix`.
159
+ await this.prepareFrameHandler(); // Only work when without setting `assetPrefix`.
165
160
  // Setting `assetPrefix` means these resources should be uploaded to CDN.
166
161
 
167
- const staticPathRegExp = new RegExp(`^/(static/|upload/|favicon.ico|icon.png${favicons.length > 0 ? `|${favicons.join('|')}` : ''})`);
162
+ const staticPathRegExp = (0, _utils2.getStaticReg)(this.conf.output || {});
168
163
  this.staticFileHandler = (0, _serveFile.createStaticFileHandler)([{
169
164
  path: staticPathRegExp,
170
165
  target: distDir
@@ -388,7 +383,7 @@ class ModernServer {
388
383
  return;
389
384
  }
390
385
 
391
- const routeAPI = (0, _route2.createRouteAPI)(matched, this.router);
386
+ const routeAPI = (0, _route2.createRouteAPI)(matched, this.router, context.url);
392
387
  await this.emitRouteHook('afterMatch', {
393
388
  context,
394
389
  routeAPI
@@ -401,12 +396,15 @@ class ModernServer {
401
396
  const {
402
397
  current
403
398
  } = routeAPI;
404
- const route = current.generate();
405
- const params = current.parseURLParams(context.url);
406
- context.setParams(params); // route is api service
399
+ const route = current.generate(context.url);
400
+ context.setParams(route.params);
401
+ context.setServerData('router', {
402
+ baseUrl: route.urlPath,
403
+ params: route.params
404
+ }); // route is api service
407
405
 
408
406
  if (route.isApi) {
409
- this.handleAPI(context);
407
+ await this.handleAPI(context);
410
408
  return;
411
409
  }
412
410
 
@@ -448,6 +446,7 @@ class ModernServer {
448
446
  templateAPI
449
447
  });
450
448
  await this.injectMicroFE(context, templateAPI);
449
+ templateAPI.appendHead(`<script>window._SERVER_DATA=${JSON.stringify(context.serverData)}</script>`);
451
450
  response = templateAPI.get();
452
451
  }
453
452
 
@@ -590,7 +589,7 @@ class ModernServer {
590
589
  const matched = this.router.match(statusPage) || this.router.match(customErrorPage); // if no custom status page find
591
590
 
592
591
  if (matched) {
593
- const route = matched.generate();
592
+ const route = matched.generate(context.url);
594
593
  const {
595
594
  entryName
596
595
  } = route; // check entryName, aviod matched '/' route
@@ -616,26 +615,6 @@ class ModernServer {
616
615
  res.end((0, _utils2.createErrorDocument)(status, text));
617
616
  }
618
617
 
619
- prepareFavicons(favicon, faviconByEntries) {
620
- const faviconNames = [];
621
-
622
- if (favicon) {
623
- faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
624
- }
625
-
626
- if (faviconByEntries) {
627
- Object.keys(faviconByEntries).forEach(f => {
628
- const curFavicon = faviconByEntries[f];
629
-
630
- if (curFavicon) {
631
- faviconNames.push(curFavicon.substring(curFavicon.lastIndexOf('/') + 1));
632
- }
633
- });
634
- }
635
-
636
- return faviconNames;
637
- }
638
-
639
618
  }
640
619
  /* eslint-enable max-lines */
641
620
 
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.toMessage = exports.noop = exports.mergeExtension = exports.createMiddlewareCollecter = exports.createErrorDocument = void 0;
6
+ exports.toPath = exports.toMessage = exports.prepareFavicons = exports.noop = exports.mergeExtension = exports.getStaticReg = exports.createMiddlewareCollecter = exports.createErrorDocument = void 0;
7
+
8
+ var _pathToRegexp = require("path-to-regexp");
7
9
 
8
10
  const mergeExtension = users => {
9
11
  const output = [];
@@ -91,4 +93,51 @@ const createMiddlewareCollecter = () => {
91
93
  };
92
94
  };
93
95
 
94
- exports.createMiddlewareCollecter = createMiddlewareCollecter;
96
+ exports.createMiddlewareCollecter = createMiddlewareCollecter;
97
+
98
+ const toPath = (reg, params) => {
99
+ const fn = (0, _pathToRegexp.compile)(reg, {
100
+ encode: encodeURIComponent
101
+ });
102
+ return fn(params);
103
+ };
104
+
105
+ exports.toPath = toPath;
106
+
107
+ const getStaticReg = (output = {}) => {
108
+ const {
109
+ favicon,
110
+ faviconByEntries,
111
+ cssPath,
112
+ jsPath,
113
+ mediaPath
114
+ } = output;
115
+ const favicons = prepareFavicons(favicon, faviconByEntries);
116
+ const staticFiles = [cssPath, jsPath, mediaPath].filter(v => Boolean(v));
117
+ const staticPathRegExp = new RegExp(`^/(static/|upload/|favicon.ico|icon.png${favicons.length > 0 ? `|${favicons.join('|')}` : ''}|${staticFiles.join('|')})`);
118
+ return staticPathRegExp;
119
+ };
120
+
121
+ exports.getStaticReg = getStaticReg;
122
+
123
+ const prepareFavicons = (favicon, faviconByEntries) => {
124
+ const faviconNames = [];
125
+
126
+ if (favicon) {
127
+ faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
128
+ }
129
+
130
+ if (faviconByEntries) {
131
+ Object.keys(faviconByEntries).forEach(f => {
132
+ const curFavicon = faviconByEntries[f];
133
+
134
+ if (curFavicon) {
135
+ faviconNames.push(curFavicon.substring(curFavicon.lastIndexOf('/') + 1));
136
+ }
137
+ });
138
+ }
139
+
140
+ return faviconNames;
141
+ };
142
+
143
+ exports.prepareFavicons = prepareFavicons;