@modern-js/app-tools 1.21.3 → 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 +138 -16
  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
@@ -4,12 +4,12 @@ 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 { fs, logger, chalk, isSSR } from '@modern-js/utils';
7
+ import { logger, isSSR } from '@modern-js/utils';
8
8
  import { ResolvedConfigContext } from '@modern-js/core';
9
- import { createCompiler } from "../utils/createCompiler";
10
- import { createServer } from "../utils/createServer";
11
- import { generateRoutes } from "../utils/routes";
12
9
  import { printInstructions } from "../utils/printInstructions";
10
+ import { createDevCompiler } from "../utils/createCompiler";
11
+ import { createServer, injectDataLoaderPlugin } from "../utils/createServer";
12
+ import { generateRoutes } from "../utils/routes";
13
13
  import { getSpecifiedEntries } from "../utils/getSpecifiedEntries";
14
14
  import { buildServerConfig } from "../utils/config";
15
15
  export const dev = async (api, options) => {
@@ -26,14 +26,14 @@ export const dev = async (api, options) => {
26
26
  port,
27
27
  apiOnly,
28
28
  entrypoints,
29
- serverConfigFile
29
+ serverConfigFile,
30
+ serverInternalPlugins
30
31
  } = appContext;
31
32
  const checkedEntries = await getSpecifiedEntries(options.entry || false, entrypoints);
32
33
  api.setAppContext(_objectSpread(_objectSpread({}, appContext), {}, {
33
34
  checkedEntries
34
35
  }));
35
36
  appContext.checkedEntries = checkedEntries;
36
- fs.emptyDirSync(distDirectory);
37
37
  await buildServerConfig({
38
38
  appDirectory,
39
39
  distDirectory,
@@ -48,15 +48,11 @@ export const dev = async (api, options) => {
48
48
  let compiler = null;
49
49
 
50
50
  if (!apiOnly) {
51
- const {
52
- getWebpackConfig,
53
- WebpackConfigTarget
54
- } = await import('@modern-js/webpack');
55
- const webpackConfigs = [isSSR(userConfig) && getWebpackConfig(WebpackConfigTarget.NODE, appContext, userConfig), getWebpackConfig(WebpackConfigTarget.CLIENT, appContext, userConfig)].filter(Boolean);
56
- compiler = await createCompiler({
51
+ const target = isSSR(userConfig) ? ['web', 'node'] : ['web'];
52
+ compiler = await createDevCompiler({
53
+ target,
57
54
  api,
58
- webpackConfigs,
59
- userConfig,
55
+ normalizedConfig: userConfig,
60
56
  appContext
61
57
  });
62
58
  }
@@ -79,17 +75,17 @@ export const dev = async (api, options) => {
79
75
  pwd: appDirectory,
80
76
  config: userConfig,
81
77
  serverConfigFile,
82
- plugins: appContext.plugins.filter(p => p.server).map(p => p.server)
78
+ internalPlugins: injectDataLoaderPlugin(serverInternalPlugins)
83
79
  });
84
80
  app.listen(port, async err => {
85
81
  if (err) {
86
82
  throw err;
87
83
  }
88
84
 
89
- if (apiOnly) {
90
- return printInstructions(hookRunners, appContext, userConfig);
85
+ if (!apiOnly) {
86
+ logger.info(`Starting dev server...`);
87
+ } else {
88
+ printInstructions(hookRunners, appContext, userConfig);
91
89
  }
92
-
93
- return logger.log(chalk.cyan(`Starting the development server...`));
94
90
  });
95
91
  };
@@ -1,69 +1,28 @@
1
- import path from 'path';
2
- import { getWebpackConfig, WebpackConfigTarget } from '@modern-js/webpack';
3
- import { fs, logger, isUseSSRBundle, chalk } from '@modern-js/utils';
4
- import WebpackChain from '@modern-js/utils/webpack-chain';
5
- export const formatWebpackConfig = (config, verbose) => {
6
- const stringify = WebpackChain.toString;
7
- return `module.exports = ${stringify(config, {
8
- verbose
9
- })};`;
10
- };
11
- export const inspect = (api, options) => {
12
- process.env.NODE_ENV = options.env;
1
+ import { join } from 'path';
2
+ import { isUseSSRBundle } from '@modern-js/utils';
3
+ import createBuilder from "../builder";
4
+ export const inspect = async (api, options) => {
13
5
  const resolvedConfig = api.useResolvedConfigContext();
14
6
  const appContext = api.useAppContext();
15
- const outputFiles = [];
16
- outputFiles.push(printInspectResult(WebpackConfigTarget.CLIENT, appContext, resolvedConfig, options));
7
+ const targets = ['web'];
17
8
 
18
9
  if (resolvedConfig.output.enableModernMode) {
19
- outputFiles.push(printInspectResult(WebpackConfigTarget.MODERN, appContext, resolvedConfig, options));
10
+ targets.push('modern-web');
20
11
  }
21
12
 
22
13
  if (isUseSSRBundle(resolvedConfig)) {
23
- outputFiles.push(printInspectResult(WebpackConfigTarget.NODE, appContext, resolvedConfig, options));
14
+ targets.push('node');
24
15
  }
25
16
 
26
- logger.success('Inspect succeed, you can open following files to view the full webpack config: \n');
27
- outputFiles.forEach(file => {
28
- logger.log(` - ${chalk.yellow(path.relative(appContext.appDirectory, file))}`);
17
+ const builder = await createBuilder({
18
+ target: targets,
19
+ appContext,
20
+ normalizedConfig: resolvedConfig
21
+ });
22
+ return builder.inspectConfig({
23
+ env: options.env,
24
+ verbose: options.verbose,
25
+ outputPath: join(builder.context.distPath, options.output),
26
+ writeToDisk: true
29
27
  });
30
- logger.log();
31
- };
32
- export const getTagByWebpackTarget = webpackTarget => {
33
- switch (webpackTarget) {
34
- case WebpackConfigTarget.CLIENT:
35
- return 'client';
36
-
37
- case WebpackConfigTarget.MODERN:
38
- return 'modern';
39
-
40
- case WebpackConfigTarget.NODE:
41
- return 'ssr';
42
-
43
- default:
44
- throw Error(`Unsupported webpack target: ${webpackTarget}`);
45
- }
46
- };
47
- export const printInspectResult = (webpackTarget, appContext, resolvedConfig, options) => {
48
- const webpackConfig = getWebpackConfig(webpackTarget, appContext, resolvedConfig);
49
- const {
50
- output,
51
- verbose,
52
- console = true
53
- } = options;
54
- const outputPath = output ? path.posix.join(appContext.distDirectory, output) : appContext.distDirectory;
55
- const tag = getTagByWebpackTarget(webpackTarget);
56
- const outputFile = `webpack.${tag}.inspect.js`;
57
- const outputFilePath = path.posix.join(outputPath, outputFile);
58
- const rawWebpackConfig = formatWebpackConfig(webpackConfig, verbose);
59
- fs.outputFileSync(outputFilePath, rawWebpackConfig);
60
-
61
- if (console) {
62
- logger.log(`
63
- webpack config for ${tag} build:
64
- ${rawWebpackConfig}
65
- `);
66
- }
67
-
68
- return outputFilePath;
69
28
  };
@@ -1,6 +1,7 @@
1
1
  import { logger, chalk, isApiOnly } from '@modern-js/utils';
2
2
  import server from '@modern-js/prod-server';
3
3
  import { printInstructions } from "../utils/printInstructions";
4
+ import { injectDataLoaderPlugin } from "../utils/createServer";
4
5
  export const start = async api => {
5
6
  var _userConfig$source;
6
7
 
@@ -17,8 +18,8 @@ export const start = async api => {
17
18
  const app = await server({
18
19
  pwd: appDirectory,
19
20
  config: userConfig,
20
- plugins: appContext.plugins.filter(p => p.server).map(p => p.server),
21
21
  serverConfigFile,
22
+ internalPlugins: injectDataLoaderPlugin(appContext.serverInternalPlugins),
22
23
  apiOnly
23
24
  });
24
25
  app.listen(port, async err => {
@@ -7,16 +7,17 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
7
7
  import path from 'path';
8
8
  import { defineConfig, cli } from '@modern-js/core';
9
9
  import LintPlugin from '@modern-js/plugin-jarvis';
10
- import { cleanRequireCache, Import } from '@modern-js/utils';
10
+ import { cleanRequireCache, emptyDir, Import } from '@modern-js/utils';
11
11
  import AnalyzePlugin from "./analyze";
12
12
  import { hooks } from "./hooks";
13
13
  import { i18n, localeKeys } from "./locale";
14
14
  import { getLocaleLanguage } from "./utils/language";
15
- export { defineConfig };
15
+ import { getCommand } from "./utils/commands";
16
+ export { defineConfig, hooks };
16
17
  const upgradeModel = Import.lazy('@modern-js/upgrade', require);
17
18
  export default (() => ({
18
19
  name: '@modern-js/app-tools',
19
- post: ['@modern-js/plugin-analyze', '@modern-js/plugin-ssr', '@modern-js/plugin-state', '@modern-js/plugin-router', '@modern-js/plugin-polyfill'],
20
+ post: ['@modern-js/plugin-analyze', '@modern-js/plugin-ssr', '@modern-js/plugin-state', '@modern-js/plugin-router', '@modern-js/plugin-router-legacy', '@modern-js/plugin-polyfill'],
20
21
  registerHook: hooks,
21
22
  usePlugins: [AnalyzePlugin(), LintPlugin()],
22
23
  setup: api => {
@@ -69,7 +70,7 @@ export default (() => ({
69
70
  locale
70
71
  }));
71
72
  });
72
- program.command('inspect').description('inspect internal webpack config').option(`--env <env>`, i18n.t(localeKeys.command.inspect.env), 'development').option('--output <output>', i18n.t(localeKeys.command.inspect.output), '/').option('--no-console', i18n.t(localeKeys.command.inspect.noConsole)).option('--verbose', i18n.t(localeKeys.command.inspect.verbose)).option('-c --config <config>', i18n.t(localeKeys.command.shared.config)).action(async options => {
73
+ program.command('inspect').description('inspect internal webpack config').option(`--env <env>`, i18n.t(localeKeys.command.inspect.env), 'development').option('--output <output>', i18n.t(localeKeys.command.inspect.output), '/').option('--verbose', i18n.t(localeKeys.command.inspect.verbose)).option('-c --config <config>', i18n.t(localeKeys.command.shared.config)).action(async options => {
73
74
  const {
74
75
  inspect
75
76
  } = await import("./commands/inspect");
@@ -78,6 +79,15 @@ export default (() => ({
78
79
  upgradeModel.defineCommand(program.command('upgrade'));
79
80
  },
80
81
 
82
+ async prepare() {
83
+ const command = getCommand();
84
+
85
+ if (command === 'dev' || command === 'build') {
86
+ const appContext = api.useAppContext();
87
+ await emptyDir(appContext.distDirectory);
88
+ }
89
+ },
90
+
81
91
  // 这里会被 core/initWatcher 监听的文件变动触发,如果是 src 目录下的文件变动,则不做 restart
82
92
  async fileChange(e) {
83
93
  const {
@@ -28,7 +28,6 @@ export const EN_LOCALE = {
28
28
  inspect: {
29
29
  env: 'specify env mode',
30
30
  output: 'specify inspect content output path',
31
- noConsole: 'do not log the result in terminal',
32
31
  verbose: 'show full function definitions in output'
33
32
  }
34
33
  }
@@ -28,7 +28,6 @@ export const ZH_LOCALE = {
28
28
  inspect: {
29
29
  env: '查看指定环境下的配置',
30
30
  output: '指定在 dist 目录下输出的路径',
31
- noConsole: '不在终端中输出完整结果',
32
31
  verbose: '在结果中展示函数的完整内容'
33
32
  }
34
33
  }
@@ -0,0 +1,5 @@
1
+ export const getCommand = () => {
2
+ const args = process.argv.slice(2);
3
+ const command = args[0];
4
+ return command;
5
+ };
@@ -1,55 +1,52 @@
1
- import { webpack } from '@modern-js/webpack';
2
- import { chalk, logger, formatWebpackMessages, clearConsole } from '@modern-js/utils';
1
+ import { chalk, logger } from '@modern-js/utils';
2
+ import createBuilder from "../builder";
3
3
  import { printInstructions } from "./printInstructions";
4
- export const createCompiler = async ({
4
+ export const createDevCompiler = async ({
5
5
  api,
6
- webpackConfigs,
7
- // TODO: params
8
- userConfig,
6
+ target,
7
+ normalizedConfig,
9
8
  appContext
10
9
  }) => {
11
10
  try {
12
11
  const hookRunners = api.useHookRunners();
13
- await hookRunners.beforeCreateCompiler({
14
- webpackConfigs
15
- });
16
- const compiler = webpack(webpackConfigs);
17
- await hookRunners.afterCreateCompiler({
18
- compiler
19
- });
20
- let isFirstCompile = true;
21
- compiler.hooks.invalid.tap('invalid', () => {
22
- clearConsole();
23
- logger.log('Compiling...');
24
- });
25
- compiler.hooks.done.tap('done', async stats => {
26
- const statsData = stats.toJson({
27
- preset: 'errors-warnings'
28
- });
29
- const {
30
- errors,
31
- warnings
32
- } = formatWebpackMessages(statsData);
12
+ const builder = await createBuilder({
13
+ target,
14
+ normalizedConfig,
15
+ appContext,
16
+ compatPluginConfig: {
17
+ async onDevCompileDone({
18
+ isFirstCompile
19
+ }) {
20
+ if (process.stdout.isTTY || isFirstCompile) {
21
+ hookRunners.afterDev();
33
22
 
34
- if (errors.length) {
35
- logger.log(chalk.red(`Failed to compile.\n`));
36
- logger.log(errors.join('\n\n'));
37
- logger.log();
38
- } else if (process.stdout.isTTY || isFirstCompile) {
39
- await hookRunners.afterDev();
23
+ if (isFirstCompile) {
24
+ printInstructions(hookRunners, appContext, normalizedConfig);
25
+ }
26
+ }
27
+ },
40
28
 
41
- if (warnings.length) {
42
- logger.log(chalk.yellow(`Compiled with warnings.\n`));
43
- logger.log(warnings.join('\n\n'));
44
- logger.log();
29
+ async onBeforeCreateCompiler({
30
+ bundlerConfigs
31
+ }) {
32
+ // run modernjs framework `beforeCreateCompiler` hook
33
+ await hookRunners.beforeCreateCompiler({
34
+ bundlerConfigs
35
+ });
36
+ },
37
+
38
+ async onAfterCreateCompiler({
39
+ compiler
40
+ }) {
41
+ // run modernjs framework afterCreateCompiler hooks
42
+ await hookRunners.afterCreateCompiler({
43
+ compiler
44
+ });
45
45
  }
46
46
 
47
- await printInstructions(hookRunners, appContext, userConfig);
48
47
  }
49
-
50
- isFirstCompile = false;
51
48
  });
52
- return compiler;
49
+ return builder.createCompiler();
53
50
  } catch (err) {
54
51
  logger.log(chalk.red(`Failed to compile.`));
55
52
  logger.log();
@@ -1,3 +1,9 @@
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
+
1
7
  import { Server } from '@modern-js/server';
2
8
  let server = null;
3
9
  export const getServer = () => server;
@@ -15,4 +21,14 @@ export const createServer = async options => {
15
21
  server = new Server(options);
16
22
  const app = await server.init();
17
23
  return app;
24
+ };
25
+ export const injectDataLoaderPlugin = internalPlugins => {
26
+ const DataLoaderPlugin = require.resolve('@modern-js/plugin-data-loader/server');
27
+
28
+ return _objectSpread(_objectSpread({}, internalPlugins), {}, {
29
+ '@modern-js/plugin-data-loader': {
30
+ path: DataLoaderPlugin,
31
+ forced: true
32
+ }
33
+ });
18
34
  };
@@ -7,5 +7,5 @@ export const printInstructions = async (hookRunners, appContext, config) => {
7
7
  } = await hookRunners.beforePrintInstructions({
8
8
  instructions: message
9
9
  });
10
- logger.log(instructions);
10
+ logger.info(instructions);
11
11
  };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.PAGES_DIR_NAME = exports.JS_EXTENSIONS = exports.INDEX_FILE_NAME = exports.HTML_PARTIALS_FOLDER = exports.HTML_PARTIALS_EXTENSIONS = exports.FILE_SYSTEM_ROUTES_LAYOUT = exports.FILE_SYSTEM_ROUTES_INDEX = exports.FILE_SYSTEM_ROUTES_IGNORED_REGEX = exports.FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT = exports.FILE_SYSTEM_ROUTES_FILE_NAME = exports.FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP = exports.FILE_SYSTEM_ROUTES_COMPONENTS_DIR = exports.ENTRY_POINT_FILE_NAME = exports.ENTRY_BOOTSTRAP_FILE_NAME = exports.APP_FILE_NAME = void 0;
6
+ exports.PAGES_DIR_NAME = exports.NESTED_ROUTES_DIR = exports.JS_EXTENSIONS = exports.INDEX_FILE_NAME = exports.HTML_PARTIALS_FOLDER = exports.HTML_PARTIALS_EXTENSIONS = exports.FILE_SYSTEM_ROUTES_LAYOUT = exports.FILE_SYSTEM_ROUTES_INDEX = exports.FILE_SYSTEM_ROUTES_IGNORED_REGEX = exports.FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT = exports.FILE_SYSTEM_ROUTES_FILE_NAME = exports.FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP = exports.FILE_SYSTEM_ROUTES_COMPONENTS_DIR = exports.ENTRY_POINT_FILE_NAME = exports.ENTRY_BOOTSTRAP_FILE_NAME = exports.APP_FILE_NAME = void 0;
7
7
  const JS_EXTENSIONS = ['.js', '.ts', '.jsx', '.tsx'];
8
8
  exports.JS_EXTENSIONS = JS_EXTENSIONS;
9
9
  const INDEX_FILE_NAME = 'index';
@@ -12,6 +12,8 @@ const APP_FILE_NAME = 'App';
12
12
  exports.APP_FILE_NAME = APP_FILE_NAME;
13
13
  const PAGES_DIR_NAME = 'pages';
14
14
  exports.PAGES_DIR_NAME = PAGES_DIR_NAME;
15
+ const NESTED_ROUTES_DIR = 'routes';
16
+ exports.NESTED_ROUTES_DIR = NESTED_ROUTES_DIR;
15
17
  const FILE_SYSTEM_ROUTES_FILE_NAME = 'routes.js';
16
18
  exports.FILE_SYSTEM_ROUTES_FILE_NAME = FILE_SYSTEM_ROUTES_FILE_NAME;
17
19
  const ENTRY_POINT_FILE_NAME = 'index.js';
@@ -9,6 +9,12 @@ var _path = _interopRequireDefault(require("path"));
9
9
 
10
10
  var _utils = require("@modern-js/utils");
11
11
 
12
+ var _core = require("@modern-js/core");
13
+
14
+ var _esbuild = _interopRequireDefault(require("esbuild"));
15
+
16
+ var _commands = require("../utils/commands");
17
+
12
18
  var templates = _interopRequireWildcard(require("./templates"));
13
19
 
14
20
  var _getClientRoutes = require("./getClientRoutes");
@@ -17,6 +23,8 @@ var _constants = require("./constants");
17
23
 
18
24
  var _utils2 = require("./utils");
19
25
 
26
+ var _nestedRoutes = require("./nestedRoutes");
27
+
20
28
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
29
 
22
30
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -86,21 +94,67 @@ const createImportStatements = statements => {
86
94
 
87
95
  exports.createImportStatements = createImportStatements;
88
96
 
97
+ const buildLoader = async (entry, outfile) => {
98
+ const loader = {
99
+ '.js': 'jsx',
100
+ '.ts': 'tsx'
101
+ };
102
+ const EXTERNAL_REGEXP = /^[^./]|^\.[^./]|^\.\.[^/]/;
103
+ const command = (0, _commands.getCommand)();
104
+ await _esbuild.default.build({
105
+ format: 'cjs',
106
+ platform: 'node',
107
+ target: 'esnext',
108
+ loader,
109
+ watch: command === 'dev' && {},
110
+ bundle: true,
111
+ logLevel: 'error',
112
+ entryPoints: [entry],
113
+ outfile,
114
+ plugins: [{
115
+ name: 'make-all-packages-external',
116
+
117
+ setup(build) {
118
+ // https://github.com/evanw/esbuild/issues/619#issuecomment-751995294
119
+ build.onResolve({
120
+ filter: EXTERNAL_REGEXP
121
+ }, args => {
122
+ let external = true; // FIXME: windows external entrypoint
123
+
124
+ if (args.kind === 'entry-point') {
125
+ external = false;
126
+ }
127
+
128
+ return {
129
+ path: args.path,
130
+ external
131
+ };
132
+ });
133
+ }
134
+
135
+ }]
136
+ });
137
+ };
138
+
89
139
  const generateCode = async (appContext, config, entrypoints, api) => {
140
+ var _config$runtime, _config$runtime$route;
141
+
90
142
  const {
91
143
  internalDirectory,
144
+ distDirectory,
92
145
  srcDirectory,
93
146
  internalDirAlias,
94
147
  internalSrcAlias
95
148
  } = appContext;
96
149
  const hookRunners = api.useHookRunners();
150
+ const islegacy = Boolean(config === null || config === void 0 ? void 0 : (_config$runtime = config.runtime) === null || _config$runtime === void 0 ? void 0 : (_config$runtime$route = _config$runtime.router) === null || _config$runtime$route === void 0 ? void 0 : _config$runtime$route.legacy);
97
151
  const {
98
- output: {
99
- mountId
100
- }
101
- } = config;
152
+ mountId
153
+ } = config.output;
154
+ const getRoutes = islegacy ? _getClientRoutes.getClientRoutesLegacy : _getClientRoutes.getClientRoutes;
155
+ await Promise.all(entrypoints.map(generateEntryCode));
102
156
 
103
- for (const entrypoint of entrypoints) {
157
+ async function generateEntryCode(entrypoint) {
104
158
  const {
105
159
  entryName,
106
160
  isAutoMount,
@@ -111,27 +165,80 @@ const generateCode = async (appContext, config, entrypoints, api) => {
111
165
  if (isAutoMount) {
112
166
  // generate routes file for file system routes entrypoint.
113
167
  if (fileSystemRoutes) {
114
- const initialRoutes = (0, _getClientRoutes.getClientRoutes)({
115
- entrypoint,
116
- srcDirectory,
117
- srcAlias: internalSrcAlias,
118
- internalDirectory,
119
- internalDirAlias
120
- });
168
+ let initialRoutes = [];
169
+ let nestedRoute = null;
170
+
171
+ if (entrypoint.entry) {
172
+ initialRoutes = getRoutes({
173
+ entrypoint,
174
+ srcDirectory,
175
+ srcAlias: internalSrcAlias,
176
+ internalDirectory,
177
+ internalDirAlias
178
+ });
179
+ }
180
+
181
+ if (entrypoint.nestedRoutesEntry) {
182
+ if (!islegacy) {
183
+ nestedRoute = await (0, _nestedRoutes.walk)(entrypoint.nestedRoutesEntry, entrypoint.nestedRoutesEntry, {
184
+ name: internalSrcAlias,
185
+ basename: srcDirectory
186
+ });
187
+
188
+ if (nestedRoute) {
189
+ initialRoutes.unshift(nestedRoute);
190
+ }
191
+ } else {
192
+ _utils.logger.error('Nested routes is not supported in legacy mode.'); // eslint-disable-next-line no-process-exit
193
+
194
+
195
+ process.exit(1);
196
+ }
197
+ }
198
+
121
199
  const {
122
200
  routes
123
201
  } = await hookRunners.modifyFileSystemRoutes({
124
202
  entrypoint,
125
203
  routes: initialRoutes
126
204
  });
205
+ const config = (0, _core.useResolvedConfigContext)();
206
+ const ssr = config === null || config === void 0 ? void 0 : config.server.ssr;
207
+ let mode;
208
+
209
+ if (ssr) {
210
+ mode = typeof ssr === 'object' ? ssr.mode || 'string' : 'string';
211
+ } else {
212
+ mode = false;
213
+ }
214
+
127
215
  const {
128
216
  code
129
217
  } = await hookRunners.beforeGenerateRoutes({
130
218
  entrypoint,
131
219
  code: templates.fileSystemRoutes({
132
- routes
220
+ routes,
221
+ ssrMode: mode,
222
+ nestedRoutesEntry: entrypoint.nestedRoutesEntry
133
223
  })
134
- });
224
+ }); // extract nested router loaders
225
+
226
+ if (entrypoint.nestedRoutesEntry) {
227
+ const routesServerFile = _path.default.join(internalDirectory, entryName, 'routes.server.js');
228
+
229
+ const outputRoutesServerFile = _path.default.join(distDirectory, 'loader-routes', entryName, 'index.js');
230
+
231
+ const code = templates.routesForServer({
232
+ routes: routes,
233
+ alias: {
234
+ name: internalSrcAlias,
235
+ basename: srcDirectory
236
+ }
237
+ });
238
+ await _utils.fs.ensureFile(routesServerFile);
239
+ await _utils.fs.writeFile(routesServerFile, code);
240
+ await buildLoader(routesServerFile, outputRoutesServerFile);
241
+ }
135
242
 
136
243
  _utils.fs.outputFileSync(_path.default.resolve(internalDirectory, `./${entryName}/${_constants.FILE_SYSTEM_ROUTES_FILE_NAME}`), code, 'utf8');
137
244
  } // call modifyEntryImports hook
@@ -78,8 +78,9 @@ const getBundleEntry = (appContext, config) => {
78
78
  const entriesDirAbs = (0, _utils.ensureAbsolutePath)(appDirectory, entriesDir);
79
79
  const found = defaults.find(({
80
80
  entryName,
81
- entry
82
- }) => entryName === packageName || _path.default.dirname(entry) === entriesDirAbs);
81
+ entry,
82
+ nestedRoutesEntry: _nestedRoutesEntry = ''
83
+ }) => entryName === packageName || _path.default.dirname(entry) === entriesDirAbs || _path.default.dirname(_nestedRoutesEntry) === entriesDirAbs);
83
84
  found && (found.entryName = _utils.MAIN_ENTRY_NAME);
84
85
  }
85
86