@modern-js/app-tools 1.21.2 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/dist/js/modern/analyze/constants.js +1 -0
  3. package/dist/js/modern/analyze/generateCode.js +118 -16
  4. package/dist/js/modern/analyze/getBundleEntry.js +3 -2
  5. package/dist/js/modern/analyze/getClientRoutes/getRoutes.js +198 -0
  6. package/dist/js/modern/analyze/{getClientRoutes.js → getClientRoutes/getRoutesLegacy.js} +8 -28
  7. package/dist/js/modern/analyze/getClientRoutes/index.js +2 -0
  8. package/dist/js/modern/analyze/getClientRoutes/utils.js +21 -0
  9. package/dist/js/modern/analyze/getFileSystemEntry.js +31 -12
  10. package/dist/js/modern/analyze/index.js +2 -1
  11. package/dist/js/modern/analyze/nestedRoutes.js +127 -0
  12. package/dist/js/modern/analyze/templates.js +164 -10
  13. package/dist/js/modern/analyze/utils.js +2 -1
  14. package/dist/js/modern/builder/builderPlugins/compatModern.js +226 -0
  15. package/dist/js/modern/builder/createHtmlConfig.js +58 -0
  16. package/dist/js/modern/builder/createOutputConfig.js +67 -0
  17. package/dist/js/modern/builder/createSourceConfig.js +85 -0
  18. package/dist/js/modern/builder/createToolsConfig.js +94 -0
  19. package/dist/js/modern/builder/index.js +106 -0
  20. package/dist/js/modern/builder/share.js +48 -0
  21. package/dist/js/modern/builder/webpackPlugins/htmlAsyncChunkPlugin.js +37 -0
  22. package/dist/js/modern/builder/webpackPlugins/htmlBottomTemplate.js +44 -0
  23. package/dist/js/modern/commands/build.js +41 -95
  24. package/dist/js/modern/commands/dev.js +15 -19
  25. package/dist/js/modern/commands/inspect.js +17 -58
  26. package/dist/js/modern/commands/start.js +2 -1
  27. package/dist/js/modern/index.js +14 -4
  28. package/dist/js/modern/locale/en.js +0 -1
  29. package/dist/js/modern/locale/zh.js +0 -1
  30. package/dist/js/modern/utils/commands.js +5 -0
  31. package/dist/js/modern/utils/createCompiler.js +37 -40
  32. package/dist/js/modern/utils/createServer.js +16 -0
  33. package/dist/js/modern/utils/printInstructions.js +1 -1
  34. package/dist/js/node/analyze/constants.js +3 -1
  35. package/dist/js/node/analyze/generateCode.js +121 -14
  36. package/dist/js/node/analyze/getBundleEntry.js +3 -2
  37. package/dist/js/node/analyze/getClientRoutes/getRoutes.js +221 -0
  38. package/dist/js/node/analyze/{getClientRoutes.js → getClientRoutes/getRoutesLegacy.js} +16 -35
  39. package/dist/js/node/analyze/getClientRoutes/index.js +21 -0
  40. package/dist/js/node/analyze/getClientRoutes/utils.js +42 -0
  41. package/dist/js/node/analyze/getFileSystemEntry.js +30 -11
  42. package/dist/js/node/analyze/index.js +2 -1
  43. package/dist/js/node/analyze/nestedRoutes.js +144 -0
  44. package/dist/js/node/analyze/templates.js +167 -10
  45. package/dist/js/node/analyze/utils.js +6 -2
  46. package/dist/js/node/builder/builderPlugins/compatModern.js +245 -0
  47. package/dist/js/node/builder/createHtmlConfig.js +76 -0
  48. package/dist/js/node/builder/createOutputConfig.js +75 -0
  49. package/dist/js/node/builder/createSourceConfig.js +99 -0
  50. package/dist/js/node/builder/createToolsConfig.js +103 -0
  51. package/dist/js/node/builder/index.js +129 -0
  52. package/dist/js/node/builder/share.js +63 -0
  53. package/dist/js/node/builder/webpackPlugins/htmlAsyncChunkPlugin.js +46 -0
  54. package/dist/js/node/builder/webpackPlugins/htmlBottomTemplate.js +53 -0
  55. package/dist/js/node/commands/build.js +44 -98
  56. package/dist/js/node/commands/dev.js +13 -23
  57. package/dist/js/node/commands/inspect.js +18 -74
  58. package/dist/js/node/commands/start.js +3 -1
  59. package/dist/js/node/index.js +19 -2
  60. package/dist/js/node/locale/en.js +0 -1
  61. package/dist/js/node/locale/zh.js +0 -1
  62. package/dist/js/node/utils/commands.js +14 -0
  63. package/dist/js/node/utils/createCompiler.js +43 -49
  64. package/dist/js/node/utils/createServer.js +21 -2
  65. package/dist/js/node/utils/printInstructions.js +1 -1
  66. package/dist/js/treeshaking/analyze/constants.js +16 -0
  67. package/dist/js/treeshaking/analyze/generateCode.js +412 -0
  68. package/dist/js/treeshaking/analyze/getBundleEntry.js +77 -0
  69. package/dist/js/treeshaking/analyze/getClientRoutes/getRoutes.js +210 -0
  70. package/dist/js/treeshaking/analyze/getClientRoutes/getRoutesLegacy.js +211 -0
  71. package/dist/js/treeshaking/analyze/getClientRoutes/index.js +2 -0
  72. package/dist/js/treeshaking/analyze/getClientRoutes/utils.js +27 -0
  73. package/dist/js/treeshaking/analyze/getFileSystemEntry.js +109 -0
  74. package/dist/js/treeshaking/analyze/getHtmlTemplate.js +153 -0
  75. package/dist/js/treeshaking/analyze/getServerRoutes.js +170 -0
  76. package/dist/js/treeshaking/analyze/index.js +214 -0
  77. package/dist/js/treeshaking/analyze/isDefaultExportFunction.js +32 -0
  78. package/dist/js/treeshaking/analyze/makeLegalIdentifier.js +18 -0
  79. package/dist/js/treeshaking/analyze/nestedRoutes.js +207 -0
  80. package/dist/js/treeshaking/analyze/templates.js +189 -0
  81. package/dist/js/treeshaking/analyze/utils.js +95 -0
  82. package/dist/js/treeshaking/builder/builderPlugins/compatModern.js +231 -0
  83. package/dist/js/treeshaking/builder/createHtmlConfig.js +59 -0
  84. package/dist/js/treeshaking/builder/createOutputConfig.js +67 -0
  85. package/dist/js/treeshaking/builder/createSourceConfig.js +100 -0
  86. package/dist/js/treeshaking/builder/createToolsConfig.js +90 -0
  87. package/dist/js/treeshaking/builder/index.js +172 -0
  88. package/dist/js/treeshaking/builder/share.js +50 -0
  89. package/dist/js/treeshaking/builder/webpackPlugins/htmlAsyncChunkPlugin.js +58 -0
  90. package/dist/js/treeshaking/builder/webpackPlugins/htmlBottomTemplate.js +53 -0
  91. package/dist/js/treeshaking/commands/build.js +168 -0
  92. package/dist/js/treeshaking/commands/deploy.js +29 -0
  93. package/dist/js/treeshaking/commands/dev.js +146 -0
  94. package/dist/js/treeshaking/commands/index.js +3 -0
  95. package/dist/js/treeshaking/commands/inspect.js +52 -0
  96. package/dist/js/treeshaking/commands/start.js +78 -0
  97. package/dist/js/treeshaking/exports/server.js +1 -0
  98. package/dist/js/treeshaking/hooks.js +21 -0
  99. package/dist/js/treeshaking/index.js +304 -0
  100. package/dist/js/treeshaking/locale/en.js +34 -0
  101. package/dist/js/treeshaking/locale/index.js +9 -0
  102. package/dist/js/treeshaking/locale/zh.js +34 -0
  103. package/dist/js/treeshaking/utils/commands.js +5 -0
  104. package/dist/js/treeshaking/utils/config.js +140 -0
  105. package/dist/js/treeshaking/utils/createCompiler.js +117 -0
  106. package/dist/js/treeshaking/utils/createServer.js +83 -0
  107. package/dist/js/treeshaking/utils/getSpecifiedEntries.js +68 -0
  108. package/dist/js/treeshaking/utils/language.js +5 -0
  109. package/dist/js/treeshaking/utils/printInstructions.js +35 -0
  110. package/dist/js/treeshaking/utils/routes.js +33 -0
  111. package/dist/js/treeshaking/utils/types.js +0 -0
  112. package/dist/types/analyze/constants.d.ts +1 -0
  113. package/dist/types/analyze/generateCode.d.ts +1 -1
  114. package/dist/types/analyze/{getClientRoutes.d.ts → getClientRoutes/getRoutes.d.ts} +2 -7
  115. package/dist/types/analyze/getClientRoutes/getRoutesLegacy.d.ts +15 -0
  116. package/dist/types/analyze/getClientRoutes/index.d.ts +2 -0
  117. package/dist/types/analyze/getClientRoutes/utils.d.ts +5 -0
  118. package/dist/types/analyze/index.d.ts +2 -2
  119. package/dist/types/analyze/nestedRoutes.d.ts +5 -0
  120. package/dist/types/analyze/templates.d.ts +17 -3
  121. package/dist/types/analyze/utils.d.ts +2 -1
  122. package/dist/types/builder/builderPlugins/compatModern.d.ts +14 -0
  123. package/dist/types/builder/createHtmlConfig.d.ts +6 -0
  124. package/dist/types/builder/createOutputConfig.d.ts +3 -0
  125. package/dist/types/builder/createSourceConfig.d.ts +5 -0
  126. package/dist/types/builder/createToolsConfig.d.ts +13 -0
  127. package/dist/types/builder/index.d.ts +19 -0
  128. package/dist/types/builder/share.d.ts +26 -0
  129. package/dist/types/builder/webpackPlugins/htmlAsyncChunkPlugin.d.ts +8 -0
  130. package/dist/types/builder/webpackPlugins/htmlBottomTemplate.d.ts +10 -0
  131. package/dist/types/commands/build.d.ts +2 -1
  132. package/dist/types/commands/deploy.d.ts +2 -1
  133. package/dist/types/commands/dev.d.ts +2 -1
  134. package/dist/types/commands/inspect.d.ts +5 -6
  135. package/dist/types/commands/start.d.ts +2 -1
  136. package/dist/types/hooks.d.ts +15 -10
  137. package/dist/types/index.d.ts +4 -2
  138. package/dist/types/locale/en.d.ts +0 -1
  139. package/dist/types/locale/index.d.ts +0 -2
  140. package/dist/types/locale/zh.d.ts +0 -1
  141. package/dist/types/utils/commands.d.ts +1 -0
  142. package/dist/types/utils/createCompiler.d.ts +9 -10
  143. package/dist/types/utils/createServer.d.ts +8 -1
  144. package/dist/types/utils/printInstructions.d.ts +3 -2
  145. package/dist/types/utils/types.d.ts +2 -3
  146. package/package.json +25 -43
@@ -0,0 +1,67 @@
1
+ import { createCopyPattern } from "./share";
2
+ export function createOutputConfig(normalizedConfig, appContext) {
3
+ // TODO: add `externals` options in Modern.
4
+ const {
5
+ assetPrefix,
6
+ copy,
7
+ cssModuleLocalIdentName,
8
+ cssPath,
9
+ jsPath,
10
+ htmlPath,
11
+ mediaPath,
12
+ path,
13
+ disableInlineRuntimeChunk,
14
+ disableMinimize,
15
+ disableSourceMap,
16
+ enableCssModuleTSDeclaration,
17
+ enableInlineScripts,
18
+ enableInlineStyles,
19
+ polyfill,
20
+ dataUriLimit,
21
+ disableAssetsCache,
22
+ enableLatestDecorators,
23
+ disableCssModuleExtension
24
+ } = normalizedConfig.output;
25
+ const defaultCopyPattern = createCopyPattern(appContext, normalizedConfig, 'upload');
26
+ const builderCopy = copy ? [...copy, defaultCopyPattern] : [defaultCopyPattern];
27
+ return {
28
+ assetPrefix,
29
+ copy: builderCopy,
30
+ distPath: {
31
+ root: path,
32
+ css: cssPath,
33
+ js: jsPath,
34
+ html: htmlPath,
35
+ // `@modern-js/webpack` output all media files to `dist/media` by default
36
+ svg: mediaPath || 'midia',
37
+ image: mediaPath || 'midia',
38
+ font: mediaPath || 'midia',
39
+ media: mediaPath || 'midia'
40
+ },
41
+ dataUriLimit: {
42
+ svg: dataUriLimit,
43
+ image: dataUriLimit,
44
+ font: dataUriLimit,
45
+ media: dataUriLimit
46
+ },
47
+ disableCssModuleExtension,
48
+ disableInlineRuntimeChunk,
49
+ disableMinimize,
50
+ disableSourceMap,
51
+ enableCssModuleTSDeclaration,
52
+ enableInlineScripts,
53
+ enableInlineStyles,
54
+ polyfill,
55
+ // 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
56
+ cleanDistPath: false,
57
+ disableFilenameHash: disableAssetsCache,
58
+ enableLatestDecorators,
59
+ filename: {
60
+ css: cssModuleLocalIdentName
61
+ },
62
+ // `@modern-js/webpack` used to generate asset manifest by default
63
+ enableAssetManifest: true,
64
+ // compatible the modern-js with fallback behavior
65
+ enableAssetFallback: true
66
+ };
67
+ }
@@ -0,0 +1,85 @@
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
+
14
+ for (const envVar of envVars || []) {
15
+ const envVarValue = process.env[envVar];
16
+ envVarValue && (builderGlobalVars[`process.env.${envVar}`] = envVarValue);
17
+ }
18
+
19
+ const builderModuleScope = createBuilderModuleScope(moduleScopes);
20
+ const builderInclude = createBuilderInclude(include, appContext);
21
+ return {
22
+ alias: mergeAlias(alias),
23
+ moduleScopes: builderModuleScope,
24
+ globalVars: builderGlobalVars,
25
+ include: builderInclude,
26
+ preEntry,
27
+ // ensure resolve.extensions same as before
28
+ resolveExtensionPrefix: '.web'
29
+ };
30
+ }
31
+ export function createBuilderInclude(include, appContext) {
32
+ const defaultInclude = [appContext.internalDirectory];
33
+ const transformInclude = (include || []).map(include => {
34
+ if (typeof include === 'string') {
35
+ if (isAbsolute(include)) {
36
+ return include;
37
+ }
38
+
39
+ return new RegExp(include);
40
+ }
41
+
42
+ return include;
43
+ }).concat(defaultInclude); // concat default Include
44
+
45
+ const root = findMonorepoRoot(appContext.appDirectory);
46
+
47
+ if (!root) {
48
+ return transformInclude;
49
+ }
50
+
51
+ const modernjsMonorepo = isModernjsMonorepo(root);
52
+
53
+ if (modernjsMonorepo) {
54
+ const paths = globby.sync(posix.join(root, 'features', '**', 'package.json'), {
55
+ ignore: ['**/node_modules/**/*']
56
+ }).map(pathname => dirname(pathname) + sep);
57
+ return [...paths, ...transformInclude];
58
+ }
59
+
60
+ return transformInclude;
61
+ }
62
+ export function createBuilderModuleScope(moduleScopes) {
63
+ if (moduleScopes) {
64
+ let builderModuleScope = [];
65
+ const DEFAULT_SCOPES = ['./src', './shared', /node_modules/];
66
+
67
+ if (Array.isArray(moduleScopes)) {
68
+ if (isPrimitiveScope(moduleScopes)) {
69
+ builderModuleScope = DEFAULT_SCOPES.concat(moduleScopes);
70
+ } else {
71
+ builderModuleScope = [DEFAULT_SCOPES, ...moduleScopes];
72
+ }
73
+ } else {
74
+ builderModuleScope = [DEFAULT_SCOPES, moduleScopes];
75
+ }
76
+
77
+ return builderModuleScope;
78
+ } else {
79
+ return undefined;
80
+ }
81
+
82
+ function isPrimitiveScope(items) {
83
+ return items.every(item => typeof item === 'string' || Object.prototype.toString.call(item) === '[object RegExp]');
84
+ }
85
+ }
@@ -0,0 +1,94 @@
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
+ 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
+ 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
+ import { applyOptionsChain } from '@modern-js/utils';
8
+ export function createToolsConfig(normalizedConfig) {
9
+ const {
10
+ disableCssExtract,
11
+ enableTsLoader
12
+ } = normalizedConfig.output;
13
+ const {
14
+ autoprefixer,
15
+ babel,
16
+ minifyCss,
17
+ terser,
18
+ webpack,
19
+ webpackChain,
20
+ tsLoader,
21
+ styledComponents,
22
+ sass,
23
+ postcss,
24
+ less,
25
+ htmlPlugin,
26
+ // TODO: remove modernjs tools.lodash config
27
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
+ lodash
29
+ } = normalizedConfig.tools;
30
+ const builderTsLoader = createBuilderTsLoader(tsLoader, enableTsLoader);
31
+ const builderTsChecker = createBuilderTsChecker(normalizedConfig.output);
32
+ return {
33
+ tsChecker: builderTsChecker,
34
+ styleLoader: disableCssExtract ? {} : undefined,
35
+ cssExtract: disableCssExtract ? false : undefined,
36
+ autoprefixer,
37
+ babel,
38
+ minifyCss,
39
+ terser,
40
+ webpack,
41
+ webpackChain: webpackChain,
42
+ tsLoader: builderTsLoader,
43
+ styledComponents: styledComponents,
44
+ sass: sass,
45
+ postcss: postcss,
46
+ less: less,
47
+ // can't remove comment in html minify.
48
+ // some html template insert by using those comments.
49
+ htmlPlugin: [config => _objectSpread(_objectSpread({}, config), {}, {
50
+ minify: typeof config.minify === 'object' ? _objectSpread(_objectSpread({}, config.minify), {}, {
51
+ removeComments: false
52
+ }) : config.minify
53
+ }), // eslint-disable-next-line no-nested-ternary
54
+ ...(Array.isArray(htmlPlugin) ? htmlPlugin : htmlPlugin ? [htmlPlugin] : [])]
55
+ };
56
+ }
57
+
58
+ function createBuilderTsLoader(tsLoader, enableTsLoader) {
59
+ const useTsLoader = Boolean(enableTsLoader);
60
+
61
+ if (!useTsLoader) {
62
+ return undefined;
63
+ }
64
+
65
+ const defaultTsLoader = {
66
+ compilerOptions: {
67
+ target: 'es5',
68
+ module: 'ESNext'
69
+ },
70
+ transpileOnly: false,
71
+ allowTsInNodeModules: true
72
+ };
73
+ return (_, utils) => applyOptionsChain(defaultTsLoader, tsLoader, utils);
74
+ }
75
+
76
+ export function createBuilderTsChecker(output) {
77
+ if (output.enableTsLoader || output.disableTsChecker) {
78
+ return false;
79
+ }
80
+
81
+ const defaultTsChecker = {
82
+ issue: {
83
+ include: [{
84
+ file: '**/src/**/*'
85
+ }],
86
+ exclude: [{
87
+ file: '**/*.(spec|test).ts'
88
+ }, {
89
+ file: '**/node_modules/**/*'
90
+ }]
91
+ }
92
+ };
93
+ return defaultTsChecker;
94
+ }
@@ -0,0 +1,106 @@
1
+ import { createBuilder } from '@modern-js/builder';
2
+ import { builderWebpackProvider } from '@modern-js/builder-webpack-provider';
3
+ import { applyOptionsChain } 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
+ export default (async ({
10
+ target: _target = 'web',
11
+ normalizedConfig,
12
+ appContext,
13
+ compatPluginConfig
14
+ }) => {
15
+ const targets = Array.isArray(_target) ? _target : [_target];
16
+
17
+ if (normalizedConfig.output.enableModernMode && !targets.includes('modern-web')) {
18
+ targets.push('modern-web');
19
+ }
20
+
21
+ const builderConfig = createBuilderProviderConfig(normalizedConfig, appContext); // create webpack provider
22
+
23
+ const webpackProvider = builderWebpackProvider({
24
+ builderConfig
25
+ });
26
+ const builderOptions = createBuilderOptions(_target, appContext);
27
+ const builder = await createBuilder(webpackProvider, builderOptions);
28
+ await applyBuilderPlugins(builder, normalizedConfig, appContext, compatPluginConfig);
29
+ return builder;
30
+ });
31
+
32
+ function createBuilderProviderConfig(normalizedConfig, appContext) {
33
+ const source = createSourceConfig(normalizedConfig, appContext);
34
+ const html = createHtmlConfig(normalizedConfig, appContext);
35
+ const output = createOutputConfig(normalizedConfig, appContext);
36
+ const tools = createToolsConfig(normalizedConfig);
37
+ return {
38
+ source,
39
+ html,
40
+ output,
41
+ tools,
42
+ performance: {
43
+ // `@modern-js/webpack` used to remove moment locale by default
44
+ removeMomentLocale: true
45
+ }
46
+ };
47
+ }
48
+
49
+ export function createBuilderOptions(target, appContext) {
50
+ // create entries
51
+ const entries = {};
52
+ const {
53
+ entrypoints = [],
54
+ checkedEntries
55
+ } = appContext;
56
+
57
+ for (const {
58
+ entryName,
59
+ entry
60
+ } of entrypoints) {
61
+ if (checkedEntries && !checkedEntries.includes(entryName)) {
62
+ continue;
63
+ }
64
+
65
+ if (entryName in entries) {
66
+ entries[entryName].push(entry);
67
+ } else {
68
+ entries[entryName] = [entry];
69
+ }
70
+ }
71
+
72
+ return {
73
+ cwd: appContext.appDirectory,
74
+ target,
75
+ configPath: appContext.configFile || undefined,
76
+ entry: entries,
77
+ framework: appContext.metaName
78
+ };
79
+ }
80
+ /**
81
+ * register builder Plugin by condition
82
+ */
83
+
84
+ async function applyBuilderPlugins(builder, normalizedConfig, appContext, compatPluginConfig) {
85
+ if (!normalizedConfig.output.disableNodePolyfill) {
86
+ const {
87
+ PluginNodePolyfill
88
+ } = await import('@modern-js/builder-plugin-node-polyfill');
89
+ builder.addPlugins([PluginNodePolyfill()]);
90
+ }
91
+
92
+ if (normalizedConfig.tools.esbuild) {
93
+ const {
94
+ esbuild: esbuildOptions
95
+ } = normalizedConfig.tools;
96
+ const {
97
+ PluginEsbuild
98
+ } = await import('@modern-js/builder-plugin-esbuild');
99
+ builder.addPlugins([PluginEsbuild({
100
+ loader: false,
101
+ minimize: applyOptionsChain({}, esbuildOptions)
102
+ })]);
103
+ }
104
+
105
+ builder.addPlugins([PluginCompatModern(appContext, normalizedConfig, compatPluginConfig)]);
106
+ }
@@ -0,0 +1,48 @@
1
+ import path from 'path';
2
+ import { template as lodashTemplate } from '@modern-js/utils/lodash';
3
+ import { removeTailSlash } from '@modern-js/utils';
4
+ export function createCopyPattern(appContext, config, patternsType, chain) {
5
+ const configDir = path.resolve(appContext.appDirectory, config.source.configDir);
6
+ const uploadDir = path.posix.join(configDir.replace(/\\/g, '/'), 'upload');
7
+ const publicDir = path.posix.join(configDir.replace(/\\/g, '/'), 'public');
8
+ const minifiedJsRexExp = /\.min\.js/;
9
+
10
+ const info = file => ({
11
+ // If the file name ends with `.min.js`, we assume it's a compressed file.
12
+ // So we don't want copy-webpack-plugin to minify it.
13
+ // ref: https://github.com/webpack-contrib/copy-webpack-plugin#info
14
+ minimized: minifiedJsRexExp.test(file.sourceFilename)
15
+ });
16
+
17
+ if (patternsType === 'public') {
18
+ if (!chain) {
19
+ throw new Error("expect get a webpackChain, but receive 'undefined'");
20
+ }
21
+
22
+ return {
23
+ info,
24
+ from: '**/*',
25
+ to: 'public',
26
+ context: publicDir,
27
+ noErrorOnMissing: true,
28
+ // eslint-disable-next-line node/prefer-global/buffer
29
+ transform: (content, absoluteFrom) => {
30
+ if (!/\.html?$/.test(absoluteFrom)) {
31
+ return content;
32
+ }
33
+
34
+ return lodashTemplate(content.toString('utf8'))({
35
+ assetPrefix: removeTailSlash(chain.output.get('publicPath'))
36
+ });
37
+ }
38
+ };
39
+ } else {
40
+ return {
41
+ info,
42
+ from: '**/*',
43
+ to: 'upload',
44
+ context: uploadDir,
45
+ noErrorOnMissing: true
46
+ };
47
+ }
48
+ }
@@ -0,0 +1,37 @@
1
+ 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; }
2
+
3
+ export class HtmlAsyncChunkPlugin {
4
+ constructor(htmlWebpackPlugin) {
5
+ _defineProperty(this, "name", void 0);
6
+
7
+ _defineProperty(this, "htmlWebpackPlugin", void 0);
8
+
9
+ this.name = 'HtmlAsyncChunkPlugin';
10
+ this.htmlWebpackPlugin = htmlWebpackPlugin;
11
+ }
12
+
13
+ apply(compiler) {
14
+ compiler.hooks.compilation.tap(this.name, compilation => {
15
+ const hooks = this.htmlWebpackPlugin.getHooks(compilation);
16
+ hooks.alterAssetTagGroups.tap(this.name, assets => {
17
+ const tags = [...assets.headTags, ...assets.bodyTags];
18
+
19
+ for (const tag of tags) {
20
+ if (tag.tagName === 'script') {
21
+ const {
22
+ attributes
23
+ } = tag;
24
+
25
+ if (attributes && attributes.defer === true) {
26
+ attributes.async = true;
27
+ delete attributes.defer;
28
+ }
29
+ }
30
+ }
31
+
32
+ return assets;
33
+ });
34
+ });
35
+ }
36
+
37
+ }
@@ -0,0 +1,44 @@
1
+ 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; }
2
+
3
+ export class BottomTemplatePlugin {
4
+ constructor(htmlWebpackPlugin) {
5
+ _defineProperty(this, "htmlWebpackPlugin", void 0);
6
+
7
+ _defineProperty(this, "bottomTemplateReg", /<!--<\?-\s*bottomTemplate\s*\?>-->/);
8
+
9
+ _defineProperty(this, "bodyRegExp", /(<\/\s*body\s*>)/i);
10
+
11
+ _defineProperty(this, "name", void 0);
12
+
13
+ this.htmlWebpackPlugin = htmlWebpackPlugin;
14
+ this.name = 'bottom-template';
15
+ }
16
+
17
+ apply(compiler) {
18
+ compiler.hooks.compilation.tap(this.name, compilation => {
19
+ this.htmlWebpackPlugin.getHooks(compilation).beforeEmit.tap(this.name, data => {
20
+ var _data$plugin$options;
21
+
22
+ if (!((_data$plugin$options = data.plugin.options) !== null && _data$plugin$options !== void 0 && _data$plugin$options.__internal__)) {
23
+ return data;
24
+ } // 含有 <!--<?- bottomTemplate ?>--> 占位符时才需要注入 bottom.html
25
+
26
+
27
+ if (this.bottomTemplateReg.test(data.html)) {
28
+ // 清空占位符
29
+ data.html = data.html.replace(this.bottomTemplateReg, '');
30
+ const {
31
+ bottomTemplate
32
+ } = data.plugin.options;
33
+
34
+ if (bottomTemplate) {
35
+ data.html = data.html.replace(this.bodyRegExp, match => `\n${bottomTemplate}\n${match}`);
36
+ }
37
+ }
38
+
39
+ return data;
40
+ });
41
+ });
42
+ }
43
+
44
+ }
@@ -4,14 +4,11 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
4
4
 
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
- import { webpack, getWebpackConfig, WebpackConfigTarget } from '@modern-js/webpack';
8
7
  import { ResolvedConfigContext } from '@modern-js/core';
9
- import { formatWebpackMessages, measureFileSizesBeforeBuild, printFileSizesAfterBuild, printBuildError, logger, isUseSSRBundle, emptyDir } from '@modern-js/utils';
8
+ import { logger, isUseSSRBundle, printBuildError } from '@modern-js/utils';
10
9
  import { generateRoutes } from "../utils/routes";
11
10
  import { buildServerConfig, emitResolvedConfig } from "../utils/config";
12
- // These sizes are pretty large. We'll warn for bundles exceeding them.
13
- const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
14
- const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
11
+ import createBuilder from "../builder";
15
12
  export const build = async (api, options) => {
16
13
  let resolvedConfig = api.useResolvedConfigContext();
17
14
  const appContext = api.useAppContext();
@@ -26,9 +23,9 @@ export const build = async (api, options) => {
26
23
  distDirectory,
27
24
  serverConfigFile
28
25
  } = appContext;
29
- await emptyDir(distDirectory);
30
26
  await hookRunners.beforeBuild({
31
- webpackConfigs: []
27
+ // "null" bundlerConfigs
28
+ bundlerConfigs: undefined
32
29
  });
33
30
  await buildServerConfig({
34
31
  appDirectory,
@@ -36,61 +33,13 @@ export const build = async (api, options) => {
36
33
  configFile: serverConfigFile
37
34
  });
38
35
  await generateRoutes(appContext);
39
- await hookRunners.afterBuild();
36
+ await hookRunners.afterBuild({
37
+ // "null" stats
38
+ stats: undefined
39
+ });
40
40
  return;
41
41
  }
42
42
 
43
- const webpackBuild = async (webpackConfig, type) => {
44
- const compiler = webpack(webpackConfig);
45
- return new Promise((resolve, reject) => {
46
- let label = process.env.NODE_ENV || '';
47
-
48
- if (type && type !== 'legacy') {
49
- label += ` ${type}`;
50
- }
51
-
52
- logger.info(`Creating a ${label} build...`);
53
- compiler.run((err, stats) => {
54
- let messages;
55
-
56
- if (!err) {
57
- messages = formatWebpackMessages(stats.toJson({
58
- all: false,
59
- warnings: true,
60
- errors: true
61
- }));
62
-
63
- if (messages.errors.length === 0) {
64
- logger.info(`File sizes after ${label} build:\n`);
65
- printFileSizesAfterBuild(stats, previousFileSizes, distDirectory, WARN_AFTER_BUNDLE_GZIP_SIZE, WARN_AFTER_CHUNK_GZIP_SIZE);
66
- logger.log();
67
- }
68
- } // When using run or watch, call close and wait for it to finish before calling run or watch again.
69
- // Concurrent compilations will corrupt the output files.
70
-
71
-
72
- compiler.close(closeErr => {
73
- if (closeErr) {
74
- logger.error(closeErr);
75
- }
76
-
77
- if (err) {
78
- reject(err);
79
- } else {
80
- if (messages.errors.length) {
81
- reject(new Error(messages.errors.join('\n\n')));
82
- return;
83
- }
84
-
85
- resolve({
86
- warnings: messages.warnings
87
- });
88
- }
89
- });
90
- });
91
- });
92
- };
93
-
94
43
  resolvedConfig = _objectSpread(_objectSpread({}, resolvedConfig), {}, {
95
44
  cliOptions: options
96
45
  });
@@ -100,55 +49,52 @@ export const build = async (api, options) => {
100
49
  appDirectory,
101
50
  serverConfigFile
102
51
  } = appContext;
103
- const previousFileSizes = await measureFileSizesBeforeBuild(distDirectory);
104
- await emptyDir(distDirectory);
105
52
  await buildServerConfig({
106
53
  appDirectory,
107
54
  distDirectory,
108
55
  configFile: serverConfigFile
109
56
  });
110
- const buildConfigs = [];
111
- buildConfigs.push({
112
- type: 'legacy',
113
- config: getWebpackConfig(WebpackConfigTarget.CLIENT, appContext, resolvedConfig)
114
- });
57
+ const targets = ['web'];
115
58
 
116
59
  if (resolvedConfig.output.enableModernMode) {
117
- buildConfigs.push({
118
- type: 'modern',
119
- config: getWebpackConfig(WebpackConfigTarget.MODERN, appContext, resolvedConfig)
120
- });
60
+ targets.push('modern-web');
121
61
  }
122
62
 
123
63
  if (isUseSSRBundle(resolvedConfig)) {
124
- buildConfigs.push({
125
- type: 'ssr',
126
- config: getWebpackConfig(WebpackConfigTarget.NODE, appContext, resolvedConfig)
127
- });
64
+ targets.push('node');
128
65
  }
129
66
 
130
- await hookRunners.beforeBuild({
131
- webpackConfigs: buildConfigs.map(({
132
- config
133
- }) => config)
134
- });
135
-
136
- for (const buildConfig of buildConfigs) {
137
- const {
138
- type: buildType,
139
- config
140
- } = buildConfig;
67
+ try {
68
+ const builder = await createBuilder({
69
+ target: targets,
70
+ appContext,
71
+ normalizedConfig: resolvedConfig,
72
+ compatPluginConfig: {
73
+ async onBeforeBuild({
74
+ bundlerConfigs
75
+ }) {
76
+ await generateRoutes(appContext);
77
+ await hookRunners.beforeBuild({
78
+ bundlerConfigs
79
+ });
80
+ },
81
+
82
+ async onAfterBuild({
83
+ stats
84
+ }) {
85
+ await hookRunners.afterBuild({
86
+ stats
87
+ });
88
+ await emitResolvedConfig(appDirectory, resolvedConfig);
89
+ }
141
90
 
142
- try {
143
- await webpackBuild(config, buildType);
144
- } catch (error) {
145
- printBuildError(error); // eslint-disable-next-line no-process-exit
91
+ }
92
+ });
93
+ logger.info('Create a production build...\n');
94
+ await builder.build();
95
+ } catch (error) {
96
+ printBuildError(error); // eslint-disable-next-line no-process-exit
146
97
 
147
- process.exit(1);
148
- }
98
+ process.exit(1);
149
99
  }
150
-
151
- await generateRoutes(appContext);
152
- await hookRunners.afterBuild();
153
- await emitResolvedConfig(appDirectory, resolvedConfig);
154
100
  };