@modern-js/server 1.3.0 → 1.4.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 (121) hide show
  1. package/CHANGELOG.md +55 -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 +6 -9
  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/ssr.js +7 -2
  13. package/dist/js/modern/libs/route/index.js +0 -1
  14. package/dist/js/modern/libs/route/matcher.js +15 -3
  15. package/dist/js/modern/libs/route/route.js +1 -0
  16. package/dist/js/modern/server/dev-server/dev-server.js +18 -5
  17. package/dist/js/modern/server/index.js +5 -4
  18. package/dist/js/modern/server/modern-server-split.js +1 -1
  19. package/dist/js/modern/server/modern-server.js +9 -5
  20. package/dist/js/modern/utils.js +7 -0
  21. package/dist/js/node/dev-tools/babel/register.js +1 -0
  22. package/dist/js/node/dev-tools/dev-server-plugin.js +1 -2
  23. package/dist/js/node/dev-tools/mock/getMockData.js +29 -2
  24. package/dist/js/node/dev-tools/mock/index.js +5 -26
  25. package/dist/js/node/dev-tools/socket-server.js +4 -2
  26. package/dist/js/node/dev-tools/watcher/index.js +9 -7
  27. package/dist/js/node/dev-tools/watcher/stats-cache.js +33 -20
  28. package/dist/js/node/libs/context/context.js +6 -0
  29. package/dist/js/node/libs/hook-api/route.js +6 -4
  30. package/dist/js/node/libs/render/index.js +1 -0
  31. package/dist/js/node/libs/render/ssr.js +8 -2
  32. package/dist/js/node/libs/route/index.js +0 -1
  33. package/dist/js/node/libs/route/matcher.js +16 -3
  34. package/dist/js/node/libs/route/route.js +1 -0
  35. package/dist/js/node/server/dev-server/dev-server.js +20 -5
  36. package/dist/js/node/server/index.js +9 -6
  37. package/dist/js/node/server/modern-server-split.js +1 -1
  38. package/dist/js/node/server/modern-server.js +9 -5
  39. package/dist/js/node/utils.js +13 -2
  40. package/dist/types/dev-tools/mock/getMockData.d.ts +2 -1
  41. package/dist/types/dev-tools/socket-server.d.ts +1 -2
  42. package/dist/types/dev-tools/watcher/index.d.ts +3 -1
  43. package/dist/types/dev-tools/watcher/stats-cache.d.ts +3 -2
  44. package/dist/types/libs/context/context.d.ts +2 -0
  45. package/dist/types/libs/hook-api/route.d.ts +3 -2
  46. package/dist/types/libs/render/ssr.d.ts +1 -0
  47. package/dist/types/libs/route/matcher.d.ts +1 -1
  48. package/dist/types/libs/route/route.d.ts +1 -0
  49. package/dist/types/server/dev-server/dev-server-split.d.ts +3 -3
  50. package/dist/types/server/modern-server-split.d.ts +3 -3
  51. package/dist/types/server/modern-server.d.ts +1 -1
  52. package/dist/types/type.d.ts +6 -4
  53. package/dist/types/utils.d.ts +2 -1
  54. package/jest.config.js +1 -0
  55. package/package.json +12 -10
  56. package/tests/context.test.ts +12 -1
  57. package/tests/dev.test.ts +306 -7
  58. package/tests/fixtures/mock/exist/config/mock/index.ts +11 -0
  59. package/tests/fixtures/mock/zero/config/mock/index.ts +1 -0
  60. package/tests/fixtures/pure/tsconfig.json +0 -1
  61. package/tests/fixtures/route-spec/dynamic.json +13 -0
  62. package/tests/fixtures/ssr/bundle.js +5 -0
  63. package/tests/fixtures/watch/a.ts +3 -0
  64. package/tests/fixtures/watch/index.ts +5 -0
  65. package/tests/fixtures/watch/stats.txt +1 -0
  66. package/tests/hook.test.ts +1 -1
  67. package/tests/route.test.ts +26 -3
  68. package/tests/server.test.ts +19 -0
  69. package/tests/ssr.test.ts +34 -0
  70. package/tests/utils.test.ts +6 -0
  71. package/tests/watcher.test.ts +98 -0
  72. package/src/constants.ts +0 -26
  73. package/src/dev-tools/babel/register.ts +0 -37
  74. package/src/dev-tools/dev-server-plugin.ts +0 -48
  75. package/src/dev-tools/https/global.d.ts +0 -3
  76. package/src/dev-tools/https/index.ts +0 -12
  77. package/src/dev-tools/launch-editor/index.ts +0 -29
  78. package/src/dev-tools/mock/getMockData.ts +0 -109
  79. package/src/dev-tools/mock/index.ts +0 -63
  80. package/src/dev-tools/socket-server.ts +0 -192
  81. package/src/dev-tools/watcher/dependency-tree.ts +0 -94
  82. package/src/dev-tools/watcher/index.ts +0 -77
  83. package/src/dev-tools/watcher/stats-cache.ts +0 -53
  84. package/src/index.ts +0 -16
  85. package/src/libs/context/context.ts +0 -176
  86. package/src/libs/context/index.ts +0 -7
  87. package/src/libs/hook-api/route.ts +0 -38
  88. package/src/libs/hook-api/template.ts +0 -53
  89. package/src/libs/metrics.ts +0 -15
  90. package/src/libs/proxy.ts +0 -85
  91. package/src/libs/render/cache/__tests__/cache.fun.test.ts +0 -94
  92. package/src/libs/render/cache/__tests__/cache.test.ts +0 -240
  93. package/src/libs/render/cache/__tests__/cacheable.ts +0 -44
  94. package/src/libs/render/cache/__tests__/error-configuration.ts +0 -34
  95. package/src/libs/render/cache/__tests__/matched-cache.ts +0 -88
  96. package/src/libs/render/cache/index.ts +0 -75
  97. package/src/libs/render/cache/page-caches/index.ts +0 -11
  98. package/src/libs/render/cache/page-caches/lru.ts +0 -38
  99. package/src/libs/render/cache/spr.ts +0 -301
  100. package/src/libs/render/cache/type.ts +0 -59
  101. package/src/libs/render/cache/util.ts +0 -97
  102. package/src/libs/render/index.ts +0 -78
  103. package/src/libs/render/modern/browser-list.ts +0 -7
  104. package/src/libs/render/modern/index.ts +0 -41
  105. package/src/libs/render/modern/module.d.ts +0 -4
  106. package/src/libs/render/reader.ts +0 -119
  107. package/src/libs/render/ssr.ts +0 -62
  108. package/src/libs/render/static.ts +0 -52
  109. package/src/libs/render/type.ts +0 -38
  110. package/src/libs/route/index.ts +0 -77
  111. package/src/libs/route/matcher.ts +0 -93
  112. package/src/libs/route/route.ts +0 -32
  113. package/src/libs/serve-file.ts +0 -34
  114. package/src/server/dev-server/dev-server-split.ts +0 -41
  115. package/src/server/dev-server/dev-server.ts +0 -284
  116. package/src/server/dev-server/index.ts +0 -2
  117. package/src/server/index.ts +0 -163
  118. package/src/server/modern-server-split.ts +0 -97
  119. package/src/server/modern-server.ts +0 -636
  120. package/src/type.ts +0 -88
  121. package/src/utils.ts +0 -79
package/CHANGELOG.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # @modern-js/server
2
2
 
3
+ ## 1.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ec4dbffb: feat: support as a pure api service
8
+
9
+ ### Patch Changes
10
+
11
+ - 816fd721: support more server context
12
+ - d9cc5ea9: support resatrt options transfer
13
+ - bfbea9a7: support multi base url and dynamic base url
14
+ - d099e5c5: fix error when modify modern.config.js
15
+ - 24f616ca: feat: support custom meta info
16
+ - 272cab15: refactor server plugin manager
17
+ - Updated dependencies [d9cc5ea9]
18
+ - Updated dependencies [bd819a8d]
19
+ - Updated dependencies [ec4dbffb]
20
+ - Updated dependencies [d099e5c5]
21
+ - Updated dependencies [bada2879]
22
+ - Updated dependencies [24f616ca]
23
+ - Updated dependencies [bd819a8d]
24
+ - Updated dependencies [272cab15]
25
+ - @modern-js/core@1.4.0
26
+ - @modern-js/utils@1.3.0
27
+ - @modern-js/server-core@1.2.2
28
+
29
+ ## 1.3.2
30
+
31
+ ### Patch Changes
32
+
33
+ - 83166714: change .npmignore
34
+ - Updated dependencies [83166714]
35
+ - Updated dependencies [c3de9882]
36
+ - Updated dependencies [33ff48af]
37
+ - @modern-js/core@1.3.2
38
+ - @modern-js/bff-utils@1.2.2
39
+ - @modern-js/hmr-client@1.2.1
40
+ - @modern-js/server-plugin@1.2.1
41
+ - @modern-js/server-utils@1.2.1
42
+ - @modern-js/utils@1.2.2
43
+
44
+ ## 1.3.1
45
+
46
+ ### Patch Changes
47
+
48
+ - e2d3a575: fix extending core config interface
49
+ - 823809c6: fix: hot reload not working on windows
50
+ - e2d3a575: fix extending core config interface
51
+ - Updated dependencies [823809c6]
52
+ - Updated dependencies [4584cc04]
53
+ - Updated dependencies [7c19fd94]
54
+ - @modern-js/bff-utils@1.2.1
55
+ - @modern-js/utils@1.2.1
56
+ - @modern-js/core@1.3.1
57
+
3
58
  ## 1.3.0
4
59
 
5
60
  ### Minor Changes
@@ -18,6 +18,7 @@ export const enableRegister = (projectRoot, config) => {
18
18
  return require('@babel/register')(_objectSpread(_objectSpread({}, babelConfig), {}, {
19
19
  only: [function (filePath) {
20
20
  // TODO: wait params
21
+ // FIXME: 删除hardcode,根据 AppContext 中的 metaName 设置路径
21
22
  if (filePath.includes(`node_modules${path.sep}.modern-js`)) {
22
23
  return true;
23
24
  }
@@ -14,8 +14,7 @@ export default class DevServerPlugin {
14
14
  } = this;
15
15
  const host = `&host=${options.client.host || 'localhost'}`;
16
16
  const path = `&path=${options.client.path}`;
17
- const port = `&port=${options.client.port}`; // Todo @songzhenwei
18
-
17
+ const port = `&port=${options.client.port}`;
19
18
  const clientEntry = `${require.resolve('@modern-js/hmr-client')}?${host}${path}${port}`;
20
19
 
21
20
  const hotEntry = require.resolve('webpack/hot/dev-server');
@@ -5,6 +5,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
5
5
  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; }
6
6
 
7
7
  import { compatRequire } from '@modern-js/utils';
8
+ import { match } from 'path-to-regexp';
8
9
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
9
10
  const VALID_METHODS = ['get', 'post', 'put', 'delete', 'patch']; // eslint-disable-next-line @typescript-eslint/no-unused-vars
10
11
 
@@ -81,4 +82,26 @@ export default (filepath => {
81
82
 
82
83
  const data = normalizeConfig(mockModule);
83
84
  return data;
84
- });
85
+ });
86
+ export const getMatched = (context, mockApiList) => {
87
+ const {
88
+ path: targetPathname,
89
+ method: targetMethod
90
+ } = context;
91
+ const matched = mockApiList.find(mockApi => {
92
+ const {
93
+ method,
94
+ path: pathname
95
+ } = mockApi;
96
+
97
+ if (method.toLowerCase() === targetMethod.toLowerCase()) {
98
+ return match(pathname, {
99
+ encode: encodeURI,
100
+ decode: decodeURIComponent
101
+ })(targetPathname);
102
+ }
103
+
104
+ return false;
105
+ });
106
+ return matched;
107
+ };
@@ -1,32 +1,7 @@
1
1
  import path from 'path';
2
2
  import { fs } from '@modern-js/utils';
3
- import { match } from 'path-to-regexp';
4
3
  import { AGGRED_DIR } from "../../constants";
5
- import getMockData from "./getMockData";
6
-
7
- const getMatched = (context, mockApiList) => {
8
- const {
9
- path: targetPathname,
10
- method: targetMethod
11
- } = context;
12
- const matched = mockApiList.find(mockApi => {
13
- const {
14
- method,
15
- path: pathname
16
- } = mockApi;
17
-
18
- if (method.toLowerCase() === targetMethod.toLowerCase()) {
19
- return match(pathname, {
20
- encode: encodeURI,
21
- decode: decodeURIComponent
22
- })(targetPathname);
23
- }
24
-
25
- return false;
26
- });
27
- return matched;
28
- };
29
-
4
+ import getMockData, { getMatched } from "./getMockData";
30
5
  export const createMockHandler = ({
31
6
  pwd
32
7
  }) => {
@@ -106,8 +106,10 @@ export default class SocketServer {
106
106
  });
107
107
  }
108
108
 
109
- close(connection) {
110
- connection.close();
109
+ close() {
110
+ this.sockets.forEach(socket => {
111
+ socket.close();
112
+ });
111
113
  } // get standard stats
112
114
 
113
115
 
@@ -1,31 +1,28 @@
1
+ import path from 'path';
1
2
  import chokidar from 'chokidar';
2
3
  import { DependencyTree } from "./dependency-tree";
3
4
  import { StatsCache } from "./stats-cache";
4
-
5
- const getWatchedFiles = watcher => {
5
+ export const getWatchedFiles = watcher => {
6
6
  const watched = watcher.getWatched();
7
7
  const files = [];
8
8
  Object.keys(watched).forEach(dir => {
9
9
  watched[dir].forEach(fileName => {
10
- files.push(`${dir}/${fileName}`);
10
+ files.push(path.join(dir, fileName));
11
11
  });
12
12
  });
13
13
  return files;
14
14
  };
15
-
16
15
  export default class Watcher {
17
16
  constructor() {
18
17
  this.dependencyTree = null;
19
18
  this.watcher = void 0;
20
19
  }
21
20
 
22
- listen(files, callback) {
21
+ listen(files, options, callback) {
23
22
  const watched = files.filter(Boolean);
23
+ const filenames = watched.map(filename => filename.replace(/\\/g, '/'));
24
24
  const cache = new StatsCache();
25
- const watcher = chokidar.watch(watched, {
26
- // 初始化的时候不触发 add、addDir 事件
27
- ignoreInitial: true
28
- });
25
+ const watcher = chokidar.watch(filenames, options);
29
26
  watcher.on('ready', () => {
30
27
  cache.add(getWatchedFiles(watcher));
31
28
  });
@@ -1,20 +1,24 @@
1
1
  import fs from 'fs';
2
+ import crypto from 'crypto';
2
3
  export class StatsCache {
3
4
  constructor() {
4
- this.cachedStats = {};
5
+ this.cachedHash = {};
6
+ this.cachedSize = {};
5
7
  }
6
8
 
7
9
  add(files) {
8
10
  const {
9
- cachedStats
11
+ cachedHash,
12
+ cachedSize
10
13
  } = this;
11
14
 
12
15
  for (const filename of files) {
13
16
  if (fs.existsSync(filename)) {
14
- const stat = fs.statSync(filename);
17
+ const stats = fs.statSync(filename);
15
18
 
16
- if (stat.isFile() && !cachedStats[filename]) {
17
- cachedStats[filename] = this.sign(stat);
19
+ if (stats.isFile() && !cachedHash[filename]) {
20
+ cachedHash[filename] = this.hash(stats, filename);
21
+ cachedSize[filename] = stats.size;
18
22
  }
19
23
  }
20
24
  }
@@ -22,32 +26,41 @@ export class StatsCache {
22
26
 
23
27
  refresh(filename) {
24
28
  const {
25
- cachedStats
29
+ cachedHash,
30
+ cachedSize
26
31
  } = this;
27
32
 
28
33
  if (fs.existsSync(filename)) {
29
- const stat = fs.statSync(filename);
34
+ const stats = fs.statSync(filename);
30
35
 
31
- if (stat.isFile()) {
32
- cachedStats[filename] = this.sign(stat);
36
+ if (stats.isFile()) {
37
+ cachedHash[filename] = this.hash(stats, filename);
38
+ cachedSize[filename] = stats.size;
33
39
  }
34
40
  }
35
41
  }
36
42
 
37
43
  del(filename) {
38
- if (this.cachedStats[filename]) {
39
- delete this.cachedStats[filename];
44
+ if (this.cachedHash[filename]) {
45
+ delete this.cachedHash[filename];
46
+ delete this.cachedSize[filename];
40
47
  }
41
48
  }
42
49
 
43
50
  isDiff(filename) {
44
51
  const {
45
- cachedStats
52
+ cachedHash,
53
+ cachedSize
46
54
  } = this;
47
- const stat = fs.statSync(filename);
48
- const cachedStat = cachedStats[filename];
55
+ const stats = fs.statSync(filename);
56
+ const hash = cachedHash[filename];
57
+ const size = cachedSize[filename];
49
58
 
50
- if (this.sign(stat) !== cachedStat) {
59
+ if (stats.size !== size) {
60
+ return true;
61
+ }
62
+
63
+ if (this.hash(stats, filename) !== hash) {
51
64
  return true;
52
65
  }
53
66
 
@@ -55,12 +68,11 @@ export class StatsCache {
55
68
  }
56
69
 
57
70
  has(filename) {
58
- return Boolean(this.cachedStats[filename]);
59
- } // Todo size 其实有点问题,修改单个字符会导致触发不了 change
60
-
71
+ return Boolean(this.cachedHash[filename]);
72
+ }
61
73
 
62
- sign(stat) {
63
- return stat.size;
74
+ hash(stats, filename) {
75
+ return crypto.createHash('md5').update(fs.readFileSync(filename)).digest('hex');
64
76
  }
65
77
 
66
78
  }
@@ -19,10 +19,12 @@ export class ModernServerContext {
19
19
  this.params = {};
20
20
  this.logger = void 0;
21
21
  this.metrics = void 0;
22
+ this.serverData = void 0;
22
23
  this.req = req;
23
24
  this.res = res;
24
25
  this.logger = req.logger;
25
26
  this.metrics = req.metrics;
27
+ this.serverData = {};
26
28
  this.bind();
27
29
  }
28
30
 
@@ -41,6 +43,10 @@ export class ModernServerContext {
41
43
  this.params = params;
42
44
  }
43
45
 
46
+ setServerData(key, value) {
47
+ this.serverData[key] = value;
48
+ }
49
+
44
50
  getReqHeader(key) {
45
51
  const {
46
52
  req
@@ -1,13 +1,15 @@
1
1
  class RouteAPI {
2
- constructor(matched, router) {
2
+ constructor(matched, router, url) {
3
3
  this.router = void 0;
4
4
  this.current = void 0;
5
+ this.url = void 0;
5
6
  this.current = matched;
6
7
  this.router = router;
8
+ this.url = url;
7
9
  }
8
10
 
9
11
  cur() {
10
- return this.current.generate();
12
+ return this.current.generate(this.url);
11
13
  }
12
14
 
13
15
  get(entryName) {
@@ -15,7 +17,7 @@ class RouteAPI {
15
17
  router
16
18
  } = this;
17
19
  const matched = router.matchEntry(entryName);
18
- return matched ? matched.generate() : null;
20
+ return matched ? matched.generate(this.url) : null;
19
21
  }
20
22
 
21
23
  use(entryName) {
@@ -34,4 +36,4 @@ class RouteAPI {
34
36
 
35
37
  }
36
38
 
37
- export const createRouteAPI = (matched, router) => new RouteAPI(matched, router);
39
+ export const createRouteAPI = (matched, router, url) => new RouteAPI(matched, router, url);
@@ -40,6 +40,7 @@ export const createRenderHandler = ({
40
40
  const result = await ssr.render(ctx, {
41
41
  distDir,
42
42
  entryName: route.entryName,
43
+ urlPath: route.urlPath,
43
44
  bundle: route.bundle,
44
45
  template: templateHTML,
45
46
  staticGenerate
@@ -1,9 +1,11 @@
1
1
  import path from 'path';
2
2
  import { SERVER_RENDER_FUNCTION_NAME } from '@modern-js/utils';
3
3
  import mime from 'mime-types';
4
+ import cookie from 'cookie';
4
5
  import cache from "./cache";
5
6
  export const render = async (ctx, renderOptions, runner) => {
6
7
  const {
8
+ urlPath,
7
9
  bundle,
8
10
  distDir,
9
11
  template,
@@ -13,11 +15,14 @@ export const render = async (ctx, renderOptions, runner) => {
13
15
  const bundleJS = path.join(distDir, bundle);
14
16
  const context = {
15
17
  request: {
18
+ baseUrl: urlPath,
16
19
  params: ctx.params,
17
20
  pathname: ctx.path,
21
+ host: ctx.host,
18
22
  query: ctx.query,
19
- headers: ctx.headers,
20
- cookie: ctx.headers.cookie
23
+ url: ctx.href,
24
+ cookieMap: cookie.parse(ctx.headers.cookie || ''),
25
+ headers: ctx.headers
21
26
  },
22
27
  redirection: {},
23
28
  template,
@@ -9,7 +9,6 @@ export class RouteMatchManager {
9
9
 
10
10
  filter(pathname) {
11
11
  return this.matchers.reduce((matches, matcher) => {
12
- // 非网关来的,或网关匹配上之后,内部再进行一次自己的匹配
13
12
  if (matcher.matchUrlPath(pathname)) {
14
13
  matches.push(matcher);
15
14
  }
@@ -1,5 +1,6 @@
1
1
  import { removeTailSlash } from '@modern-js/utils';
2
2
  import { match, pathToRegexp } from 'path-to-regexp';
3
+ import { toPath } from "../../utils";
3
4
  import { ModernRoute } from "./route"; // eslint-disable-next-line no-useless-escape
4
5
 
5
6
  const regCharsDetector = /[^a-zA-Z\-_0-9\/\.]/;
@@ -14,8 +15,16 @@ export class RouteMatcher {
14
15
  } // generate modern route object
15
16
 
16
17
 
17
- generate() {
18
- return new ModernRoute(this.spec);
18
+ generate(url) {
19
+ const route = new ModernRoute(this.spec);
20
+
21
+ if (this.urlPath) {
22
+ const params = this.parseURLParams(url);
23
+ route.urlPath = toPath(route.urlPath, params);
24
+ route.params = params;
25
+ }
26
+
27
+ return route;
19
28
  }
20
29
 
21
30
  parseURLParams(pathname) {
@@ -73,9 +82,12 @@ export class RouteMatcher {
73
82
 
74
83
  if (useReg) {
75
84
  this.urlMatcher = match(urlPath, {
85
+ end: false,
76
86
  decode: decodeURIComponent
77
87
  });
78
- this.urlReg = pathToRegexp(urlPath);
88
+ this.urlReg = pathToRegexp(urlPath, [], {
89
+ end: false
90
+ });
79
91
  }
80
92
  }
81
93
 
@@ -10,6 +10,7 @@ export class ModernRoute {
10
10
  this.isSSR = void 0;
11
11
  this.isSPA = void 0;
12
12
  this.enableModernMode = void 0;
13
+ this.params = {};
13
14
  this.entryName = routeSpec.entryName || '';
14
15
  this.urlPath = routeSpec.urlPath;
15
16
  this.entryPath = routeSpec.entryPath || '';
@@ -118,13 +118,20 @@ export class ModernDevServer extends ModernServer {
118
118
  }
119
119
 
120
120
  async close() {
121
+ var _this$socketServer2;
122
+
121
123
  super.close();
122
124
  await this.watcher.close();
123
125
  await new Promise(resolve => {
124
- this.devMiddleware.close(() => {
126
+ if (this.devMiddleware) {
127
+ this.devMiddleware.close(() => {
128
+ resolve();
129
+ });
130
+ } else {
125
131
  resolve();
126
- });
132
+ }
127
133
  });
134
+ (_this$socketServer2 = this.socketServer) === null || _this$socketServer2 === void 0 ? void 0 : _this$socketServer2.close();
128
135
  }
129
136
 
130
137
  async createHTTPServer(handler) {
@@ -239,16 +246,22 @@ export class ModernDevServer extends ModernServer {
239
246
  const {
240
247
  mock
241
248
  } = AGGRED_DIR;
242
- const defaultWatched = [`${pwd}/${mock}/**/*`, `${pwd}/${SERVER_DIR}/**/*`, `${pwd}/${API_DIR}/!(typings)/**`, `${pwd}/${SHARED_DIR}/**/*`];
249
+ const defaultWatched = [`${mock}/**/*`, `${SERVER_DIR}/**/*`, `${API_DIR}/**`, `${SHARED_DIR}/**/*`];
250
+ const defaultWatchedPaths = defaultWatched.map(p => path.normalize(path.join(pwd, p)));
251
+ const mockPath = path.normalize(path.join(pwd, mock));
243
252
  const watcher = new Watcher();
244
253
  watcher.createDepTree(); // 监听文件变动,如果有变动则给 client,也就是 start 启动的插件发消息
245
254
 
246
- watcher.listen(defaultWatched, filepath => {
255
+ watcher.listen(defaultWatchedPaths, {
256
+ // 初始化的时候不触发 add、addDir 事件
257
+ ignoreInitial: true,
258
+ ignored: /api\/typings\/.*/
259
+ }, filepath => {
247
260
  watcher.updateDepTree();
248
261
  watcher.cleanDepCache(filepath);
249
262
  this.runner.reset();
250
263
 
251
- if (filepath.startsWith(`${pwd}/${mock}`)) {
264
+ if (filepath.startsWith(mockPath)) {
252
265
  this.mockHandler = createMockHandler({
253
266
  pwd
254
267
  });
@@ -5,9 +5,9 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
5
5
  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; }
6
6
 
7
7
  import path from 'path';
8
- import { serverManager } from '@modern-js/server-plugin';
9
- import { logger as defaultLogger } from '@modern-js/utils';
10
- import { AppContext, initAppContext, initAppDir, loadUserConfig, ConfigContext } from '@modern-js/core';
8
+ import { serverManager, AppContext, ConfigContext } from '@modern-js/server-core';
9
+ import { compatRequire, logger as defaultLogger } from '@modern-js/utils';
10
+ import { initAppContext, initAppDir, loadUserConfig } from '@modern-js/core';
11
11
  import { metrics as defaultMetrics } from "../libs/metrics";
12
12
  import { ModernServer } from "./modern-server";
13
13
  import { ModernAPIServer, ModernSSRServer, ModernWebServer } from "./modern-server-split";
@@ -115,8 +115,9 @@ export class Server {
115
115
  const {
116
116
  options
117
117
  } = this;
118
+ serverManager.clear();
118
119
  (_options$plugins = options.plugins) === null || _options$plugins === void 0 ? void 0 : _options$plugins.forEach(p => {
119
- serverManager.usePlugin(p);
120
+ serverManager.usePlugin(compatRequire(p.pluginPath));
120
121
  });
121
122
  const appContext = await this.initAppContext();
122
123
  serverManager.run(() => {
@@ -5,7 +5,7 @@ export class ModernSSRServer extends ModernServer {
5
5
  }
6
6
 
7
7
  verifyMatch(context, matched) {
8
- if (matched.generate().isApi) {
8
+ if (matched.generate(context.url).isApi) {
9
9
  this.render404(context);
10
10
  }
11
11
  }
@@ -353,7 +353,7 @@ export class ModernServer {
353
353
  return;
354
354
  }
355
355
 
356
- const routeAPI = createRouteAPI(matched, this.router);
356
+ const routeAPI = createRouteAPI(matched, this.router, context.url);
357
357
  await this.emitRouteHook('afterMatch', {
358
358
  context,
359
359
  routeAPI
@@ -366,9 +366,12 @@ export class ModernServer {
366
366
  const {
367
367
  current
368
368
  } = routeAPI;
369
- const route = current.generate();
370
- const params = current.parseURLParams(context.url);
371
- context.setParams(params); // route is api service
369
+ const route = current.generate(context.url);
370
+ context.setParams(route.params);
371
+ context.setServerData('router', {
372
+ baseUrl: route.urlPath,
373
+ params: route.params
374
+ }); // route is api service
372
375
 
373
376
  if (route.isApi) {
374
377
  this.handleAPI(context);
@@ -413,6 +416,7 @@ export class ModernServer {
413
416
  templateAPI
414
417
  });
415
418
  await this.injectMicroFE(context, templateAPI);
419
+ templateAPI.appendHead(`<script>window._SERVER_DATA=${JSON.stringify(context.serverData)}</script>`);
416
420
  response = templateAPI.get();
417
421
  }
418
422
 
@@ -555,7 +559,7 @@ export class ModernServer {
555
559
  const matched = this.router.match(statusPage) || this.router.match(customErrorPage); // if no custom status page find
556
560
 
557
561
  if (matched) {
558
- const route = matched.generate();
562
+ const route = matched.generate(context.url);
559
563
  const {
560
564
  entryName
561
565
  } = route; // check entryName, aviod matched '/' route
@@ -1,3 +1,4 @@
1
+ import { compile } from 'path-to-regexp';
1
2
  export const mergeExtension = users => {
2
3
  const output = [];
3
4
  return {
@@ -70,4 +71,10 @@ export const createMiddlewareCollecter = () => {
70
71
  addWebMiddleware,
71
72
  addAPIMiddleware
72
73
  };
74
+ };
75
+ export const toPath = (reg, params) => {
76
+ const fn = compile(reg, {
77
+ encode: encodeURIComponent
78
+ });
79
+ return fn(params);
73
80
  };
@@ -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;