@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
@@ -4,7 +4,6 @@ import { isReact18, normalizeToPosixPath } from '@modern-js/utils';
4
4
  import { FILE_SYSTEM_ROUTES_FILE_NAME } from "./constants";
5
5
  export const walkDirectory = dir => fs.readdirSync(dir).reduce((previous, filename) => {
6
6
  const filePath = path.join(dir, filename);
7
-
8
7
  if (fs.statSync(filePath).isDirectory()) {
9
8
  return [...previous, ...walkDirectory(filePath)];
10
9
  } else {
@@ -47,7 +46,6 @@ export const getDefaultImports = ({
47
46
  }],
48
47
  value: normalizeToPosixPath(customBootstrap.replace(srcDirectory, internalSrcAlias))
49
48
  }].filter(Boolean);
50
-
51
49
  if (fileSystemRoutes) {
52
50
  const route = {
53
51
  specifiers: [{
@@ -55,7 +53,6 @@ export const getDefaultImports = ({
55
53
  }],
56
54
  value: normalizeToPosixPath(`${internalDirAlias}/${entryName}/${FILE_SYSTEM_ROUTES_FILE_NAME}`)
57
55
  };
58
-
59
56
  if (fileSystemRoutes.globalApp) {
60
57
  imports.push({
61
58
  specifiers: [{
@@ -66,7 +63,6 @@ export const getDefaultImports = ({
66
63
  } else {
67
64
  route.initialize = 'const App = false;';
68
65
  }
69
-
70
66
  imports.push(route);
71
67
  } else {
72
68
  imports.push({
@@ -76,17 +72,15 @@ export const getDefaultImports = ({
76
72
  value: normalizeToPosixPath(entry.replace(srcDirectory, internalSrcAlias))
77
73
  });
78
74
  }
79
-
80
75
  return imports;
81
76
  };
82
77
  export const isRouteComponentFile = filePath => {
83
78
  if (/\.(d|test|spec|e2e)\.(js|jsx|ts|tsx)$/.test(filePath)) {
84
79
  return false;
85
80
  }
86
-
87
81
  if (['.js', '.jsx', '.ts', '.tsx'].includes(path.extname(filePath))) {
88
82
  return true;
89
83
  }
90
-
91
84
  return false;
92
- };
85
+ };
86
+ export const replaceWithAlias = (base, filePath, alias) => normalizeToPosixPath(path.join(alias, path.relative(base, filePath)));
@@ -0,0 +1,208 @@
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 { join } from 'path';
5
+ import { mergeBuilderConfig } from '@modern-js/builder-shared';
6
+ import { template as lodashTemplate } from '@modern-js/utils/lodash';
7
+ import HtmlWebpackPlugin from '@modern-js/builder-webpack-provider/html-webpack-plugin';
8
+ import { getEntryOptions } from '@modern-js/utils';
9
+ import { BottomTemplatePlugin } from "../webpackPlugins/htmlBottomTemplate";
10
+ import { HtmlAsyncChunkPlugin } from "../webpackPlugins/htmlAsyncChunkPlugin";
11
+ import { createCopyPattern } from "../share";
12
+ import RouterPlugin from "../webpackPlugins/routerPlugin";
13
+ /**
14
+ * Provides default configuration consistent with `@modern-js/webpack`
15
+ */
16
+ export const PluginCompatModern = (appContext, modernConfig, options) => ({
17
+ name: 'builder-plugin-compat-modern',
18
+ setup(api) {
19
+ api.modifyBuilderConfig(config => {
20
+ if (isStreamingSSR(modernConfig)) {
21
+ return mergeBuilderConfig(config, {
22
+ html: {
23
+ inject: 'body'
24
+ }
25
+ });
26
+ }
27
+ return config;
28
+ });
29
+ api.modifyWebpackChain((chain, {
30
+ target,
31
+ CHAIN_ID,
32
+ isProd
33
+ }) => {
34
+ const builderNormalizedConfig = api.getNormalizedConfig();
35
+ // set webpack config name
36
+ if (target === 'node') {
37
+ chain.name('server');
38
+ } else if (target === 'modern-web') {
39
+ chain.name('modern');
40
+ } else {
41
+ chain.name('client');
42
+ }
43
+ chain.resolve.modules.add('node_modules').add(join(api.context.rootPath, 'node_modules'));
44
+
45
+ // apply node compat
46
+ if (target === 'node') {
47
+ applyNodeCompat(chain, modernConfig, isProd);
48
+ }
49
+ if (isHtmlEnabled(builderNormalizedConfig, target)) {
50
+ applyBottomHtmlWebpackPlugin({
51
+ api,
52
+ chain,
53
+ CHAIN_ID,
54
+ appContext,
55
+ modernConfig
56
+ });
57
+ applyAsyncChunkHtmlPlugin({
58
+ chain,
59
+ CHAIN_ID,
60
+ modernConfig
61
+ });
62
+ }
63
+
64
+ // apply copy plugin
65
+ // const copyPatterns = createCopyPatterns(chain, appContext, modernConfig);
66
+ const defaultCopyPattern = createCopyPattern(appContext, modernConfig, 'public', chain);
67
+ chain.plugin(CHAIN_ID.PLUGIN.COPY).tap(args => {
68
+ var _args$;
69
+ return [{
70
+ patterns: [...(((_args$ = args[0]) === null || _args$ === void 0 ? void 0 : _args$.patterns) || []), defaultCopyPattern]
71
+ }];
72
+ });
73
+ const {
74
+ entrypoints
75
+ } = appContext;
76
+ const existNestedRoutes = entrypoints.some(entrypoint => entrypoint.nestedRoutesEntry);
77
+ chain.plugin('route-plugin').use(RouterPlugin, [{
78
+ existNestedRoutes
79
+ }]);
80
+ function isHtmlEnabled(config, target) {
81
+ var _config$tools;
82
+ return ((_config$tools = config.tools) === null || _config$tools === void 0 ? void 0 : _config$tools.htmlPlugin) !== false && target !== 'node' && target !== 'web-worker';
83
+ }
84
+ });
85
+ if (options) {
86
+ applyCallbacks(api, options);
87
+ }
88
+ }
89
+ });
90
+
91
+ /**
92
+ * register builder hooks callback
93
+ */
94
+ function applyCallbacks(api, options) {
95
+ options.onAfterBuild && api.onAfterBuild(options.onAfterBuild);
96
+ options.onAfterCreateCompiler && api.onAfterCreateCompiler(options.onAfterCreateCompiler);
97
+ options.onAfterStartDevServer && api.onAfterStartDevServer(options.onAfterStartDevServer);
98
+ options.onBeforeBuild && api.onBeforeBuild(options.onBeforeBuild);
99
+ options.onBeforeCreateCompiler && api.onBeforeCreateCompiler(options.onBeforeCreateCompiler);
100
+ options.onBeforeStartDevServer && api.onBeforeStartDevServer(options.onBeforeStartDevServer);
101
+ options.onDevCompileDone && api.onDevCompileDone(options.onDevCompileDone);
102
+ options.onExit && api.onExit(options.onExit);
103
+ }
104
+
105
+ /**
106
+ * compat some config, if target is `node`
107
+ */
108
+ function applyNodeCompat(chain, modernConfig, isProd) {
109
+ // apply node resolve extensions
110
+ for (const ext of ['.node.js', '.node.jsx', '.node.ts', '.node.tsx']) {
111
+ chain.resolve.extensions.prepend(ext);
112
+ }
113
+
114
+ // apply filterEntriesBySSRConfig
115
+ filterEntriesBySSRConfig(isProd, chain, modernConfig.server, modernConfig.output);
116
+ function filterEntriesBySSRConfig(isProd, chain, serverConfig, outputConfig) {
117
+ var _outputConfig$ssg;
118
+ const entries = chain.entryPoints.entries();
119
+ // if prod and ssg config is true or function
120
+ if (isProd && ((outputConfig === null || outputConfig === void 0 ? void 0 : outputConfig.ssg) === true || typeof (outputConfig === null || outputConfig === void 0 ? void 0 : (_outputConfig$ssg = outputConfig.ssg) === null || _outputConfig$ssg === void 0 ? void 0 : _outputConfig$ssg[0]) === 'function')) {
121
+ return;
122
+ }
123
+
124
+ // if single entry has ssg config
125
+ // `ssg: {}` is not allowed if multi entry
126
+ const entryNames = Object.keys(entries);
127
+ if (isProd && entryNames.length === 1 && outputConfig !== null && outputConfig !== void 0 && outputConfig.ssg) {
128
+ return;
129
+ }
130
+
131
+ // collect all ssg entries
132
+ const ssgEntries = [];
133
+ if (isProd && outputConfig !== null && outputConfig !== void 0 && outputConfig.ssg) {
134
+ const {
135
+ ssg
136
+ } = outputConfig;
137
+ entryNames.forEach(name => {
138
+ if (ssg[name]) {
139
+ ssgEntries.push(name);
140
+ }
141
+ });
142
+ }
143
+ const {
144
+ ssr,
145
+ ssrByEntries
146
+ } = serverConfig || {};
147
+ entryNames.forEach(name => {
148
+ if (!ssgEntries.includes(name) && (ssr && (ssrByEntries === null || ssrByEntries === void 0 ? void 0 : ssrByEntries[name]) === false || !ssr && !(ssrByEntries !== null && ssrByEntries !== void 0 && ssrByEntries[name]))) {
149
+ chain.entryPoints.delete(name);
150
+ }
151
+ });
152
+ }
153
+ }
154
+
155
+ /**
156
+ * inject bottom template
157
+ */
158
+ function applyBottomHtmlWebpackPlugin({
159
+ api,
160
+ chain,
161
+ modernConfig,
162
+ appContext,
163
+ CHAIN_ID
164
+ }) {
165
+ // inject bottomTemplate into html-webpack-plugin
166
+ for (const entryName of Object.keys(api.context.entry)) {
167
+ // FIXME: the only need necessary
168
+ const baseTemplateParams = _objectSpread({
169
+ entryName,
170
+ title: getEntryOptions(entryName, modernConfig.output.title, modernConfig.output.titleByEntries, appContext.packageName),
171
+ mountId: modernConfig.output.mountId
172
+ }, getEntryOptions(entryName, modernConfig.output.templateParameters, modernConfig.output.templateParametersByEntries, appContext.packageName));
173
+ chain.plugin(`${CHAIN_ID.PLUGIN.HTML}-${entryName}`).tap(args => [_objectSpread(_objectSpread({}, args[0] || {}), {}, {
174
+ __internal__: true,
175
+ bottomTemplate: appContext.htmlTemplates[`__${entryName}-bottom__`] && lodashTemplate(appContext.htmlTemplates[`__${entryName}-bottom__`])(baseTemplateParams)
176
+ })]);
177
+ }
178
+ chain.plugin(CHAIN_ID.PLUGIN.BOTTOM_TEMPLATE).use(BottomTemplatePlugin, [HtmlWebpackPlugin]);
179
+ }
180
+ const isStreamingSSR = userConfig => {
181
+ const isStreaming = ssr => ssr && typeof ssr === 'object' && ssr.mode === 'stream';
182
+ const {
183
+ server
184
+ } = userConfig;
185
+ if (isStreaming(server.ssr)) {
186
+ return true;
187
+ }
188
+
189
+ // Since we cannot apply different plugins for different entries,
190
+ // we regard the whole app as streaming ssr only if one entry meets the requirement.
191
+ if (server !== null && server !== void 0 && server.ssrByEntries && typeof server.ssrByEntries === 'object') {
192
+ for (const name of Object.keys(server.ssrByEntries)) {
193
+ if (isStreaming(server.ssrByEntries[name])) {
194
+ return true;
195
+ }
196
+ }
197
+ }
198
+ return false;
199
+ };
200
+ function applyAsyncChunkHtmlPlugin({
201
+ chain,
202
+ modernConfig,
203
+ CHAIN_ID
204
+ }) {
205
+ if (isStreamingSSR(modernConfig)) {
206
+ chain.plugin(CHAIN_ID.PLUGIN.HTML_ASYNC_CHUNK).use(HtmlAsyncChunkPlugin, [HtmlWebpackPlugin]);
207
+ }
208
+ }
@@ -0,0 +1,58 @@
1
+ import path from 'path';
2
+ import { findExists } from '@modern-js/utils';
3
+ export function createHtmlConfig(normalizedConfig, appContext) {
4
+ const {
5
+ disableHtmlFolder,
6
+ favicon,
7
+ faviconByEntries,
8
+ inject,
9
+ injectByEntries,
10
+ meta,
11
+ metaByEntries,
12
+ mountId,
13
+ title,
14
+ titleByEntries,
15
+ scriptExt,
16
+ templateParameters,
17
+ templateParametersByEntries
18
+ } = normalizedConfig.output;
19
+ const {
20
+ configDir
21
+ } = normalizedConfig.source;
22
+
23
+ // transform Modernjs `output.scriptExt` to Builder `html.crossorigin` configuration
24
+ const builderCrossorigin = createBuilderCrossorigin(scriptExt);
25
+ const builderAppIcon = createBuilderAppIcon(configDir, appContext);
26
+ const builderFavicon = createBuilderFavicon(favicon, configDir, appContext);
27
+ return {
28
+ appIcon: builderAppIcon,
29
+ disableHtmlFolder,
30
+ favicon: builderFavicon,
31
+ faviconByEntries,
32
+ inject,
33
+ injectByEntries,
34
+ meta,
35
+ metaByEntries,
36
+ mountId,
37
+ title,
38
+ titleByEntries,
39
+ crossorigin: builderCrossorigin,
40
+ templateByEntries: appContext.htmlTemplates,
41
+ templateParameters,
42
+ templateParametersByEntries: templateParametersByEntries
43
+ };
44
+ }
45
+ const ICON_EXTENSIONS = ['png', 'jpg', 'jpeg', 'svg', 'ico'];
46
+ export function createBuilderAppIcon(configDir, appContext) {
47
+ const appIcon = findExists(ICON_EXTENSIONS.map(ext => path.resolve(appContext.appDirectory, configDir, `icon.${ext}`)));
48
+ return typeof appIcon === 'string' ? appIcon : undefined;
49
+ }
50
+ export function createBuilderCrossorigin(scriptExt) {
51
+ var _scriptExtCustomConfi;
52
+ const scriptExtCustomConfig = scriptExt === null || scriptExt === void 0 ? void 0 : scriptExt.custom;
53
+ return scriptExtCustomConfig !== null && scriptExtCustomConfig !== void 0 && (_scriptExtCustomConfi = scriptExtCustomConfig.test) !== null && _scriptExtCustomConfi !== void 0 && _scriptExtCustomConfi.test('.js') && (scriptExtCustomConfig === null || scriptExtCustomConfig === void 0 ? void 0 : scriptExtCustomConfig.attribute) === 'crossorigin' ? scriptExtCustomConfig.value : undefined;
54
+ }
55
+ export function createBuilderFavicon(favicon, configDir, appContext) {
56
+ const defaultFavicon = findExists(ICON_EXTENSIONS.map(ext => path.resolve(appContext.appDirectory, configDir, `favicon.${ext}`)));
57
+ return favicon || defaultFavicon || undefined;
58
+ }
@@ -0,0 +1,70 @@
1
+ import { createCopyPattern } from "./share";
2
+ export function createOutputConfig(normalizedConfig, appContext) {
3
+ // TODO: add `externals` options in Modern.
4
+
5
+ const {
6
+ assetPrefix,
7
+ copy,
8
+ cssModuleLocalIdentName,
9
+ cssPath,
10
+ jsPath,
11
+ htmlPath,
12
+ mediaPath,
13
+ path,
14
+ disableInlineRuntimeChunk,
15
+ disableMinimize,
16
+ disableSourceMap,
17
+ disableTsChecker,
18
+ enableCssModuleTSDeclaration,
19
+ enableInlineScripts,
20
+ enableInlineStyles,
21
+ polyfill,
22
+ dataUriLimit,
23
+ disableAssetsCache,
24
+ enableLatestDecorators,
25
+ disableCssModuleExtension
26
+ } = normalizedConfig.output;
27
+ const defaultCopyPattern = createCopyPattern(appContext, normalizedConfig, 'upload');
28
+ const builderCopy = copy ? [...copy, defaultCopyPattern] : [defaultCopyPattern];
29
+ return {
30
+ assetPrefix,
31
+ copy: builderCopy,
32
+ distPath: {
33
+ root: path,
34
+ css: cssPath,
35
+ js: jsPath,
36
+ html: htmlPath,
37
+ // `@modern-js/webpack` output all media files to `dist/media` by default
38
+ svg: mediaPath || 'media',
39
+ image: mediaPath || 'media',
40
+ font: mediaPath || 'media',
41
+ media: mediaPath || 'media'
42
+ },
43
+ dataUriLimit: {
44
+ svg: dataUriLimit,
45
+ image: dataUriLimit,
46
+ font: dataUriLimit,
47
+ media: dataUriLimit
48
+ },
49
+ disableCssModuleExtension,
50
+ disableInlineRuntimeChunk,
51
+ disableMinimize,
52
+ disableSourceMap,
53
+ disableTsChecker,
54
+ enableCssModuleTSDeclaration,
55
+ enableInlineScripts,
56
+ enableInlineStyles,
57
+ polyfill,
58
+ // We need to do this in the app-tools prepare hook because some files will be generated into the dist directory in the analyze process
59
+ cleanDistPath: false,
60
+ disableFilenameHash: disableAssetsCache,
61
+ enableLatestDecorators,
62
+ filename: {
63
+ css: cssModuleLocalIdentName
64
+ },
65
+ // `@modern-js/webpack` used to generate asset manifest by default
66
+ enableAssetManifest: true,
67
+ // compatible the modern-js with fallback behavior
68
+ enableAssetFallback: true
69
+ };
70
+ }
@@ -0,0 +1,74 @@
1
+ import { dirname, isAbsolute, posix, sep } from 'path';
2
+ import { globby, mergeAlias, findMonorepoRoot, isModernjsMonorepo } from '@modern-js/utils';
3
+ export function createSourceConfig(normalizedConfig, appContext) {
4
+ const {
5
+ alias,
6
+ envVars,
7
+ globalVars,
8
+ include,
9
+ moduleScopes,
10
+ preEntry
11
+ } = normalizedConfig.source;
12
+ const builderGlobalVars = globalVars || {};
13
+ for (const envVar of envVars || []) {
14
+ const envVarValue = process.env[envVar];
15
+ envVarValue && (builderGlobalVars[`process.env.${envVar}`] = envVarValue);
16
+ }
17
+ const builderModuleScope = createBuilderModuleScope(moduleScopes);
18
+ const builderInclude = createBuilderInclude(include, appContext);
19
+ return {
20
+ alias: mergeAlias(alias),
21
+ moduleScopes: builderModuleScope,
22
+ globalVars: builderGlobalVars,
23
+ include: builderInclude,
24
+ preEntry,
25
+ // ensure resolve.extensions same as before
26
+ resolveExtensionPrefix: '.web'
27
+ };
28
+ }
29
+ export function createBuilderInclude(include, appContext) {
30
+ const defaultInclude = [appContext.internalDirectory];
31
+ const transformInclude = (include || []).map(include => {
32
+ if (typeof include === 'string') {
33
+ if (isAbsolute(include)) {
34
+ return include;
35
+ }
36
+ return new RegExp(include);
37
+ }
38
+ return include;
39
+ }).concat(defaultInclude); // concat default Include
40
+
41
+ const root = findMonorepoRoot(appContext.appDirectory);
42
+ if (!root) {
43
+ return transformInclude;
44
+ }
45
+ const modernjsMonorepo = isModernjsMonorepo(root);
46
+ if (modernjsMonorepo) {
47
+ const paths = globby.sync(posix.join(root, 'features', '**', 'package.json'), {
48
+ ignore: ['**/node_modules/**/*']
49
+ }).map(pathname => dirname(pathname) + sep);
50
+ return [...paths, ...transformInclude];
51
+ }
52
+ return transformInclude;
53
+ }
54
+ export function createBuilderModuleScope(moduleScopes) {
55
+ if (moduleScopes) {
56
+ let builderModuleScope = [];
57
+ const DEFAULT_SCOPES = ['./src', './shared', /node_modules/];
58
+ if (Array.isArray(moduleScopes)) {
59
+ if (isPrimitiveScope(moduleScopes)) {
60
+ builderModuleScope = DEFAULT_SCOPES.concat(moduleScopes);
61
+ } else {
62
+ builderModuleScope = [DEFAULT_SCOPES, ...moduleScopes];
63
+ }
64
+ } else {
65
+ builderModuleScope = [DEFAULT_SCOPES, moduleScopes];
66
+ }
67
+ return builderModuleScope;
68
+ } else {
69
+ return undefined;
70
+ }
71
+ function isPrimitiveScope(items) {
72
+ return items.every(item => typeof item === 'string' || Object.prototype.toString.call(item) === '[object RegExp]');
73
+ }
74
+ }
@@ -0,0 +1,87 @@
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 { applyOptionsChain } from '@modern-js/utils';
5
+ export function createToolsConfig(normalizedConfig) {
6
+ const {
7
+ disableCssExtract,
8
+ enableTsLoader
9
+ } = normalizedConfig.output;
10
+ const {
11
+ autoprefixer,
12
+ babel,
13
+ minifyCss,
14
+ terser,
15
+ webpack,
16
+ webpackChain,
17
+ tsLoader,
18
+ styledComponents,
19
+ sass,
20
+ postcss,
21
+ less,
22
+ htmlPlugin,
23
+ // TODO: remove modernjs tools.lodash config
24
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
+ lodash
26
+ } = normalizedConfig.tools;
27
+ const builderTsLoader = createBuilderTsLoader(tsLoader, enableTsLoader);
28
+ const builderTsChecker = createBuilderTsChecker(normalizedConfig.output);
29
+ return {
30
+ tsChecker: builderTsChecker,
31
+ styleLoader: disableCssExtract ? {} : undefined,
32
+ cssExtract: disableCssExtract ? false : undefined,
33
+ autoprefixer,
34
+ babel,
35
+ minifyCss,
36
+ terser,
37
+ webpack,
38
+ webpackChain: webpackChain,
39
+ tsLoader: builderTsLoader,
40
+ styledComponents: styledComponents,
41
+ sass: sass,
42
+ postcss: postcss,
43
+ less: less,
44
+ // can't remove comment in html minify.
45
+ // some html template insert by using those comments.
46
+ htmlPlugin: [config => _objectSpread(_objectSpread({}, config), {}, {
47
+ minify: typeof config.minify === 'object' ? _objectSpread(_objectSpread({}, config.minify), {}, {
48
+ removeComments: false
49
+ }) : config.minify
50
+ }),
51
+ // eslint-disable-next-line no-nested-ternary
52
+ ...(Array.isArray(htmlPlugin) ? htmlPlugin : htmlPlugin ? [htmlPlugin] : [])]
53
+ };
54
+ }
55
+ function createBuilderTsLoader(tsLoader, enableTsLoader) {
56
+ const useTsLoader = Boolean(enableTsLoader);
57
+ if (!useTsLoader) {
58
+ return undefined;
59
+ }
60
+ const defaultTsLoader = {
61
+ compilerOptions: {
62
+ target: 'es5',
63
+ module: 'ESNext'
64
+ },
65
+ transpileOnly: false,
66
+ allowTsInNodeModules: true
67
+ };
68
+ return (_, utils) => applyOptionsChain(defaultTsLoader, tsLoader, utils);
69
+ }
70
+ export function createBuilderTsChecker(output) {
71
+ if (output.enableTsLoader) {
72
+ return false;
73
+ }
74
+ const defaultTsChecker = {
75
+ issue: {
76
+ include: [{
77
+ file: '**/src/**/*'
78
+ }],
79
+ exclude: [{
80
+ file: '**/*.(spec|test).ts'
81
+ }, {
82
+ file: '**/node_modules/**/*'
83
+ }]
84
+ }
85
+ };
86
+ return defaultTsChecker;
87
+ }
@@ -0,0 +1,108 @@
1
+ import { createBuilder } from '@modern-js/builder';
2
+ import { builderWebpackProvider } from '@modern-js/builder-webpack-provider';
3
+ import { applyOptionsChain, isUseSSRBundle } from '@modern-js/utils';
4
+ import { PluginCompatModern } from "./builderPlugins/compatModern";
5
+ import { createHtmlConfig } from "./createHtmlConfig";
6
+ import { createOutputConfig } from "./createOutputConfig";
7
+ import { createSourceConfig } from "./createSourceConfig";
8
+ import { createToolsConfig } from "./createToolsConfig";
9
+ function getBuilderTargets(normalizedConfig) {
10
+ const targets = ['web'];
11
+ if (normalizedConfig.output.enableModernMode && !targets.includes('modern-web')) {
12
+ targets.push('modern-web');
13
+ }
14
+ if (isUseSSRBundle(normalizedConfig)) {
15
+ targets.push('node');
16
+ }
17
+ return targets;
18
+ }
19
+ export async function createBuilderForEdenX({
20
+ normalizedConfig,
21
+ appContext,
22
+ compatPluginConfig
23
+ }) {
24
+ const builderConfig = createBuilderProviderConfig(normalizedConfig, appContext);
25
+ // create webpack provider
26
+ const webpackProvider = builderWebpackProvider({
27
+ builderConfig
28
+ });
29
+ const target = getBuilderTargets(normalizedConfig);
30
+ const builderOptions = createBuilderOptions(target, appContext);
31
+ const builder = await createBuilder(webpackProvider, builderOptions);
32
+ await applyBuilderPlugins(builder, normalizedConfig, appContext, compatPluginConfig);
33
+ return builder;
34
+ }
35
+ function createBuilderProviderConfig(normalizedConfig, appContext) {
36
+ const source = createSourceConfig(normalizedConfig, appContext);
37
+ const html = createHtmlConfig(normalizedConfig, appContext);
38
+ const output = createOutputConfig(normalizedConfig, appContext);
39
+ const tools = createToolsConfig(normalizedConfig);
40
+ return {
41
+ source,
42
+ html,
43
+ output,
44
+ tools,
45
+ dev: {
46
+ https: normalizedConfig.dev.https,
47
+ assetPrefix: normalizedConfig.dev.assetPrefix
48
+ },
49
+ performance: {
50
+ // `@modern-js/webpack` used to remove moment locale by default
51
+ removeMomentLocale: true
52
+ }
53
+ };
54
+ }
55
+ export function createBuilderOptions(target, appContext) {
56
+ // create entries
57
+
58
+ const entries = {};
59
+ const {
60
+ entrypoints = [],
61
+ checkedEntries
62
+ } = appContext;
63
+ for (const {
64
+ entryName,
65
+ entry
66
+ } of entrypoints) {
67
+ if (checkedEntries && !checkedEntries.includes(entryName)) {
68
+ continue;
69
+ }
70
+ if (entryName in entries) {
71
+ entries[entryName].push(entry);
72
+ } else {
73
+ entries[entryName] = [entry];
74
+ }
75
+ }
76
+ return {
77
+ cwd: appContext.appDirectory,
78
+ target,
79
+ configPath: appContext.configFile || undefined,
80
+ entry: entries,
81
+ framework: appContext.metaName
82
+ };
83
+ }
84
+
85
+ /**
86
+ * register builder Plugin by condition
87
+ */
88
+ async function applyBuilderPlugins(builder, normalizedConfig, appContext, compatPluginConfig) {
89
+ if (!normalizedConfig.output.disableNodePolyfill) {
90
+ const {
91
+ PluginNodePolyfill
92
+ } = await import('@modern-js/builder-plugin-node-polyfill');
93
+ builder.addPlugins([PluginNodePolyfill()]);
94
+ }
95
+ if (normalizedConfig.tools.esbuild) {
96
+ const {
97
+ esbuild: esbuildOptions
98
+ } = normalizedConfig.tools;
99
+ const {
100
+ PluginEsbuild
101
+ } = await import('@modern-js/builder-plugin-esbuild');
102
+ builder.addPlugins([PluginEsbuild({
103
+ loader: false,
104
+ minimize: applyOptionsChain({}, esbuildOptions)
105
+ })]);
106
+ }
107
+ builder.addPlugins([PluginCompatModern(appContext, normalizedConfig, compatPluginConfig)]);
108
+ }