@modern-js/app-tools 1.21.5 → 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.
Files changed (170) hide show
  1. package/CHANGELOG.md +319 -51
  2. package/dist/js/modern/analyze/constants.js +1 -0
  3. package/dist/js/modern/analyze/generateCode.js +126 -32
  4. package/dist/js/modern/analyze/getBundleEntry.js +7 -14
  5. package/dist/js/modern/analyze/getClientRoutes/getRoutes.js +173 -0
  6. package/dist/js/modern/analyze/{getClientRoutes.js → getClientRoutes/getRoutesLegacy.js} +13 -58
  7. package/dist/js/modern/analyze/getClientRoutes/index.js +2 -0
  8. package/dist/js/modern/analyze/getClientRoutes/utils.js +18 -0
  9. package/dist/js/modern/analyze/getFileSystemEntry.js +27 -21
  10. package/dist/js/modern/analyze/getHtmlTemplate.js +2 -9
  11. package/dist/js/modern/analyze/getServerRoutes.js +15 -32
  12. package/dist/js/modern/analyze/index.js +81 -23
  13. package/dist/js/modern/analyze/isDefaultExportFunction.js +0 -4
  14. package/dist/js/modern/analyze/makeLegalIdentifier.js +0 -2
  15. package/dist/js/modern/analyze/nestedRoutes.js +102 -0
  16. package/dist/js/modern/analyze/templates.js +151 -12
  17. package/dist/js/modern/analyze/utils.js +2 -8
  18. package/dist/js/modern/builder/builderPlugins/compatModern.js +208 -0
  19. package/dist/js/modern/builder/createHtmlConfig.js +58 -0
  20. package/dist/js/modern/builder/createOutputConfig.js +70 -0
  21. package/dist/js/modern/builder/createSourceConfig.js +74 -0
  22. package/dist/js/modern/builder/createToolsConfig.js +87 -0
  23. package/dist/js/modern/builder/index.js +108 -0
  24. package/dist/js/modern/builder/share.js +44 -0
  25. package/dist/js/modern/builder/webpackPlugins/htmlAsyncChunkPlugin.js +29 -0
  26. package/dist/js/modern/builder/webpackPlugins/htmlBottomTemplate.js +33 -0
  27. package/dist/js/modern/builder/webpackPlugins/routerPlugin.js +97 -0
  28. package/dist/js/modern/commands/build.js +16 -110
  29. package/dist/js/modern/commands/dev.js +12 -28
  30. package/dist/js/modern/commands/inspect.js +8 -66
  31. package/dist/js/modern/commands/start.js +2 -3
  32. package/dist/js/modern/index.js +17 -16
  33. package/dist/js/modern/locale/en.js +0 -1
  34. package/dist/js/modern/locale/zh.js +0 -1
  35. package/dist/js/modern/utils/commands.js +5 -0
  36. package/dist/js/modern/utils/config.js +1 -12
  37. package/dist/js/modern/utils/createServer.js +12 -1
  38. package/dist/js/modern/utils/getSpecifiedEntries.js +0 -6
  39. package/dist/js/modern/utils/printInstructions.js +3 -2
  40. package/dist/js/modern/utils/routes.js +0 -2
  41. package/dist/js/node/analyze/constants.js +3 -1
  42. package/dist/js/node/analyze/generateCode.js +123 -47
  43. package/dist/js/node/analyze/getBundleEntry.js +7 -20
  44. package/dist/js/node/analyze/getClientRoutes/getRoutes.js +181 -0
  45. package/dist/js/node/analyze/{getClientRoutes.js → getClientRoutes/getRoutesLegacy.js} +19 -78
  46. package/dist/js/node/analyze/getClientRoutes/index.js +19 -0
  47. package/dist/js/node/analyze/getClientRoutes/utils.js +28 -0
  48. package/dist/js/node/analyze/getFileSystemEntry.js +26 -28
  49. package/dist/js/node/analyze/getHtmlTemplate.js +2 -23
  50. package/dist/js/node/analyze/getServerRoutes.js +14 -40
  51. package/dist/js/node/analyze/index.js +81 -33
  52. package/dist/js/node/analyze/isDefaultExportFunction.js +0 -12
  53. package/dist/js/node/analyze/makeLegalIdentifier.js +0 -4
  54. package/dist/js/node/analyze/nestedRoutes.js +111 -0
  55. package/dist/js/node/analyze/templates.js +153 -21
  56. package/dist/js/node/analyze/utils.js +4 -20
  57. package/dist/js/node/builder/builderPlugins/compatModern.js +216 -0
  58. package/dist/js/node/builder/createHtmlConfig.js +68 -0
  59. package/dist/js/node/builder/createOutputConfig.js +76 -0
  60. package/dist/js/node/builder/createSourceConfig.js +82 -0
  61. package/dist/js/node/builder/createToolsConfig.js +94 -0
  62. package/dist/js/node/builder/index.js +117 -0
  63. package/dist/js/node/builder/share.js +51 -0
  64. package/dist/js/node/builder/webpackPlugins/htmlAsyncChunkPlugin.js +36 -0
  65. package/dist/js/node/builder/webpackPlugins/htmlBottomTemplate.js +40 -0
  66. package/dist/js/node/builder/webpackPlugins/routerPlugin.js +105 -0
  67. package/dist/js/node/commands/build.js +14 -121
  68. package/dist/js/node/commands/deploy.js +0 -2
  69. package/dist/js/node/commands/dev.js +10 -44
  70. package/dist/js/node/commands/index.js +0 -6
  71. package/dist/js/node/commands/inspect.js +10 -90
  72. package/dist/js/node/commands/start.js +2 -11
  73. package/dist/js/node/exports/server.js +0 -1
  74. package/dist/js/node/hooks.js +0 -2
  75. package/dist/js/node/index.js +22 -32
  76. package/dist/js/node/locale/en.js +0 -1
  77. package/dist/js/node/locale/index.js +0 -4
  78. package/dist/js/node/locale/zh.js +0 -1
  79. package/dist/js/node/utils/commands.js +12 -0
  80. package/dist/js/node/utils/config.js +1 -25
  81. package/dist/js/node/utils/createServer.js +15 -11
  82. package/dist/js/node/utils/getSpecifiedEntries.js +0 -9
  83. package/dist/js/node/utils/language.js +0 -2
  84. package/dist/js/node/utils/printInstructions.js +3 -6
  85. package/dist/js/node/utils/routes.js +0 -5
  86. package/dist/js/treeshaking/analyze/constants.js +16 -0
  87. package/dist/js/treeshaking/analyze/generateCode.js +369 -0
  88. package/dist/js/treeshaking/analyze/getBundleEntry.js +69 -0
  89. package/dist/js/treeshaking/analyze/getClientRoutes/getRoutes.js +184 -0
  90. package/dist/js/treeshaking/analyze/getClientRoutes/getRoutesLegacy.js +185 -0
  91. package/dist/js/treeshaking/analyze/getClientRoutes/index.js +2 -0
  92. package/dist/js/treeshaking/analyze/getClientRoutes/utils.js +24 -0
  93. package/dist/js/treeshaking/analyze/getFileSystemEntry.js +96 -0
  94. package/dist/js/treeshaking/analyze/getHtmlTemplate.js +129 -0
  95. package/dist/js/treeshaking/analyze/getServerRoutes.js +157 -0
  96. package/dist/js/treeshaking/analyze/index.js +334 -0
  97. package/dist/js/treeshaking/analyze/isDefaultExportFunction.js +28 -0
  98. package/dist/js/treeshaking/analyze/makeLegalIdentifier.js +16 -0
  99. package/dist/js/treeshaking/analyze/nestedRoutes.js +165 -0
  100. package/dist/js/treeshaking/analyze/templates.js +170 -0
  101. package/dist/js/treeshaking/analyze/utils.js +88 -0
  102. package/dist/js/treeshaking/builder/builderPlugins/compatModern.js +212 -0
  103. package/dist/js/treeshaking/builder/createHtmlConfig.js +59 -0
  104. package/dist/js/treeshaking/builder/createOutputConfig.js +70 -0
  105. package/dist/js/treeshaking/builder/createSourceConfig.js +88 -0
  106. package/dist/js/treeshaking/builder/createToolsConfig.js +85 -0
  107. package/dist/js/treeshaking/builder/index.js +161 -0
  108. package/dist/js/treeshaking/builder/share.js +46 -0
  109. package/dist/js/treeshaking/builder/webpackPlugins/htmlAsyncChunkPlugin.js +46 -0
  110. package/dist/js/treeshaking/builder/webpackPlugins/htmlBottomTemplate.js +41 -0
  111. package/dist/js/treeshaking/builder/webpackPlugins/routerPlugin.js +121 -0
  112. package/dist/js/treeshaking/commands/build.js +83 -0
  113. package/dist/js/treeshaking/commands/deploy.js +26 -0
  114. package/dist/js/treeshaking/commands/dev.js +124 -0
  115. package/dist/js/treeshaking/commands/index.js +3 -0
  116. package/dist/js/treeshaking/commands/inspect.js +29 -0
  117. package/dist/js/treeshaking/commands/start.js +69 -0
  118. package/dist/js/treeshaking/exports/server.js +1 -0
  119. package/dist/js/treeshaking/hooks.js +21 -0
  120. package/dist/js/treeshaking/index.js +267 -0
  121. package/dist/js/treeshaking/locale/en.js +34 -0
  122. package/dist/js/treeshaking/locale/index.js +9 -0
  123. package/dist/js/treeshaking/locale/zh.js +34 -0
  124. package/dist/js/treeshaking/utils/commands.js +5 -0
  125. package/dist/js/treeshaking/utils/config.js +124 -0
  126. package/dist/js/treeshaking/utils/createServer.js +73 -0
  127. package/dist/js/treeshaking/utils/getSpecifiedEntries.js +58 -0
  128. package/dist/js/treeshaking/utils/language.js +5 -0
  129. package/dist/js/treeshaking/utils/printInstructions.js +30 -0
  130. package/dist/js/treeshaking/utils/routes.js +29 -0
  131. package/dist/js/treeshaking/utils/types.js +0 -0
  132. package/dist/types/analyze/constants.d.ts +1 -0
  133. package/dist/types/analyze/generateCode.d.ts +1 -1
  134. package/dist/types/analyze/{getClientRoutes.d.ts → getClientRoutes/getRoutes.d.ts} +2 -7
  135. package/dist/types/analyze/getClientRoutes/getRoutesLegacy.d.ts +15 -0
  136. package/dist/types/analyze/getClientRoutes/index.d.ts +2 -0
  137. package/dist/types/analyze/getClientRoutes/utils.d.ts +5 -0
  138. package/dist/types/analyze/index.d.ts +4 -5
  139. package/dist/types/analyze/nestedRoutes.d.ts +5 -0
  140. package/dist/types/analyze/templates.d.ts +19 -3
  141. package/dist/types/analyze/utils.d.ts +2 -1
  142. package/dist/types/builder/builderPlugins/compatModern.d.ts +13 -0
  143. package/dist/types/builder/createHtmlConfig.d.ts +6 -0
  144. package/dist/types/builder/createOutputConfig.d.ts +3 -0
  145. package/dist/types/builder/createSourceConfig.d.ts +5 -0
  146. package/dist/types/builder/createToolsConfig.d.ts +13 -0
  147. package/dist/types/builder/index.d.ts +15 -0
  148. package/dist/types/builder/share.d.ts +26 -0
  149. package/dist/types/builder/webpackPlugins/htmlAsyncChunkPlugin.d.ts +8 -0
  150. package/dist/types/builder/webpackPlugins/htmlBottomTemplate.d.ts +10 -0
  151. package/dist/types/builder/webpackPlugins/routerPlugin.d.ts +10 -0
  152. package/dist/types/commands/build.d.ts +2 -1
  153. package/dist/types/commands/deploy.d.ts +2 -1
  154. package/dist/types/commands/dev.d.ts +2 -1
  155. package/dist/types/commands/inspect.d.ts +2 -6
  156. package/dist/types/commands/start.d.ts +2 -1
  157. package/dist/types/hooks.d.ts +15 -10
  158. package/dist/types/index.d.ts +4 -4
  159. package/dist/types/locale/en.d.ts +0 -1
  160. package/dist/types/locale/index.d.ts +0 -2
  161. package/dist/types/locale/zh.d.ts +0 -1
  162. package/dist/types/utils/commands.d.ts +1 -0
  163. package/dist/types/utils/config.d.ts +0 -1
  164. package/dist/types/utils/createServer.d.ts +8 -1
  165. package/dist/types/utils/printInstructions.d.ts +3 -2
  166. package/dist/types/utils/types.d.ts +2 -3
  167. package/package.json +25 -42
  168. package/dist/js/modern/utils/createCompiler.js +0 -61
  169. package/dist/js/node/utils/createCompiler.js +0 -81
  170. package/dist/types/utils/createCompiler.d.ts +0 -13
@@ -2,30 +2,24 @@ import path from 'path';
2
2
  import { ensureAbsolutePath, fs, findExists, MAIN_ENTRY_NAME } from '@modern-js/utils';
3
3
  import { getFileSystemEntry } from "./getFileSystemEntry";
4
4
  import { JS_EXTENSIONS } from "./constants";
5
-
6
5
  const ensureExtensions = file => {
7
6
  if (!path.extname(file)) {
8
7
  return findExists(JS_EXTENSIONS.map(ext => `${file}${ext}`)) || file;
9
8
  }
10
-
11
9
  return file;
12
10
  };
13
-
14
11
  const ifAlreadyExists = (entrypoints, checked) => entrypoints.some(entrypoint => {
15
12
  if (ensureExtensions(entrypoint.entry) === ensureExtensions(checked.entry)) {
16
13
  // reset entryName
17
14
  checked.entryName = entrypoint.entryName;
18
15
  return true;
19
- } // filesystem routes entrypoint conflict with normal entrypoint.
20
-
21
-
16
+ }
17
+ // filesystem routes entrypoint conflict with normal entrypoint.
22
18
  if (entrypoint.entry.startsWith(checked.entry) || checked.entry.startsWith(entrypoint.entry)) {
23
19
  throw new Error(`Entry configuration conflicts\n Your configuration: ${checked.entry}.\n Default entrypoint: ${entrypoint.entry}\n Please reset source.entries or set source.disableDefaultEntries to disable the default entry rules.`);
24
20
  }
25
-
26
21
  return false;
27
22
  });
28
-
29
23
  export const getBundleEntry = (appContext, config) => {
30
24
  const {
31
25
  appDirectory,
@@ -38,8 +32,9 @@ export const getBundleEntry = (appContext, config) => {
38
32
  entriesDir
39
33
  }
40
34
  } = config;
41
- const defaults = disableDefaultEntries ? [] : getFileSystemEntry(appContext, config); // merge entrypoints from user config with directory convention.
35
+ const defaults = disableDefaultEntries ? [] : getFileSystemEntry(appContext, config);
42
36
 
37
+ // merge entrypoints from user config with directory convention.
43
38
  if (entries) {
44
39
  Object.keys(entries).forEach(name => {
45
40
  const value = entries[name];
@@ -54,22 +49,20 @@ export const getBundleEntry = (appContext, config) => {
54
49
  isAutoMount: !value.disableMount,
55
50
  fileSystemRoutes: value.enableFileSystemRoutes ? {} : undefined
56
51
  };
57
-
58
52
  if (!ifAlreadyExists(defaults, entrypoint)) {
59
53
  defaults.push(entrypoint);
60
54
  }
61
55
  });
62
56
  }
63
-
64
57
  if (!disableDefaultEntries) {
65
58
  // find main entry point which server route is '/'.
66
59
  const entriesDirAbs = ensureAbsolutePath(appDirectory, entriesDir);
67
60
  const found = defaults.find(({
68
61
  entryName,
69
- entry
70
- }) => entryName === packageName || path.dirname(entry) === entriesDirAbs);
62
+ entry,
63
+ nestedRoutesEntry: _nestedRoutesEntry = ''
64
+ }) => entryName === packageName || path.dirname(entry) === entriesDirAbs || path.dirname(_nestedRoutesEntry) === entriesDirAbs);
71
65
  found && (found.entryName = MAIN_ENTRY_NAME);
72
66
  }
73
-
74
67
  return defaults;
75
68
  };
@@ -0,0 +1,173 @@
1
+ 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; }
2
+ 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; }
3
+ 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; }
4
+ import path from 'path';
5
+ import { fs } from '@modern-js/utils';
6
+ import { makeLegalIdentifier } from "../makeLegalIdentifier";
7
+ import { FILE_SYSTEM_ROUTES_COMPONENTS_DIR, FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP, FILE_SYSTEM_ROUTES_INDEX, FILE_SYSTEM_ROUTES_LAYOUT } from "../constants";
8
+ import { replaceWithAlias } from "../utils";
9
+ import { debug, findLayout, shouldSkip, getRouteWeight } from "./utils";
10
+ const compName = (srcDirectory, filePath) => {
11
+ const legalCompName = makeLegalIdentifier(path.relative(srcDirectory, filePath));
12
+ return `Comp_${legalCompName}`;
13
+ };
14
+ const layoutNameAbbr = filePath => {
15
+ const prefix = 'L_';
16
+ const dirName = path.dirname(filePath).split('/').pop() || '';
17
+ return `${prefix}${makeLegalIdentifier(dirName)}`;
18
+ };
19
+ const parents = [];
20
+
21
+ /* eslint-disable no-param-reassign */
22
+ const recursiveReadDir = ({
23
+ dir,
24
+ routes,
25
+ basePath: _basePath = '/',
26
+ srcDirectory,
27
+ srcAlias
28
+ }) => {
29
+ let hasDynamicRoute = false;
30
+ let resetParent = false;
31
+ let parent = parents[parents.length - 1];
32
+ const layout = findLayout(dir);
33
+ if (layout) {
34
+ if (_basePath === '/') {
35
+ throw new Error(`should use _app instead of _layout in ${dir}`);
36
+ } else {
37
+ const alias = replaceWithAlias(srcDirectory, layout, srcAlias);
38
+ const componentName = compName(srcDirectory, layout);
39
+ const route = {
40
+ path: `${_basePath.substring(0, _basePath.length - 1)}`,
41
+ children: [],
42
+ _component: alias,
43
+ component: componentName,
44
+ parent,
45
+ type: 'page'
46
+ };
47
+ parent = route;
48
+ resetParent = true;
49
+ routes.push(route);
50
+ parents.push(route);
51
+ routes = route.children;
52
+ }
53
+ }
54
+ for (const relative of fs.readdirSync(dir)) {
55
+ const filePath = path.join(dir, relative);
56
+ if (!shouldSkip(filePath)) {
57
+ const filename = path.basename(filePath, path.extname(filePath));
58
+ const alias = replaceWithAlias(srcDirectory, filePath, srcAlias);
59
+ const componentName = compName(srcDirectory, filePath);
60
+ const dynamicRouteMatched = FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP.exec(filename);
61
+ if (dynamicRouteMatched) {
62
+ if (hasDynamicRoute) {
63
+ throw new Error(`Can't set two dynamic route in one directory: ${dir}`);
64
+ } else {
65
+ hasDynamicRoute = true;
66
+ }
67
+ }
68
+ const route = {
69
+ path: `${_basePath}${dynamicRouteMatched ? `:${dynamicRouteMatched[1]}${dynamicRouteMatched[2]}` : filename}`,
70
+ _component: alias,
71
+ component: componentName,
72
+ parent,
73
+ type: 'page'
74
+ };
75
+ if (fs.statSync(filePath).isDirectory()) {
76
+ recursiveReadDir({
77
+ dir: filePath,
78
+ routes,
79
+ basePath: `${route.path}/`,
80
+ srcDirectory,
81
+ srcAlias
82
+ });
83
+ continue;
84
+ }
85
+ if (filename === FILE_SYSTEM_ROUTES_LAYOUT) {
86
+ continue;
87
+ }
88
+ if (filename === FILE_SYSTEM_ROUTES_INDEX) {
89
+ route.path = _basePath === '/' ? _basePath : `${_basePath.substring(0, _basePath.length - 1)}`;
90
+ }
91
+ if (filename === '404' && _basePath === '/') {
92
+ route.path = '*';
93
+ }
94
+ routes.push(route);
95
+ }
96
+ }
97
+ if (resetParent) {
98
+ parents.pop();
99
+ }
100
+ };
101
+ /* eslint-enable no-param-reassign */
102
+
103
+ const normalizeNestedRoutes = (nested, internalComponentsDir, internalDirectory, internalDirAlias) => {
104
+ const flat = routes => routes.reduce((memo, route) => memo.concat(Array.isArray(route.children) ? flat(route.children) : [route]), []);
105
+ const generate = route => {
106
+ const codes = [];
107
+ let lastComponent = route.component;
108
+ const imports = [`import React from 'react';`, `import ${lastComponent} from '${route._component}'`];
109
+
110
+ // eslint-disable-next-line no-param-reassign, no-cond-assign
111
+ while (route = route.parent) {
112
+ const layoutComponent = route.component;
113
+ const layoutComponentAbbr = layoutNameAbbr(route._component);
114
+ imports.push(`import ${layoutComponent} from '${route._component}';`);
115
+ const currentComponent = `${layoutComponentAbbr}_${lastComponent}`;
116
+ codes.push(`const ${currentComponent} = props => <${layoutComponent} Component={${lastComponent}} {...props} />;`);
117
+ lastComponent = currentComponent;
118
+ }
119
+ const file = path.resolve(internalComponentsDir, `${lastComponent}.jsx`);
120
+ fs.outputFileSync(file, `${imports.join('\n')}\n${codes.join('\n')}\nexport default ${lastComponent}`);
121
+ return {
122
+ component: lastComponent,
123
+ _component: replaceWithAlias(internalDirectory, file, internalDirAlias)
124
+ };
125
+ };
126
+ const normalized = flat(nested).map(route => route.parent ? _objectSpread(_objectSpread(_objectSpread({}, route), generate(route)), {}, {
127
+ parent: undefined
128
+ }) : _objectSpread(_objectSpread({}, route), {}, {
129
+ parent: undefined
130
+ }));
131
+ return normalized;
132
+ };
133
+ export const getClientRoutes = ({
134
+ entrypoint,
135
+ srcDirectory,
136
+ srcAlias,
137
+ internalDirectory,
138
+ internalDirAlias
139
+ }) => {
140
+ const {
141
+ entry,
142
+ entryName
143
+ } = entrypoint;
144
+ if (!fs.existsSync(entry)) {
145
+ throw new Error(`generate file system routes error, ${entry} directory not found.`);
146
+ }
147
+ if (!(fs.existsSync(entry) && fs.statSync(entry).isDirectory())) {
148
+ throw new Error(`generate file system routes error, ${entry} should be directory.`);
149
+ }
150
+ let routes = [];
151
+ recursiveReadDir({
152
+ dir: entry,
153
+ routes,
154
+ basePath: '/',
155
+ srcDirectory,
156
+ srcAlias
157
+ });
158
+ const internalComponentsDir = path.resolve(internalDirectory, `${entryName}/${FILE_SYSTEM_ROUTES_COMPONENTS_DIR}`);
159
+ fs.emptyDirSync(internalComponentsDir);
160
+ routes = normalizeNestedRoutes(routes, internalComponentsDir, internalDirectory, internalDirAlias);
161
+ parents.length = 0;
162
+
163
+ // FIXME: support more situations
164
+ routes.sort((a, b) => {
165
+ const delta = getRouteWeight(a.path) - getRouteWeight(b.path);
166
+ if (delta === 0) {
167
+ return a.path.length - b.path.length;
168
+ }
169
+ return delta;
170
+ });
171
+ debug(`fileSystem routes: %o`, routes);
172
+ return routes;
173
+ };
@@ -1,49 +1,25 @@
1
1
  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; }
2
-
3
2
  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; }
4
-
5
3
  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
-
7
4
  import path from 'path';
8
- import { fs, createDebugger, findExists, normalizeToPosixPath } from '@modern-js/utils';
9
- import { makeLegalIdentifier } from "./makeLegalIdentifier";
10
- import { FILE_SYSTEM_ROUTES_COMPONENTS_DIR, FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP, FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT, FILE_SYSTEM_ROUTES_IGNORED_REGEX, FILE_SYSTEM_ROUTES_INDEX, FILE_SYSTEM_ROUTES_LAYOUT, JS_EXTENSIONS } from "./constants";
11
- const debug = createDebugger('get-client-routes');
12
-
13
- const findLayout = dir => findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `${FILE_SYSTEM_ROUTES_LAYOUT}${ext}`)));
14
-
15
- const shouldSkip = file => {
16
- // should not skip directory.
17
- if (fs.statSync(file).isDirectory()) {
18
- return false;
19
- }
20
-
21
- const ext = path.extname(file);
22
-
23
- if (FILE_SYSTEM_ROUTES_IGNORED_REGEX.test(file) || !JS_EXTENSIONS.includes(ext) || FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT === path.basename(file, ext)) {
24
- return true;
25
- }
26
-
27
- return false;
28
- };
29
-
30
- const replaceWithAlias = (base, filePath, alias) => normalizeToPosixPath(path.join(alias, path.relative(base, filePath)));
31
-
5
+ import { fs } from '@modern-js/utils';
6
+ import { makeLegalIdentifier } from "../makeLegalIdentifier";
7
+ import { FILE_SYSTEM_ROUTES_COMPONENTS_DIR, FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP, FILE_SYSTEM_ROUTES_INDEX, FILE_SYSTEM_ROUTES_LAYOUT } from "../constants";
8
+ import { replaceWithAlias } from "../utils";
9
+ import { debug, findLayout, shouldSkip, getRouteWeight } from "./utils";
32
10
  const compName = (srcDirectory, filePath) => {
33
11
  const legalCompName = makeLegalIdentifier(path.relative(srcDirectory, filePath));
34
12
  return `Comp_${legalCompName}`;
35
13
  };
36
-
37
14
  const layoutNameAbbr = filePath => {
38
15
  const prefix = 'L_';
39
16
  const dirName = path.dirname(filePath).split('/').pop() || '';
40
17
  return `${prefix}${makeLegalIdentifier(dirName)}`;
41
18
  };
42
-
43
19
  const parents = [];
44
- /* eslint-disable no-param-reassign */
45
20
 
46
- const recursiveReadDir = ({
21
+ /* eslint-disable no-param-reassign */
22
+ const recursiveReadDirLegacy = ({
47
23
  dir,
48
24
  routes,
49
25
  basePath: _basePath = '/',
@@ -54,7 +30,6 @@ const recursiveReadDir = ({
54
30
  let resetParent = false;
55
31
  let parent = parents[parents.length - 1];
56
32
  const layout = findLayout(dir);
57
-
58
33
  if (layout) {
59
34
  if (_basePath === '/') {
60
35
  throw new Error(`should use _app instead of _layout in ${dir}`);
@@ -76,16 +51,13 @@ const recursiveReadDir = ({
76
51
  routes = route.routes;
77
52
  }
78
53
  }
79
-
80
54
  for (const relative of fs.readdirSync(dir)) {
81
55
  const filePath = path.join(dir, relative);
82
-
83
56
  if (!shouldSkip(filePath)) {
84
57
  const filename = path.basename(filePath, path.extname(filePath));
85
58
  const alias = replaceWithAlias(srcDirectory, filePath, srcAlias);
86
59
  const componentName = compName(srcDirectory, filePath);
87
60
  const dynamicRouteMatched = FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP.exec(filename);
88
-
89
61
  if (dynamicRouteMatched) {
90
62
  if (hasDynamicRoute) {
91
63
  throw new Error(`Can't set two dynamic route in one directory: ${dir}`);
@@ -93,7 +65,6 @@ const recursiveReadDir = ({
93
65
  hasDynamicRoute = true;
94
66
  }
95
67
  }
96
-
97
68
  const route = {
98
69
  path: `${_basePath}${dynamicRouteMatched ? `:${dynamicRouteMatched[1]}${dynamicRouteMatched[2]}` : filename}`,
99
70
  _component: alias,
@@ -101,9 +72,8 @@ const recursiveReadDir = ({
101
72
  exact: true,
102
73
  parent
103
74
  };
104
-
105
75
  if (fs.statSync(filePath).isDirectory()) {
106
- recursiveReadDir({
76
+ recursiveReadDirLegacy({
107
77
  dir: filePath,
108
78
  routes,
109
79
  basePath: `${route.path}/`,
@@ -112,39 +82,33 @@ const recursiveReadDir = ({
112
82
  });
113
83
  continue;
114
84
  }
115
-
116
85
  if (filename === FILE_SYSTEM_ROUTES_LAYOUT) {
117
86
  continue;
118
87
  }
119
-
120
88
  if (filename === FILE_SYSTEM_ROUTES_INDEX) {
121
89
  route.path = _basePath === '/' ? _basePath : `${_basePath.substring(0, _basePath.length - 1)}`;
122
90
  }
123
-
124
91
  if (filename === '404' && _basePath === '/') {
125
92
  route.path = '*';
126
93
  route.exact = false;
127
94
  }
128
-
129
95
  routes.push(route);
130
96
  }
131
97
  }
132
-
133
98
  if (resetParent) {
134
99
  parents.pop();
135
100
  }
136
101
  };
137
102
  /* eslint-enable no-param-reassign */
138
103
 
139
-
140
104
  const normalizeNestedRoutes = (nested, internalComponentsDir, internalDirectory, internalDirAlias) => {
141
105
  const flat = routes => routes.reduce((memo, route) => memo.concat(Array.isArray(route.routes) ? flat(route.routes) : [route]), []);
142
-
143
106
  const generate = route => {
144
107
  const codes = [];
145
108
  let lastComponent = route.component;
146
- const imports = [`import React from 'react';`, `import ${lastComponent} from '${route._component}'`]; // eslint-disable-next-line no-param-reassign, no-cond-assign
109
+ const imports = [`import React from 'react';`, `import ${lastComponent} from '${route._component}'`];
147
110
 
111
+ // eslint-disable-next-line no-param-reassign, no-cond-assign
148
112
  while (route = route.parent) {
149
113
  const layoutComponent = route.component;
150
114
  const layoutComponentAbbr = layoutNameAbbr(route._component);
@@ -153,7 +117,6 @@ const normalizeNestedRoutes = (nested, internalComponentsDir, internalDirectory,
153
117
  codes.push(`const ${currentComponent} = props => <${layoutComponent} Component={${lastComponent}} {...props} />;`);
154
118
  lastComponent = currentComponent;
155
119
  }
156
-
157
120
  const file = path.resolve(internalComponentsDir, `${lastComponent}.jsx`);
158
121
  fs.outputFileSync(file, `${imports.join('\n')}\n${codes.join('\n')}\nexport default ${lastComponent}`);
159
122
  return {
@@ -161,7 +124,6 @@ const normalizeNestedRoutes = (nested, internalComponentsDir, internalDirectory,
161
124
  _component: replaceWithAlias(internalDirectory, file, internalDirAlias)
162
125
  };
163
126
  };
164
-
165
127
  const normalized = flat(nested).map(route => route.parent ? _objectSpread(_objectSpread(_objectSpread({}, route), generate(route)), {}, {
166
128
  parent: undefined
167
129
  }) : _objectSpread(_objectSpread({}, route), {}, {
@@ -169,9 +131,6 @@ const normalizeNestedRoutes = (nested, internalComponentsDir, internalDirectory,
169
131
  }));
170
132
  return normalized;
171
133
  };
172
-
173
- const getRouteWeight = route => route === '*' ? 999 : route.split(':').length - 1;
174
-
175
134
  export const getClientRoutes = ({
176
135
  entrypoint,
177
136
  srcDirectory,
@@ -183,17 +142,14 @@ export const getClientRoutes = ({
183
142
  entry,
184
143
  entryName
185
144
  } = entrypoint;
186
-
187
145
  if (!fs.existsSync(entry)) {
188
146
  throw new Error(`generate file system routes error, ${entry} directory not found.`);
189
147
  }
190
-
191
148
  if (!(fs.existsSync(entry) && fs.statSync(entry).isDirectory())) {
192
149
  throw new Error(`generate file system routes error, ${entry} should be directory.`);
193
150
  }
194
-
195
151
  let routes = [];
196
- recursiveReadDir({
152
+ recursiveReadDirLegacy({
197
153
  dir: entry,
198
154
  routes,
199
155
  basePath: '/',
@@ -203,15 +159,14 @@ export const getClientRoutes = ({
203
159
  const internalComponentsDir = path.resolve(internalDirectory, `${entryName}/${FILE_SYSTEM_ROUTES_COMPONENTS_DIR}`);
204
160
  fs.emptyDirSync(internalComponentsDir);
205
161
  routes = normalizeNestedRoutes(routes, internalComponentsDir, internalDirectory, internalDirAlias);
206
- parents.length = 0; // FIXME: support more situations
162
+ parents.length = 0;
207
163
 
164
+ // FIXME: support more situations
208
165
  routes.sort((a, b) => {
209
166
  const delta = getRouteWeight(a.path) - getRouteWeight(b.path);
210
-
211
167
  if (delta === 0) {
212
168
  return a.path.length - b.path.length;
213
169
  }
214
-
215
170
  return delta;
216
171
  });
217
172
  debug(`fileSystem routes: %o`, routes);
@@ -0,0 +1,2 @@
1
+ export { getClientRoutes } from "./getRoutes";
2
+ export { getClientRoutes as getClientRoutesLegacy } from "./getRoutesLegacy";
@@ -0,0 +1,18 @@
1
+ import path from 'path';
2
+ import { createDebugger, findExists, fs } from '@modern-js/utils';
3
+ import { JS_EXTENSIONS, FILE_SYSTEM_ROUTES_LAYOUT, FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT, FILE_SYSTEM_ROUTES_IGNORED_REGEX } from "../constants";
4
+ const debug = createDebugger('get-client-routes');
5
+ export { debug };
6
+ export const findLayout = dir => findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `${FILE_SYSTEM_ROUTES_LAYOUT}${ext}`)));
7
+ export const getRouteWeight = route => route === '*' ? 999 : route.split(':').length - 1;
8
+ export const shouldSkip = file => {
9
+ // should not skip directory.
10
+ if (fs.statSync(file).isDirectory()) {
11
+ return false;
12
+ }
13
+ const ext = path.extname(file);
14
+ if (FILE_SYSTEM_ROUTES_IGNORED_REGEX.test(file) || !JS_EXTENSIONS.includes(ext) || FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT === path.basename(file, ext)) {
15
+ return true;
16
+ }
17
+ return false;
18
+ };
@@ -2,55 +2,62 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { findExists, ensureAbsolutePath } from '@modern-js/utils';
4
4
  import { isDefaultExportFunction } from "./isDefaultExportFunction";
5
- import { JS_EXTENSIONS, INDEX_FILE_NAME, APP_FILE_NAME, PAGES_DIR_NAME, FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT } from "./constants";
6
-
5
+ import { JS_EXTENSIONS, INDEX_FILE_NAME, APP_FILE_NAME, PAGES_DIR_NAME, FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT, NESTED_ROUTES_DIR } from "./constants";
7
6
  const hasIndex = dir => findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `${INDEX_FILE_NAME}${ext}`)));
8
-
9
7
  const hasApp = dir => findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `${APP_FILE_NAME}${ext}`)));
10
-
11
8
  const hasPages = dir => fs.existsSync(path.join(dir, PAGES_DIR_NAME));
12
-
13
- const isBundleEntry = dir => hasApp(dir) || hasPages(dir) || hasIndex(dir);
14
-
9
+ const hasNestedRoutes = dir => fs.existsSync(path.join(dir, NESTED_ROUTES_DIR));
10
+ const isBundleEntry = dir => hasApp(dir) || hasPages(dir) || hasIndex(dir) || hasNestedRoutes(dir);
15
11
  const scanDir = dirs => dirs.map(dir => {
16
12
  const indexFile = hasIndex(dir);
17
13
  const customBootstrap = isDefaultExportFunction(indexFile) ? indexFile : false;
18
14
  const entryName = path.basename(dir);
19
-
20
15
  if (indexFile && !customBootstrap) {
21
16
  return {
22
17
  entryName,
23
18
  entry: indexFile,
19
+ absoluteEntryDir: path.resolve(dir),
24
20
  isAutoMount: false
25
21
  };
26
22
  }
27
-
28
- if (hasApp(dir)) {
23
+ const isHasApp = hasApp(dir);
24
+ if (isHasApp) {
29
25
  return {
30
26
  entryName,
31
27
  entry: path.join(dir, APP_FILE_NAME),
32
28
  isAutoMount: true,
29
+ absoluteEntryDir: path.resolve(dir),
33
30
  customBootstrap
34
31
  };
35
- } else if (hasPages(dir)) {
36
- return {
32
+ }
33
+ const isHasNestedRoutes = hasNestedRoutes(dir);
34
+ const isHasPages = hasPages(dir);
35
+ if (isHasNestedRoutes || isHasPages) {
36
+ const entrypoint = {
37
37
  entryName,
38
- entry: path.join(dir, PAGES_DIR_NAME),
38
+ entry: '',
39
39
  fileSystemRoutes: {
40
40
  globalApp: findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `./${PAGES_DIR_NAME}/${FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT}${ext}`)))
41
41
  },
42
42
  isAutoMount: true,
43
+ absoluteEntryDir: path.resolve(dir),
43
44
  customBootstrap
44
45
  };
45
- } else {
46
- return {
47
- entryName,
48
- entry: indexFile,
49
- isAutoMount: false
50
- };
46
+ if (isHasPages) {
47
+ entrypoint.entry = path.join(dir, PAGES_DIR_NAME);
48
+ }
49
+ if (isHasNestedRoutes) {
50
+ entrypoint.nestedRoutesEntry = path.join(dir, NESTED_ROUTES_DIR);
51
+ }
52
+ return entrypoint;
51
53
  }
54
+ return {
55
+ entryName,
56
+ entry: indexFile,
57
+ absoluteEntryDir: path.resolve(dir),
58
+ isAutoMount: false
59
+ };
52
60
  });
53
-
54
61
  export const getFileSystemEntry = (appContext, config) => {
55
62
  const {
56
63
  appDirectory
@@ -61,7 +68,6 @@ export const getFileSystemEntry = (appContext, config) => {
61
68
  }
62
69
  } = config;
63
70
  const src = ensureAbsolutePath(appDirectory, entriesDir);
64
-
65
71
  if (fs.existsSync(src)) {
66
72
  if (fs.statSync(src).isDirectory()) {
67
73
  return scanDir(isBundleEntry(src) ? [src] : fs.readdirSync(src).map(file => path.join(src, file)).filter(file => fs.statSync(file).isDirectory() && isBundleEntry(file)));
@@ -3,7 +3,6 @@ import { fs, findExists, MAIN_ENTRY_NAME } from '@modern-js/utils';
3
3
  import { HTML_PARTIALS_EXTENSIONS, HTML_PARTIALS_FOLDER } from "./constants";
4
4
  import * as templates from "./templates";
5
5
  var PartialPosition;
6
-
7
6
  (function (PartialPosition) {
8
7
  PartialPosition["TOP"] = "top";
9
8
  PartialPosition["HEAD"] = "head";
@@ -11,7 +10,6 @@ var PartialPosition;
11
10
  PartialPosition["BOTTOM"] = "bottom";
12
11
  PartialPosition["INDEX"] = "index";
13
12
  })(PartialPosition || (PartialPosition = {}));
14
-
15
13
  const findPartials = (dir, entryName, position) => {
16
14
  if (fs.existsSync(dir)) {
17
15
  const base = findExists(HTML_PARTIALS_EXTENSIONS.map(ext => path.resolve(dir, `${position}${ext}`)));
@@ -21,11 +19,10 @@ const findPartials = (dir, entryName, position) => {
21
19
  content: fs.readFileSync(file, 'utf8')
22
20
  } : null;
23
21
  }
24
-
25
22
  return null;
26
- }; // generate html template for
27
-
23
+ };
28
24
 
25
+ // generate html template for
29
26
  export const getHtmlTemplate = async (entrypoints, api, {
30
27
  appContext,
31
28
  config
@@ -41,14 +38,12 @@ export const getHtmlTemplate = async (entrypoints, api, {
41
38
  } = config;
42
39
  const htmlDir = path.resolve(appDirectory, configDir, HTML_PARTIALS_FOLDER);
43
40
  const htmlTemplates = {};
44
-
45
41
  for (const entrypoint of entrypoints) {
46
42
  const {
47
43
  entryName
48
44
  } = entrypoint;
49
45
  const name = entrypoints.length === 1 && entryName === MAIN_ENTRY_NAME ? '' : entryName;
50
46
  const customIndexTemplate = findPartials(htmlDir, name, PartialPosition.INDEX);
51
-
52
47
  if (customIndexTemplate) {
53
48
  htmlTemplates[entryName] = customIndexTemplate.file;
54
49
  } else {
@@ -71,12 +66,10 @@ export const getHtmlTemplate = async (entrypoints, api, {
71
66
  fs.outputFileSync(templatePath, templates.html(partials), 'utf8');
72
67
  htmlTemplates[entryName] = templatePath;
73
68
  const bottomTemplate = findPartials(htmlDir, name, PartialPosition.BOTTOM);
74
-
75
69
  if (bottomTemplate) {
76
70
  htmlTemplates[`__${entryName}-bottom__`] = bottomTemplate.content;
77
71
  }
78
72
  }
79
73
  }
80
-
81
74
  return htmlTemplates;
82
75
  };