@modern-js/app-tools 1.4.7-canary.0 → 1.6.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # @modern-js/app-tools
2
2
 
3
+ ## 1.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 3bf4f8b0: feat: support start api server only
8
+
9
+ ### Patch Changes
10
+
11
+ - 04ae5262: chore: bump @modern-js/utils to v1.4.1 in dependencies
12
+ - 60f7d8bf: feat: add tests dir to npmignore
13
+ - 5dbbeb57: fix: export extended Command type
14
+ - 305e0bb4: fix: commander.commandsMap typing not work
15
+ - Updated dependencies [a4330c73]
16
+ - Updated dependencies [b8599d09]
17
+ - Updated dependencies [6cffe99d]
18
+ - Updated dependencies [04ae5262]
19
+ - Updated dependencies [60f7d8bf]
20
+ - Updated dependencies [e4cec1ce]
21
+ - Updated dependencies [3b7aa8bb]
22
+ - Updated dependencies [5dbbeb57]
23
+ - Updated dependencies [ebfcbb35]
24
+ - Updated dependencies [3bf4f8b0]
25
+ - Updated dependencies [305e0bb4]
26
+ - Updated dependencies [ebfcbb35]
27
+ - Updated dependencies [28ac120a]
28
+ - @modern-js/core@1.8.0
29
+ - @modern-js/node-bundle-require@1.3.1
30
+ - @modern-js/utils@1.5.0
31
+ - @modern-js/i18n-cli-language-detector@1.2.2
32
+ - @modern-js/plugin-fast-refresh@1.2.4
33
+ - @modern-js/plugin-i18n@1.2.4
34
+ - @modern-js/webpack@1.5.5
35
+ - @modern-js/new-action@1.3.6
36
+ - @modern-js/prod-server@1.1.1
37
+ - @modern-js/server@1.4.10
38
+ - @modern-js/plugin@1.3.3
39
+ - @modern-js/types@1.5.0
40
+ - @modern-js/plugin-analyze@1.4.0
41
+
42
+ ## 1.5.0
43
+
44
+ ### Minor Changes
45
+
46
+ - d2d1d6b2: feat: support server config
47
+
48
+ ### Patch Changes
49
+
50
+ - 6aa80baa: fix: Generate config helper file only config file exist
51
+ - Updated dependencies [60855eb2]
52
+ - Updated dependencies [046e58aa]
53
+ - Updated dependencies [ec1b7367]
54
+ - Updated dependencies [77ff9754]
55
+ - Updated dependencies [d2d1d6b2]
56
+ - Updated dependencies [07a4887e]
57
+ - Updated dependencies [ea2ae711]
58
+ - Updated dependencies [17d0cc46]
59
+ - Updated dependencies [d2d1d6b2]
60
+ - @modern-js/core@1.7.0
61
+ - @modern-js/plugin-analyze@1.3.6
62
+ - @modern-js/webpack@1.5.4
63
+ - @modern-js/utils@1.4.0
64
+ - @modern-js/prod-server@1.1.0
65
+ - @modern-js/node-bundle-require@1.3.0
66
+ - @modern-js/types@1.4.0
67
+ - @modern-js/plugin-i18n@1.2.3
68
+ - @modern-js/new-action@1.3.5
69
+ - @modern-js/plugin-fast-refresh@1.2.3
70
+ - @modern-js/server@1.4.9
71
+
3
72
  ## 1.4.6
4
73
 
5
74
  ### Patch Changes
@@ -12,24 +12,30 @@ import { generateRoutes } from "../utils/routes";
12
12
  import { buildServerConfig, emitResolvedConfig } from "../utils/config";
13
13
  // These sizes are pretty large. We'll warn for bundles exceeding them.
14
14
  const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
15
- const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; // eslint-disable-next-line max-statements
16
-
15
+ const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
17
16
  export const build = async (api, options) => {
18
17
  const resolvedConfig = api.useResolvedConfigContext();
19
18
  const appContext = api.useAppContext();
20
19
  const hookRunners = api.useHookRunners();
21
20
  const {
22
- existSrc
21
+ apiOnly
23
22
  } = appContext;
24
23
 
25
- if (!existSrc) {
24
+ if (apiOnly) {
26
25
  const {
27
- distDirectory
26
+ appDirectory,
27
+ distDirectory,
28
+ serverConfigFile
28
29
  } = appContext;
29
30
  await emptyDir(distDirectory);
30
31
  await hookRunners.beforeBuild({
31
32
  webpackConfigs: []
32
33
  });
34
+ await buildServerConfig({
35
+ appDirectory,
36
+ distDirectory,
37
+ configFile: serverConfigFile
38
+ });
33
39
  await generateRoutes(appContext);
34
40
  await hookRunners.afterBuild();
35
41
  return;
@@ -98,7 +104,11 @@ export const build = async (api, options) => {
98
104
  } = appContext;
99
105
  const previousFileSizes = await measureFileSizesBeforeBuild(distDirectory);
100
106
  await emptyDir(distDirectory);
101
- await buildServerConfig(appDirectory, serverConfigFile);
107
+ await buildServerConfig({
108
+ appDirectory,
109
+ distDirectory,
110
+ configFile: serverConfigFile
111
+ });
102
112
  const buildConfigs = [];
103
113
  buildConfigs.push({
104
114
  type: 'legacy',
@@ -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;
@@ -29,15 +29,20 @@ export const dev = async (api, options) => {
29
29
  }));
30
30
  appContext.checkedEntries = checkedEntries;
31
31
  fs.emptyDirSync(distDirectory);
32
- await buildServerConfig(appDirectory, serverConfigFile, {
33
- esbuildOptions: {
34
- watch: true
32
+ await buildServerConfig({
33
+ appDirectory,
34
+ distDirectory,
35
+ configFile: serverConfigFile,
36
+ options: {
37
+ esbuildOptions: {
38
+ watch: true
39
+ }
35
40
  }
36
41
  });
37
42
  await hookRunners.beforeDev();
38
43
  let compiler = null;
39
44
 
40
- if (existSrc) {
45
+ if (!apiOnly) {
41
46
  const {
42
47
  getWebpackConfig,
43
48
  WebpackConfigTarget
@@ -81,11 +86,11 @@ export const dev = async (api, options) => {
81
86
  throw err;
82
87
  }
83
88
 
84
- if (existSrc) {
85
- clearConsole();
86
- logger.log(chalk.cyan(`Starting the development server...`));
87
- } else {
88
- await printInstructions(hookRunners, appContext, userConfig);
89
+ if (apiOnly) {
90
+ return printInstructions(hookRunners, appContext, userConfig);
89
91
  }
92
+
93
+ clearConsole();
94
+ return logger.log(chalk.cyan(`Starting the development server...`));
90
95
  });
91
96
  };
@@ -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: '构建应用命令',
@@ -6,16 +6,41 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
6
6
 
7
7
  import * as path from 'path';
8
8
  import { bundle } from '@modern-js/node-bundle-require';
9
- import { CONFIG_CACHE_DIR, CONFIG_FILE_EXTENSIONS, fs, getServerConfig, OUTPUT_CONFIG_FILE } from '@modern-js/utils';
9
+ import { CONFIG_FILE_EXTENSIONS, fs, getServerConfig, OUTPUT_CONFIG_FILE } from '@modern-js/utils';
10
10
  export const defineServerConfig = config => config;
11
- export const buildServerConfig = async (appDirectory, configFile, options) => {
11
+ export const buildServerConfig = async ({
12
+ appDirectory,
13
+ distDirectory,
14
+ configFile,
15
+ options
16
+ }) => {
12
17
  const configFilePath = await getServerConfig(appDirectory, configFile);
13
18
 
14
- const getOutputFile = filepath => path.resolve(CONFIG_CACHE_DIR, `${filepath.replace(new RegExp(CONFIG_FILE_EXTENSIONS.join('|')), '')}.js`);
19
+ const getOutputFile = filepath => path.resolve(distDirectory, `${filepath.replace(new RegExp(CONFIG_FILE_EXTENSIONS.join('|')), '')}.js`);
15
20
 
16
21
  if (configFilePath) {
22
+ const configHelperFilePath = path.normalize(path.join(distDirectory, './config-helper.js'));
23
+ const helperCode = `
24
+ export const defineConfig = (config) => config;
25
+ `;
26
+ await fs.ensureDir(distDirectory);
27
+ await fs.writeFile(configHelperFilePath, helperCode);
17
28
  await bundle(configFilePath, _objectSpread(_objectSpread({}, options), {}, {
18
- getOutputFile
29
+ getOutputFile,
30
+ esbuildPlugins: [{
31
+ name: 'native-build-config',
32
+
33
+ setup(ctx) {
34
+ ctx.onResolve({
35
+ filter: /app-tools\/server/
36
+ }, () => {
37
+ return {
38
+ path: configHelperFilePath
39
+ };
40
+ });
41
+ }
42
+
43
+ }]
19
44
  }));
20
45
  }
21
46
  };
@@ -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
 
@@ -25,24 +25,31 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
25
25
 
26
26
  // These sizes are pretty large. We'll warn for bundles exceeding them.
27
27
  const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
28
- const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; // eslint-disable-next-line max-statements
28
+ const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
29
29
 
30
30
  const build = async (api, options) => {
31
31
  const resolvedConfig = api.useResolvedConfigContext();
32
32
  const appContext = api.useAppContext();
33
33
  const hookRunners = api.useHookRunners();
34
34
  const {
35
- existSrc
35
+ apiOnly
36
36
  } = appContext;
37
37
 
38
- if (!existSrc) {
38
+ if (apiOnly) {
39
39
  const {
40
- distDirectory
40
+ appDirectory,
41
+ distDirectory,
42
+ serverConfigFile
41
43
  } = appContext;
42
44
  await (0, _utils.emptyDir)(distDirectory);
43
45
  await hookRunners.beforeBuild({
44
46
  webpackConfigs: []
45
47
  });
48
+ await (0, _config.buildServerConfig)({
49
+ appDirectory,
50
+ distDirectory,
51
+ configFile: serverConfigFile
52
+ });
46
53
  await (0, _routes.generateRoutes)(appContext);
47
54
  await hookRunners.afterBuild();
48
55
  return;
@@ -115,7 +122,11 @@ const build = async (api, options) => {
115
122
  } = appContext;
116
123
  const previousFileSizes = await (0, _utils.measureFileSizesBeforeBuild)(distDirectory);
117
124
  await (0, _utils.emptyDir)(distDirectory);
118
- await (0, _config.buildServerConfig)(appDirectory, serverConfigFile);
125
+ await (0, _config.buildServerConfig)({
126
+ appDirectory,
127
+ distDirectory,
128
+ configFile: serverConfigFile
129
+ });
119
130
  const buildConfigs = [];
120
131
  buildConfigs.push({
121
132
  type: 'legacy',
@@ -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;
@@ -49,15 +49,20 @@ const dev = async (api, options) => {
49
49
 
50
50
  _utils.fs.emptyDirSync(distDirectory);
51
51
 
52
- await (0, _config.buildServerConfig)(appDirectory, serverConfigFile, {
53
- esbuildOptions: {
54
- watch: true
52
+ await (0, _config.buildServerConfig)({
53
+ appDirectory,
54
+ distDirectory,
55
+ configFile: serverConfigFile,
56
+ options: {
57
+ esbuildOptions: {
58
+ watch: true
59
+ }
55
60
  }
56
61
  });
57
62
  await hookRunners.beforeDev();
58
63
  let compiler = null;
59
64
 
60
- if (existSrc) {
65
+ if (!apiOnly) {
61
66
  const {
62
67
  getWebpackConfig,
63
68
  WebpackConfigTarget
@@ -101,13 +106,12 @@ const dev = async (api, options) => {
101
106
  throw err;
102
107
  }
103
108
 
104
- if (existSrc) {
105
- (0, _utils.clearConsole)();
106
-
107
- _utils.logger.log(_utils.chalk.cyan(`Starting the development server...`));
108
- } else {
109
- await (0, _printInstructions.printInstructions)(hookRunners, appContext, userConfig);
109
+ if (apiOnly) {
110
+ return (0, _printInstructions.printInstructions)(hookRunners, appContext, userConfig);
110
111
  }
112
+
113
+ (0, _utils.clearConsole)();
114
+ return _utils.logger.log(_utils.chalk.cyan(`Starting the development server...`));
111
115
  });
112
116
  };
113
117
 
@@ -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: '构建应用命令',
@@ -25,14 +25,39 @@ const defineServerConfig = config => config;
25
25
 
26
26
  exports.defineServerConfig = defineServerConfig;
27
27
 
28
- const buildServerConfig = async (appDirectory, configFile, options) => {
28
+ const buildServerConfig = async ({
29
+ appDirectory,
30
+ distDirectory,
31
+ configFile,
32
+ options
33
+ }) => {
29
34
  const configFilePath = await (0, _utils.getServerConfig)(appDirectory, configFile);
30
35
 
31
- const getOutputFile = filepath => path.resolve(_utils.CONFIG_CACHE_DIR, `${filepath.replace(new RegExp(_utils.CONFIG_FILE_EXTENSIONS.join('|')), '')}.js`);
36
+ const getOutputFile = filepath => path.resolve(distDirectory, `${filepath.replace(new RegExp(_utils.CONFIG_FILE_EXTENSIONS.join('|')), '')}.js`);
32
37
 
33
38
  if (configFilePath) {
39
+ const configHelperFilePath = path.normalize(path.join(distDirectory, './config-helper.js'));
40
+ const helperCode = `
41
+ export const defineConfig = (config) => config;
42
+ `;
43
+ await _utils.fs.ensureDir(distDirectory);
44
+ await _utils.fs.writeFile(configHelperFilePath, helperCode);
34
45
  await (0, _nodeBundleRequire.bundle)(configFilePath, _objectSpread(_objectSpread({}, options), {}, {
35
- getOutputFile
46
+ getOutputFile,
47
+ esbuildPlugins: [{
48
+ name: 'native-build-config',
49
+
50
+ setup(ctx) {
51
+ ctx.onResolve({
52
+ filter: /app-tools\/server/
53
+ }, () => {
54
+ return {
55
+ path: configHelperFilePath
56
+ };
57
+ });
58
+ }
59
+
60
+ }]
36
61
  }));
37
62
  }
38
63
  };
@@ -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
 
@@ -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;
@@ -2,7 +2,17 @@ import { bundle } from '@modern-js/node-bundle-require';
2
2
  import type { NormalizedConfig } from '@modern-js/core';
3
3
  import type { ServerConfig } from '@modern-js/server-core';
4
4
  export declare const defineServerConfig: (config: ServerConfig) => ServerConfig;
5
- export declare const buildServerConfig: (appDirectory: string, configFile: string, options?: Parameters<typeof bundle>[1]) => Promise<void>;
5
+ export declare const buildServerConfig: ({
6
+ appDirectory,
7
+ distDirectory,
8
+ configFile,
9
+ options
10
+ }: {
11
+ appDirectory: string;
12
+ distDirectory: string;
13
+ configFile: string;
14
+ options?: Parameters<typeof bundle>[1];
15
+ }) => Promise<void>;
6
16
  /**
7
17
  *
8
18
  * 处理循环引用的 replacer
@@ -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.4.7-canary.0",
14
+ "version": "1.6.0",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -57,24 +57,24 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@babel/runtime": "^7",
60
- "@modern-js/core": "^1.6.1",
61
- "@modern-js/i18n-cli-language-detector": "^1.2.1",
62
- "@modern-js/new-action": "^1.3.3",
63
- "@modern-js/node-bundle-require": "^1.2.3",
64
- "@modern-js/plugin": "^1.3.2",
65
- "@modern-js/plugin-analyze": "^1.3.5",
66
- "@modern-js/plugin-fast-refresh": "^1.2.3",
67
- "@modern-js/plugin-i18n": "^1.2.1",
68
- "@modern-js/prod-server": "^1.0.6",
69
- "@modern-js/server": "^1.4.9",
70
- "@modern-js/types": "^1.3.6",
71
- "@modern-js/utils": "^1.3.7",
72
- "@modern-js/webpack": "^1.5.3",
60
+ "@modern-js/core": "^1.8.0",
61
+ "@modern-js/i18n-cli-language-detector": "^1.2.2",
62
+ "@modern-js/new-action": "^1.3.6",
63
+ "@modern-js/node-bundle-require": "^1.3.1",
64
+ "@modern-js/plugin": "^1.3.3",
65
+ "@modern-js/plugin-analyze": "^1.4.0",
66
+ "@modern-js/plugin-fast-refresh": "^1.2.4",
67
+ "@modern-js/plugin-i18n": "^1.2.4",
68
+ "@modern-js/prod-server": "^1.1.1",
69
+ "@modern-js/server": "^1.4.10",
70
+ "@modern-js/types": "^1.5.0",
71
+ "@modern-js/utils": "^1.5.0",
72
+ "@modern-js/webpack": "^1.5.6",
73
73
  "inquirer": "^8.2.0",
74
74
  "webpack": "^5.71.0"
75
75
  },
76
76
  "devDependencies": {
77
- "@modern-js/server-core": "^1.2.4",
77
+ "@modern-js/server-core": "^1.3.1",
78
78
  "@scripts/build": "0.0.0",
79
79
  "@scripts/jest-config": "0.0.0",
80
80
  "@types/inquirer": "^8.2.0",
@@ -88,8 +88,7 @@
88
88
  "sideEffects": false,
89
89
  "publishConfig": {
90
90
  "registry": "https://registry.npmjs.org/",
91
- "access": "public",
92
- "types": "./dist/types/index.d.ts"
91
+ "access": "public"
93
92
  },
94
93
  "scripts": {
95
94
  "new": "modern new",
@@ -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
- });