@modern-js/app-tools 1.5.0 → 1.6.2

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 (36) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/dist/js/modern/commands/build.js +18 -11
  3. package/dist/js/modern/commands/dev.js +9 -10
  4. package/dist/js/modern/commands/start.js +4 -2
  5. package/dist/js/modern/index.js +2 -2
  6. package/dist/js/modern/locale/en.js +2 -1
  7. package/dist/js/modern/locale/zh.js +2 -1
  8. package/dist/js/modern/utils/config.js +2 -1
  9. package/dist/js/modern/utils/createCompiler.js +1 -1
  10. package/dist/js/modern/utils/getSpecifiedEntries.js +1 -1
  11. package/dist/js/modern/utils/printInstructions.js +2 -2
  12. package/dist/js/node/commands/build.js +19 -12
  13. package/dist/js/node/commands/dev.js +9 -11
  14. package/dist/js/node/commands/start.js +3 -1
  15. package/dist/js/node/index.js +2 -2
  16. package/dist/js/node/locale/en.js +2 -1
  17. package/dist/js/node/locale/zh.js +2 -1
  18. package/dist/js/node/utils/config.js +2 -1
  19. package/dist/js/node/utils/createCompiler.js +2 -4
  20. package/dist/js/node/utils/getSpecifiedEntries.js +2 -4
  21. package/dist/js/node/utils/printInstructions.js +2 -2
  22. package/dist/types/hooks.d.ts +1 -1
  23. package/dist/types/locale/en.d.ts +1 -0
  24. package/dist/types/locale/index.d.ts +2 -0
  25. package/dist/types/locale/zh.d.ts +1 -0
  26. package/dist/types/utils/createCompiler.d.ts +1 -1
  27. package/dist/types/utils/types.d.ts +4 -0
  28. package/package.json +15 -18
  29. package/tests/.eslintrc.js +0 -8
  30. package/tests/__snapshots__/utils.test.ts.snap +0 -5
  31. package/tests/commands/build.test.ts +0 -42
  32. package/tests/commands/dev.test.ts +0 -7
  33. package/tests/index.test.ts +0 -7
  34. package/tests/routes.test.ts +0 -27
  35. package/tests/tsconfig.json +0 -13
  36. package/tests/utils.test.ts +0 -112
package/CHANGELOG.md CHANGED
@@ -1,5 +1,104 @@
1
1
  # @modern-js/app-tools
2
2
 
3
+ ## 1.6.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 8cf0ca21: fix: build commands not work
8
+ - Updated dependencies [4697d1db]
9
+ - Updated dependencies [0ee4bb4e]
10
+ - Updated dependencies [a4c5fe78]
11
+ - Updated dependencies [6fa74d5f]
12
+ - Updated dependencies [a22d3ea8]
13
+ - Updated dependencies [5c00db22]
14
+ - Updated dependencies [92f4909e]
15
+ - @modern-js/webpack@1.6.0
16
+ - @modern-js/core@1.10.0
17
+ - @modern-js/utils@1.7.0
18
+ - @modern-js/prod-server@1.1.3
19
+ - @modern-js/types@1.5.2
20
+ - @modern-js/server@1.4.12
21
+ - @modern-js/plugin-analyze@1.4.1
22
+ - @modern-js/plugin-fast-refresh@1.2.4
23
+ - @modern-js/node-bundle-require@1.3.2
24
+
25
+ ## 1.6.1
26
+
27
+ ### Patch Changes
28
+
29
+ - 77519490: refactor(webpack): remove `@modern-js/core`
30
+ - 592edabc: feat: prebundle url-join,mime-types,json5,fast-glob,globby,ora,inquirer
31
+ - 895fa0ff: chore: using "workspace:\*" in devDependencies
32
+ - 3d1fac2a: chore: app-tools no longer depend on webpack
33
+ - 247e2005: support devServer.devMiddleware, same as webpack-dev-server
34
+ - Updated dependencies [2d155c4c]
35
+ - Updated dependencies [a0475f1a]
36
+ - Updated dependencies [a0499e4f]
37
+ - Updated dependencies [123e432d]
38
+ - Updated dependencies [6c1438d2]
39
+ - Updated dependencies [e5a9b26d]
40
+ - Updated dependencies [0b26b93b]
41
+ - Updated dependencies [123e432d]
42
+ - Updated dependencies [f9f66ef9]
43
+ - Updated dependencies [71526621]
44
+ - Updated dependencies [77519490]
45
+ - Updated dependencies [592edabc]
46
+ - Updated dependencies [3578716a]
47
+ - Updated dependencies [895fa0ff]
48
+ - Updated dependencies [3d1fac2a]
49
+ - Updated dependencies [3578913e]
50
+ - Updated dependencies [247e2005]
51
+ - Updated dependencies [1c3beab3]
52
+ - @modern-js/utils@1.6.0
53
+ - @modern-js/webpack@1.5.7
54
+ - @modern-js/server@1.4.11
55
+ - @modern-js/prod-server@1.1.2
56
+ - @modern-js/node-bundle-require@1.3.2
57
+ - @modern-js/core@1.9.0
58
+ - @modern-js/plugin-analyze@1.4.1
59
+ - @modern-js/new-action@1.3.7
60
+ - @modern-js/types@1.5.1
61
+ - @modern-js/plugin-fast-refresh@1.2.4
62
+
63
+ ## 1.6.0
64
+
65
+ ### Minor Changes
66
+
67
+ - 3bf4f8b0: feat: support start api server only
68
+
69
+ ### Patch Changes
70
+
71
+ - 04ae5262: chore: bump @modern-js/utils to v1.4.1 in dependencies
72
+ - 60f7d8bf: feat: add tests dir to npmignore
73
+ - 5dbbeb57: fix: export extended Command type
74
+ - 305e0bb4: fix: commander.commandsMap typing not work
75
+ - Updated dependencies [a4330c73]
76
+ - Updated dependencies [b8599d09]
77
+ - Updated dependencies [6cffe99d]
78
+ - Updated dependencies [04ae5262]
79
+ - Updated dependencies [60f7d8bf]
80
+ - Updated dependencies [e4cec1ce]
81
+ - Updated dependencies [3b7aa8bb]
82
+ - Updated dependencies [5dbbeb57]
83
+ - Updated dependencies [ebfcbb35]
84
+ - Updated dependencies [3bf4f8b0]
85
+ - Updated dependencies [305e0bb4]
86
+ - Updated dependencies [ebfcbb35]
87
+ - Updated dependencies [28ac120a]
88
+ - @modern-js/core@1.8.0
89
+ - @modern-js/node-bundle-require@1.3.1
90
+ - @modern-js/utils@1.5.0
91
+ - @modern-js/i18n-cli-language-detector@1.2.2
92
+ - @modern-js/plugin-fast-refresh@1.2.4
93
+ - @modern-js/plugin-i18n@1.2.4
94
+ - @modern-js/webpack@1.5.5
95
+ - @modern-js/new-action@1.3.6
96
+ - @modern-js/prod-server@1.1.1
97
+ - @modern-js/server@1.4.10
98
+ - @modern-js/plugin@1.3.3
99
+ - @modern-js/types@1.5.0
100
+ - @modern-js/plugin-analyze@1.4.0
101
+
3
102
  ## 1.5.0
4
103
 
5
104
  ### Minor Changes
@@ -4,8 +4,7 @@ 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 } from 'webpack';
8
- import { WebpackConfigTarget, getWebpackConfig } from '@modern-js/webpack';
7
+ import { webpack, getWebpackConfig, WebpackConfigTarget } from '@modern-js/webpack';
9
8
  import { manager, ResolvedConfigContext } from '@modern-js/core';
10
9
  import { formatWebpackMessages, measureFileSizesBeforeBuild, printFileSizesAfterBuild, printBuildError, logger, isUseSSRBundle, emptyDir } from '@modern-js/utils';
11
10
  import { generateRoutes } from "../utils/routes";
@@ -14,21 +13,28 @@ import { buildServerConfig, emitResolvedConfig } from "../utils/config";
14
13
  const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
15
14
  const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
16
15
  export const build = async (api, options) => {
17
- const resolvedConfig = api.useResolvedConfigContext();
16
+ let resolvedConfig = api.useResolvedConfigContext();
18
17
  const appContext = api.useAppContext();
19
18
  const hookRunners = api.useHookRunners();
20
19
  const {
21
- existSrc
20
+ apiOnly
22
21
  } = appContext;
23
22
 
24
- if (!existSrc) {
23
+ if (apiOnly) {
25
24
  const {
26
- distDirectory
25
+ appDirectory,
26
+ distDirectory,
27
+ serverConfigFile
27
28
  } = appContext;
28
29
  await emptyDir(distDirectory);
29
30
  await hookRunners.beforeBuild({
30
31
  webpackConfigs: []
31
32
  });
33
+ await buildServerConfig({
34
+ appDirectory,
35
+ distDirectory,
36
+ configFile: serverConfigFile
37
+ });
32
38
  await generateRoutes(appContext);
33
39
  await hookRunners.afterBuild();
34
40
  return;
@@ -86,9 +92,10 @@ export const build = async (api, options) => {
86
92
  };
87
93
 
88
94
  manager.run(() => {
89
- ResolvedConfigContext.set(_objectSpread(_objectSpread({}, resolvedConfig), {}, {
95
+ resolvedConfig = _objectSpread(_objectSpread({}, resolvedConfig), {}, {
90
96
  cliOptions: options
91
- }));
97
+ });
98
+ ResolvedConfigContext.set(resolvedConfig);
92
99
  });
93
100
  const {
94
101
  distDirectory,
@@ -105,20 +112,20 @@ export const build = async (api, options) => {
105
112
  const buildConfigs = [];
106
113
  buildConfigs.push({
107
114
  type: 'legacy',
108
- config: getWebpackConfig(WebpackConfigTarget.CLIENT)
115
+ config: getWebpackConfig(WebpackConfigTarget.CLIENT, appContext, resolvedConfig)
109
116
  });
110
117
 
111
118
  if (resolvedConfig.output.enableModernMode) {
112
119
  buildConfigs.push({
113
120
  type: 'modern',
114
- config: getWebpackConfig(WebpackConfigTarget.MODERN)
121
+ config: getWebpackConfig(WebpackConfigTarget.MODERN, appContext, resolvedConfig)
115
122
  });
116
123
  }
117
124
 
118
125
  if (isUseSSRBundle(resolvedConfig)) {
119
126
  buildConfigs.push({
120
127
  type: 'ssr',
121
- config: getWebpackConfig(WebpackConfigTarget.NODE)
128
+ config: getWebpackConfig(WebpackConfigTarget.NODE, appContext, resolvedConfig)
122
129
  });
123
130
  }
124
131
 
@@ -19,7 +19,7 @@ export const dev = async (api, options) => {
19
19
  appDirectory,
20
20
  distDirectory,
21
21
  port,
22
- existSrc,
22
+ apiOnly,
23
23
  entrypoints,
24
24
  serverConfigFile
25
25
  } = appContext;
@@ -42,12 +42,12 @@ export const dev = async (api, options) => {
42
42
  await hookRunners.beforeDev();
43
43
  let compiler = null;
44
44
 
45
- if (existSrc) {
45
+ if (!apiOnly) {
46
46
  const {
47
47
  getWebpackConfig,
48
48
  WebpackConfigTarget
49
49
  } = await import('@modern-js/webpack');
50
- const webpackConfigs = [isSSR(userConfig) && getWebpackConfig(WebpackConfigTarget.NODE), getWebpackConfig(WebpackConfigTarget.CLIENT)].filter(Boolean);
50
+ const webpackConfigs = [isSSR(userConfig) && getWebpackConfig(WebpackConfigTarget.NODE, appContext, userConfig), getWebpackConfig(WebpackConfigTarget.CLIENT, appContext, userConfig)].filter(Boolean);
51
51
  compiler = await createCompiler({
52
52
  api,
53
53
  webpackConfigs,
@@ -60,14 +60,13 @@ export const dev = async (api, options) => {
60
60
  const app = await createServer({
61
61
  dev: _objectSpread(_objectSpread({}, {
62
62
  client: {
63
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
64
63
  port: port.toString(),
65
64
  overlay: false,
66
65
  logging: 'none',
67
66
  path: HMR_SOCK_PATH,
68
67
  host: 'localhost'
69
68
  },
70
- dev: {
69
+ devMiddleware: {
71
70
  writeToDisk: file => !file.includes('.hot-update.')
72
71
  },
73
72
  hot: true,
@@ -86,11 +85,11 @@ export const dev = async (api, options) => {
86
85
  throw err;
87
86
  }
88
87
 
89
- if (existSrc) {
90
- clearConsole();
91
- logger.log(chalk.cyan(`Starting the development server...`));
92
- } else {
93
- await printInstructions(hookRunners, appContext, userConfig);
88
+ if (apiOnly) {
89
+ return printInstructions(hookRunners, appContext, userConfig);
94
90
  }
91
+
92
+ clearConsole();
93
+ return logger.log(chalk.cyan(`Starting the development server...`));
95
94
  });
96
95
  };
@@ -1,4 +1,4 @@
1
- import { logger, chalk } from '@modern-js/utils';
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
4
  export const start = async api => {
@@ -11,11 +11,13 @@ export const start = async api => {
11
11
  serverConfigFile
12
12
  } = appContext;
13
13
  logger.log(chalk.cyan(`Starting the modern server...`));
14
+ const apiOnly = await isApiOnly(appContext.appDirectory);
14
15
  const app = await server({
15
16
  pwd: appDirectory,
16
17
  config: userConfig,
17
18
  plugins: appContext.plugins.filter(p => p.server).map(p => p.server),
18
- serverConfigFile
19
+ serverConfigFile,
20
+ apiOnly
19
21
  });
20
22
  app.listen(port, async err => {
21
23
  if (err) {
@@ -30,7 +30,7 @@ export default (() => ({
30
30
  commands({
31
31
  program
32
32
  }) {
33
- program.command('dev').usage('[options]').description(i18n.t(localeKeys.command.dev.describe)).option('-c --config <config>', i18n.t(localeKeys.command.dev.config)).option('-e --entry [entry...]', i18n.t(localeKeys.command.dev.entry)).action(async options => {
33
+ program.command('dev').usage('[options]').description(i18n.t(localeKeys.command.dev.describe)).option('-c --config <config>', i18n.t(localeKeys.command.dev.config)).option('-e --entry [entry...]', i18n.t(localeKeys.command.dev.entry)).option('--api-only', i18n.t(localeKeys.command.dev.apiOnly)).action(async options => {
34
34
  await dev(api, options);
35
35
  });
36
36
  program.command('build').usage('[options]').description(i18n.t(localeKeys.command.build.describe)).option('--analyze', i18n.t(localeKeys.command.build.analyze)).action(async options => {
@@ -42,7 +42,7 @@ export default (() => ({
42
42
 
43
43
  process.exit(0);
44
44
  });
45
- program.command('start').usage('[options]').description(i18n.t(localeKeys.command.start.describe)).action(async () => {
45
+ program.command('start').usage('[options]').description(i18n.t(localeKeys.command.start.describe)).option('--api-only', i18n.t(localeKeys.command.dev.apiOnly)).action(async () => {
46
46
  await start(api);
47
47
  });
48
48
  program.command('deploy').usage('[options]').description(i18n.t(localeKeys.command.deploy.describe)).action(async options => {
@@ -3,7 +3,8 @@ export const EN_LOCALE = {
3
3
  dev: {
4
4
  describe: 'start dev server',
5
5
  config: 'specify config file',
6
- entry: 'compiler by entry'
6
+ entry: 'compiler by entry',
7
+ apiOnly: 'start api server only'
7
8
  },
8
9
  build: {
9
10
  describe: 'build application',
@@ -3,7 +3,8 @@ export const ZH_LOCALE = {
3
3
  dev: {
4
4
  describe: '本地开发命令',
5
5
  config: '制定配置文件路径',
6
- entry: '按入口编译'
6
+ entry: '按入口编译',
7
+ apiOnly: '仅启动 API 接口服务'
7
8
  },
8
9
  build: {
9
10
  describe: '构建应用命令',
@@ -19,10 +19,11 @@ export const buildServerConfig = async ({
19
19
  const getOutputFile = filepath => path.resolve(distDirectory, `${filepath.replace(new RegExp(CONFIG_FILE_EXTENSIONS.join('|')), '')}.js`);
20
20
 
21
21
  if (configFilePath) {
22
- const configHelperFilePath = path.join(distDirectory, './config-helper.js');
22
+ const configHelperFilePath = path.normalize(path.join(distDirectory, './config-helper.js'));
23
23
  const helperCode = `
24
24
  export const defineConfig = (config) => config;
25
25
  `;
26
+ await fs.ensureDir(distDirectory);
26
27
  await fs.writeFile(configHelperFilePath, helperCode);
27
28
  await bundle(configFilePath, _objectSpread(_objectSpread({}, options), {}, {
28
29
  getOutputFile,
@@ -1,4 +1,4 @@
1
- import webpack from 'webpack';
1
+ import { webpack } from '@modern-js/webpack';
2
2
  import { chalk, logger, formatWebpackMessages, clearConsole } from '@modern-js/utils';
3
3
  import { printInstructions } from "./printInstructions";
4
4
 
@@ -1,4 +1,4 @@
1
- import inquirer from 'inquirer';
1
+ import { inquirer } from '@modern-js/utils';
2
2
  export const getSpecifiedEntries = async (entry, entrypoints) => {
3
3
  const entryNames = entrypoints.map(e => e.entryName);
4
4
 
@@ -2,10 +2,10 @@ import { prettyInstructions, logger, isDev, chalk } from '@modern-js/utils';
2
2
  export const printInstructions = async (hookRunners, appContext, config) => {
3
3
  let message = prettyInstructions(appContext, config);
4
4
  const {
5
- existSrc
5
+ apiOnly
6
6
  } = appContext;
7
7
 
8
- if (isDev() && existSrc) {
8
+ if (isDev() && !apiOnly) {
9
9
  message += `\n${chalk.cyanBright([`Note that the development build is not optimized.`, `To create a production build, execute build command.`].join('\n'))}`;
10
10
  } // call beforePrintInstructions hook.
11
11
 
@@ -5,9 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.build = void 0;
7
7
 
8
- var _webpack = require("webpack");
9
-
10
- var _webpack2 = require("@modern-js/webpack");
8
+ var _webpack = require("@modern-js/webpack");
11
9
 
12
10
  var _core = require("@modern-js/core");
13
11
 
@@ -28,21 +26,28 @@ const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
28
26
  const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
29
27
 
30
28
  const build = async (api, options) => {
31
- const resolvedConfig = api.useResolvedConfigContext();
29
+ let resolvedConfig = api.useResolvedConfigContext();
32
30
  const appContext = api.useAppContext();
33
31
  const hookRunners = api.useHookRunners();
34
32
  const {
35
- existSrc
33
+ apiOnly
36
34
  } = appContext;
37
35
 
38
- if (!existSrc) {
36
+ if (apiOnly) {
39
37
  const {
40
- distDirectory
38
+ appDirectory,
39
+ distDirectory,
40
+ serverConfigFile
41
41
  } = appContext;
42
42
  await (0, _utils.emptyDir)(distDirectory);
43
43
  await hookRunners.beforeBuild({
44
44
  webpackConfigs: []
45
45
  });
46
+ await (0, _config.buildServerConfig)({
47
+ appDirectory,
48
+ distDirectory,
49
+ configFile: serverConfigFile
50
+ });
46
51
  await (0, _routes.generateRoutes)(appContext);
47
52
  await hookRunners.afterBuild();
48
53
  return;
@@ -103,9 +108,11 @@ const build = async (api, options) => {
103
108
  };
104
109
 
105
110
  _core.manager.run(() => {
106
- _core.ResolvedConfigContext.set(_objectSpread(_objectSpread({}, resolvedConfig), {}, {
111
+ resolvedConfig = _objectSpread(_objectSpread({}, resolvedConfig), {}, {
107
112
  cliOptions: options
108
- }));
113
+ });
114
+
115
+ _core.ResolvedConfigContext.set(resolvedConfig);
109
116
  });
110
117
 
111
118
  const {
@@ -123,20 +130,20 @@ const build = async (api, options) => {
123
130
  const buildConfigs = [];
124
131
  buildConfigs.push({
125
132
  type: 'legacy',
126
- config: (0, _webpack2.getWebpackConfig)(_webpack2.WebpackConfigTarget.CLIENT)
133
+ config: (0, _webpack.getWebpackConfig)(_webpack.WebpackConfigTarget.CLIENT, appContext, resolvedConfig)
127
134
  });
128
135
 
129
136
  if (resolvedConfig.output.enableModernMode) {
130
137
  buildConfigs.push({
131
138
  type: 'modern',
132
- config: (0, _webpack2.getWebpackConfig)(_webpack2.WebpackConfigTarget.MODERN)
139
+ config: (0, _webpack.getWebpackConfig)(_webpack.WebpackConfigTarget.MODERN, appContext, resolvedConfig)
133
140
  });
134
141
  }
135
142
 
136
143
  if ((0, _utils.isUseSSRBundle)(resolvedConfig)) {
137
144
  buildConfigs.push({
138
145
  type: 'ssr',
139
- config: (0, _webpack2.getWebpackConfig)(_webpack2.WebpackConfigTarget.NODE)
146
+ config: (0, _webpack.getWebpackConfig)(_webpack.WebpackConfigTarget.NODE, appContext, resolvedConfig)
140
147
  });
141
148
  }
142
149
 
@@ -37,7 +37,7 @@ const dev = async (api, options) => {
37
37
  appDirectory,
38
38
  distDirectory,
39
39
  port,
40
- existSrc,
40
+ apiOnly,
41
41
  entrypoints,
42
42
  serverConfigFile
43
43
  } = appContext;
@@ -62,12 +62,12 @@ const dev = async (api, options) => {
62
62
  await hookRunners.beforeDev();
63
63
  let compiler = null;
64
64
 
65
- if (existSrc) {
65
+ if (!apiOnly) {
66
66
  const {
67
67
  getWebpackConfig,
68
68
  WebpackConfigTarget
69
69
  } = await Promise.resolve().then(() => _interopRequireWildcard(require('@modern-js/webpack')));
70
- const webpackConfigs = [(0, _utils.isSSR)(userConfig) && getWebpackConfig(WebpackConfigTarget.NODE), getWebpackConfig(WebpackConfigTarget.CLIENT)].filter(Boolean);
70
+ const webpackConfigs = [(0, _utils.isSSR)(userConfig) && getWebpackConfig(WebpackConfigTarget.NODE, appContext, userConfig), getWebpackConfig(WebpackConfigTarget.CLIENT, appContext, userConfig)].filter(Boolean);
71
71
  compiler = await (0, _createCompiler.createCompiler)({
72
72
  api,
73
73
  webpackConfigs,
@@ -80,14 +80,13 @@ const dev = async (api, options) => {
80
80
  const app = await (0, _createServer.createServer)({
81
81
  dev: _objectSpread(_objectSpread({}, {
82
82
  client: {
83
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
84
83
  port: port.toString(),
85
84
  overlay: false,
86
85
  logging: 'none',
87
86
  path: _utils.HMR_SOCK_PATH,
88
87
  host: 'localhost'
89
88
  },
90
- dev: {
89
+ devMiddleware: {
91
90
  writeToDisk: file => !file.includes('.hot-update.')
92
91
  },
93
92
  hot: true,
@@ -106,13 +105,12 @@ const dev = async (api, options) => {
106
105
  throw err;
107
106
  }
108
107
 
109
- if (existSrc) {
110
- (0, _utils.clearConsole)();
111
-
112
- _utils.logger.log(_utils.chalk.cyan(`Starting the development server...`));
113
- } else {
114
- await (0, _printInstructions.printInstructions)(hookRunners, appContext, userConfig);
108
+ if (apiOnly) {
109
+ return (0, _printInstructions.printInstructions)(hookRunners, appContext, userConfig);
115
110
  }
111
+
112
+ (0, _utils.clearConsole)();
113
+ return _utils.logger.log(_utils.chalk.cyan(`Starting the development server...`));
116
114
  });
117
115
  };
118
116
 
@@ -25,11 +25,13 @@ const start = async api => {
25
25
 
26
26
  _utils.logger.log(_utils.chalk.cyan(`Starting the modern server...`));
27
27
 
28
+ const apiOnly = await (0, _utils.isApiOnly)(appContext.appDirectory);
28
29
  const app = await (0, _prodServer.default)({
29
30
  pwd: appDirectory,
30
31
  config: userConfig,
31
32
  plugins: appContext.plugins.filter(p => p.server).map(p => p.server),
32
- serverConfigFile
33
+ serverConfigFile,
34
+ apiOnly
33
35
  });
34
36
  app.listen(port, async err => {
35
37
  if (err) {
@@ -61,7 +61,7 @@ var _default = () => ({
61
61
  commands({
62
62
  program
63
63
  }) {
64
- program.command('dev').usage('[options]').description(_locale.i18n.t(_locale.localeKeys.command.dev.describe)).option('-c --config <config>', _locale.i18n.t(_locale.localeKeys.command.dev.config)).option('-e --entry [entry...]', _locale.i18n.t(_locale.localeKeys.command.dev.entry)).action(async options => {
64
+ program.command('dev').usage('[options]').description(_locale.i18n.t(_locale.localeKeys.command.dev.describe)).option('-c --config <config>', _locale.i18n.t(_locale.localeKeys.command.dev.config)).option('-e --entry [entry...]', _locale.i18n.t(_locale.localeKeys.command.dev.entry)).option('--api-only', _locale.i18n.t(_locale.localeKeys.command.dev.apiOnly)).action(async options => {
65
65
  await (0, _dev.dev)(api, options);
66
66
  });
67
67
  program.command('build').usage('[options]').description(_locale.i18n.t(_locale.localeKeys.command.build.describe)).option('--analyze', _locale.i18n.t(_locale.localeKeys.command.build.analyze)).action(async options => {
@@ -73,7 +73,7 @@ var _default = () => ({
73
73
 
74
74
  process.exit(0);
75
75
  });
76
- program.command('start').usage('[options]').description(_locale.i18n.t(_locale.localeKeys.command.start.describe)).action(async () => {
76
+ program.command('start').usage('[options]').description(_locale.i18n.t(_locale.localeKeys.command.start.describe)).option('--api-only', _locale.i18n.t(_locale.localeKeys.command.dev.apiOnly)).action(async () => {
77
77
  await (0, _start.start)(api);
78
78
  });
79
79
  program.command('deploy').usage('[options]').description(_locale.i18n.t(_locale.localeKeys.command.deploy.describe)).action(async options => {
@@ -9,7 +9,8 @@ const EN_LOCALE = {
9
9
  dev: {
10
10
  describe: 'start dev server',
11
11
  config: 'specify config file',
12
- entry: 'compiler by entry'
12
+ entry: 'compiler by entry',
13
+ apiOnly: 'start api server only'
13
14
  },
14
15
  build: {
15
16
  describe: 'build application',
@@ -9,7 +9,8 @@ const ZH_LOCALE = {
9
9
  dev: {
10
10
  describe: '本地开发命令',
11
11
  config: '制定配置文件路径',
12
- entry: '按入口编译'
12
+ entry: '按入口编译',
13
+ apiOnly: '仅启动 API 接口服务'
13
14
  },
14
15
  build: {
15
16
  describe: '构建应用命令',
@@ -36,10 +36,11 @@ const buildServerConfig = async ({
36
36
  const getOutputFile = filepath => path.resolve(distDirectory, `${filepath.replace(new RegExp(_utils.CONFIG_FILE_EXTENSIONS.join('|')), '')}.js`);
37
37
 
38
38
  if (configFilePath) {
39
- const configHelperFilePath = path.join(distDirectory, './config-helper.js');
39
+ const configHelperFilePath = path.normalize(path.join(distDirectory, './config-helper.js'));
40
40
  const helperCode = `
41
41
  export const defineConfig = (config) => config;
42
42
  `;
43
+ await _utils.fs.ensureDir(distDirectory);
43
44
  await _utils.fs.writeFile(configHelperFilePath, helperCode);
44
45
  await (0, _nodeBundleRequire.bundle)(configFilePath, _objectSpread(_objectSpread({}, options), {}, {
45
46
  getOutputFile,
@@ -5,14 +5,12 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createCompiler = void 0;
7
7
 
8
- var _webpack = _interopRequireDefault(require("webpack"));
8
+ var _webpack = require("@modern-js/webpack");
9
9
 
10
10
  var _utils = require("@modern-js/utils");
11
11
 
12
12
  var _printInstructions = require("./printInstructions");
13
13
 
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
-
16
14
  const prettyTime = stats => {
17
15
  var _stats$children;
18
16
 
@@ -31,7 +29,7 @@ const createCompiler = async ({
31
29
  await hookRunners.beforeCreateCompiler({
32
30
  webpackConfigs
33
31
  });
34
- const compiler = (0, _webpack.default)(webpackConfigs);
32
+ const compiler = (0, _webpack.webpack)(webpackConfigs);
35
33
  await hookRunners.afterCreateCompiler({
36
34
  compiler
37
35
  });
@@ -5,9 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getSpecifiedEntries = void 0;
7
7
 
8
- var _inquirer = _interopRequireDefault(require("inquirer"));
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
+ var _utils = require("@modern-js/utils");
11
9
 
12
10
  const getSpecifiedEntries = async (entry, entrypoints) => {
13
11
  const entryNames = entrypoints.map(e => e.entryName);
@@ -19,7 +17,7 @@ const getSpecifiedEntries = async (entry, entrypoints) => {
19
17
  if (typeof entry === 'boolean') {
20
18
  const {
21
19
  selected
22
- } = await _inquirer.default.prompt([{
20
+ } = await _utils.inquirer.prompt([{
23
21
  type: 'checkbox',
24
22
  name: 'selected',
25
23
  choices: entryNames,
@@ -10,10 +10,10 @@ var _utils = require("@modern-js/utils");
10
10
  const printInstructions = async (hookRunners, appContext, config) => {
11
11
  let message = (0, _utils.prettyInstructions)(appContext, config);
12
12
  const {
13
- existSrc
13
+ apiOnly
14
14
  } = appContext;
15
15
 
16
- if ((0, _utils.isDev)() && existSrc) {
16
+ if ((0, _utils.isDev)() && !apiOnly) {
17
17
  message += `\n${_utils.chalk.cyanBright([`Note that the development build is not optimized.`, `To create a production build, execute build command.`].join('\n'))}`;
18
18
  } // call beforePrintInstructions hook.
19
19
 
@@ -1,4 +1,4 @@
1
- import type { Compiler, Configuration, MultiCompiler } from '@modern-js/types';
1
+ import type { Compiler, Configuration, MultiCompiler } from '@modern-js/webpack';
2
2
  export declare const beforeDev: import("@modern-js/plugin").AsyncWorkflow<void, unknown>;
3
3
  export declare const afterDev: import("@modern-js/plugin").AsyncWorkflow<void, unknown>;
4
4
  export declare const beforeCreateCompiler: import("@modern-js/plugin").AsyncWorkflow<{
@@ -4,6 +4,7 @@ export declare const EN_LOCALE: {
4
4
  describe: string;
5
5
  config: string;
6
6
  entry: string;
7
+ apiOnly: string;
7
8
  };
8
9
  build: {
9
10
  describe: string;
@@ -6,6 +6,7 @@ declare const localeKeys: {
6
6
  describe: string;
7
7
  config: string;
8
8
  entry: string;
9
+ apiOnly: string;
9
10
  };
10
11
  build: {
11
12
  describe: string;
@@ -31,6 +32,7 @@ declare const localeKeys: {
31
32
  describe: string;
32
33
  config: string;
33
34
  entry: string;
35
+ apiOnly: string;
34
36
  };
35
37
  build: {
36
38
  describe: string;
@@ -4,6 +4,7 @@ export declare const ZH_LOCALE: {
4
4
  describe: string;
5
5
  config: string;
6
6
  entry: string;
7
+ apiOnly: string;
7
8
  };
8
9
  build: {
9
10
  describe: string;
@@ -1,4 +1,4 @@
1
- import webpack, { Configuration } from 'webpack';
1
+ import { webpack, Configuration } from '@modern-js/webpack';
2
2
  import type { IAppContext, NormalizedConfig, PluginAPI } from '@modern-js/core';
3
3
  export declare const createCompiler: ({
4
4
  api,
@@ -1,6 +1,10 @@
1
1
  export declare type DevOptions = {
2
2
  entry?: string[] | boolean;
3
+ apiOnly?: boolean;
3
4
  };
4
5
  export declare type BuildOptions = {
5
6
  analyze?: boolean;
7
+ };
8
+ export declare type StartOptions = {
9
+ apiOnly?: boolean;
6
10
  };
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.5.0",
14
+ "version": "1.6.2",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -57,27 +57,24 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@babel/runtime": "^7",
60
- "@modern-js/core": "^1.7.0",
61
- "@modern-js/i18n-cli-language-detector": "^1.2.1",
62
- "@modern-js/new-action": "^1.3.5",
63
- "@modern-js/node-bundle-require": "^1.3.0",
64
- "@modern-js/plugin": "^1.3.2",
65
- "@modern-js/plugin-analyze": "^1.3.6",
66
- "@modern-js/plugin-fast-refresh": "^1.2.3",
67
- "@modern-js/plugin-i18n": "^1.2.3",
68
- "@modern-js/prod-server": "^1.1.0",
69
- "@modern-js/server": "^1.4.9",
70
- "@modern-js/types": "^1.4.0",
71
- "@modern-js/utils": "^1.4.0",
72
- "@modern-js/webpack": "^1.5.4",
73
- "inquirer": "^8.2.0",
74
- "webpack": "^5.71.0"
60
+ "@modern-js/core": "^1.10.0",
61
+ "@modern-js/i18n-cli-language-detector": "^1.2.2",
62
+ "@modern-js/new-action": "^1.3.7",
63
+ "@modern-js/node-bundle-require": "^1.3.2",
64
+ "@modern-js/plugin": "^1.3.3",
65
+ "@modern-js/plugin-analyze": "^1.4.1",
66
+ "@modern-js/plugin-fast-refresh": "^1.2.4",
67
+ "@modern-js/plugin-i18n": "^1.2.4",
68
+ "@modern-js/prod-server": "^1.1.3",
69
+ "@modern-js/server": "^1.4.12",
70
+ "@modern-js/types": "^1.5.2",
71
+ "@modern-js/utils": "^1.7.0",
72
+ "@modern-js/webpack": "^1.6.0"
75
73
  },
76
74
  "devDependencies": {
77
- "@modern-js/server-core": "^1.3.0",
75
+ "@modern-js/server-core": "1.3.3",
78
76
  "@scripts/build": "0.0.0",
79
77
  "@scripts/jest-config": "0.0.0",
80
- "@types/inquirer": "^8.2.0",
81
78
  "@types/jest": "^26",
82
79
  "@types/node": "^14",
83
80
  "@types/react": "^17",
@@ -1,8 +0,0 @@
1
- module.exports = {
2
- root: true,
3
- extends: ['@modern-js'],
4
- parserOptions: {
5
- tsconfigRootDir: __dirname,
6
- project: ['./tsconfig.json'],
7
- },
8
- };
@@ -1,5 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`test app-tools utils safeReplacer should handle circular object 1`] = `"{\\"name\\":\\"a\\",\\"b\\":{\\"name\\":\\"b\\",\\"a\\":\\"[Circular root]\\"}}"`;
4
-
5
- exports[`test app-tools utils safeReplacer should handle circular object 2`] = `"{\\"name\\":\\"c\\",\\"d\\":{\\"name\\":\\"d\\",\\"e\\":{\\"name\\":\\"e\\",\\"c\\":\\"[Circular root]\\"}}}"`;
@@ -1,42 +0,0 @@
1
- import { manager } from '@modern-js/core';
2
- import { build } from '../../src/commands/build';
3
-
4
- const mockGenerateRoutes = jest.fn();
5
-
6
- jest.mock('../../src/utils/routes', () => ({
7
- __esModule: true,
8
- generateRoutes: () => mockGenerateRoutes(),
9
- }));
10
-
11
- describe('command build', () => {
12
- afterAll(() => {
13
- jest.resetAllMocks();
14
- });
15
-
16
- test('existSrc is false', async () => {
17
- const mockBeforeBuild = jest.fn();
18
- const mockAfterBuild = jest.fn();
19
- const mockAPI = {
20
- useAppContext: jest.fn((): any => ({
21
- existSrc: false,
22
- distDirectory: '',
23
- })),
24
- useResolvedConfigContext: jest.fn(),
25
- useHookRunners: (): any => ({
26
- afterBuild: mockAfterBuild,
27
- beforeBuild: mockBeforeBuild,
28
- }),
29
- };
30
-
31
- const cloned = manager.clone(mockAPI);
32
- cloned.usePlugin({
33
- async setup(api) {
34
- await build(api);
35
- expect(mockBeforeBuild).toBeCalled();
36
- expect(mockGenerateRoutes).toBeCalled();
37
- expect(mockAfterBuild).toBeCalled();
38
- },
39
- });
40
- await cloned.init();
41
- });
42
- });
@@ -1,7 +0,0 @@
1
- import { dev } from '../../src/commands/dev';
2
-
3
- describe('command', () => {
4
- test('dev', () => {
5
- expect(dev).toBeDefined();
6
- });
7
- });
@@ -1,7 +0,0 @@
1
- import plugin from '../src';
2
-
3
- describe('app-tools', () => {
4
- it('default', () => {
5
- expect(plugin).toBeDefined();
6
- });
7
- });
@@ -1,27 +0,0 @@
1
- import { fs } from '@modern-js/utils';
2
- import { generateRoutes } from '../src/utils/routes';
3
-
4
- jest.mock('@modern-js/utils', () => {
5
- const originalModule = jest.requireActual('@modern-js/utils');
6
- return {
7
- __esModule: true,
8
- ...originalModule,
9
- fs: {
10
- outputFile: jest.fn((filename: string, output: string) => ({
11
- filename,
12
- output,
13
- })),
14
- },
15
- };
16
- });
17
-
18
- describe('routes', () => {
19
- test('generateRoutes', async () => {
20
- const mockAppContext = {
21
- serverRoutes: [],
22
- distDirectory: './dist',
23
- };
24
- await generateRoutes(mockAppContext as any);
25
- expect(fs.outputFile).toHaveBeenCalledTimes(1);
26
- });
27
- });
@@ -1,13 +0,0 @@
1
- {
2
- "extends": "@modern-js/tsconfig/base",
3
- "compilerOptions": {
4
- "declaration": true,
5
- "jsx": "preserve",
6
- "baseUrl": "./",
7
- "outDir": "./out",
8
- "emitDeclarationOnly": true,
9
- "isolatedModules": true,
10
- "paths": {},
11
- "types": ["node", "jest"]
12
- }
13
- }
@@ -1,112 +0,0 @@
1
- import inquirer from 'inquirer';
2
- import { Server } from '@modern-js/server';
3
- import {
4
- closeServer,
5
- createServer,
6
- getServer,
7
- } from '../src/utils/createServer';
8
- import { getSpecifiedEntries } from '../src/utils/getSpecifiedEntries';
9
- import { safeReplacer } from '../src/utils/config';
10
-
11
- describe('test app-tools utils', () => {
12
- it('should return all entryNames correctly', async () => {
13
- const checked = await getSpecifiedEntries(false, [
14
- { entryName: 'a' },
15
- { entryName: 'b' },
16
- ] as any);
17
-
18
- expect(checked).toEqual(['a', 'b']);
19
- });
20
-
21
- it('should return spec entry', async () => {
22
- const checked = await getSpecifiedEntries(['a'], [
23
- { entryName: 'a' },
24
- { entryName: 'b' },
25
- ] as any);
26
-
27
- expect(checked).toEqual(['a']);
28
- });
29
-
30
- it('should return select entry', async () => {
31
- inquirer.prompt = jest.fn().mockResolvedValue({ selected: ['b'] }) as any;
32
- const checked = await getSpecifiedEntries(true, [
33
- { entryName: 'a' },
34
- { entryName: 'b' },
35
- ] as any);
36
-
37
- expect(checked).toEqual(['b']);
38
- });
39
-
40
- it('should get error if entry not allow', resolve => {
41
- getSpecifiedEntries(['c'], [
42
- { entryName: 'a' },
43
- { entryName: 'b' },
44
- ] as any).catch(e => {
45
- expect((e as Error).message).toMatch('can not found entry c');
46
- resolve();
47
- });
48
- });
49
-
50
- it('should create and close server correctly', async () => {
51
- const app = await createServer({
52
- dev: false,
53
- pwd: '.',
54
- config: {
55
- output: {
56
- path: 'dist',
57
- },
58
- },
59
- } as any);
60
-
61
- expect(app instanceof Server).toBe(true);
62
- expect(getServer()).toBe(app);
63
-
64
- await closeServer();
65
- expect(getServer()).toBeNull();
66
- });
67
-
68
- it('safeReplacer should handle circular object', () => {
69
- const a: {
70
- [key: string]: unknown;
71
- } = {
72
- name: 'a',
73
- };
74
-
75
- const b: {
76
- [key: string]: unknown;
77
- } = {
78
- name: 'b',
79
- };
80
-
81
- a.b = b;
82
- b.a = a;
83
-
84
- const res1 = JSON.stringify(a, safeReplacer());
85
- expect(res1).toMatchSnapshot();
86
-
87
- const c: {
88
- [key: string]: unknown;
89
- } = {
90
- name: 'c',
91
- };
92
-
93
- const d: {
94
- [key: string]: unknown;
95
- } = {
96
- name: 'd',
97
- };
98
-
99
- const e: {
100
- [key: string]: unknown;
101
- } = {
102
- name: 'e',
103
- };
104
-
105
- c.d = d;
106
- d.e = e;
107
- e.c = c;
108
-
109
- const res2 = JSON.stringify(c, safeReplacer());
110
- expect(res2).toMatchSnapshot();
111
- });
112
- });