@modern-js/core 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @modern-js/core
2
2
 
3
+ ## 1.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 4584cc04: export DeployConfig interface
8
+ - 7c19fd94: use existing port number for AppContext when dev server is restarted
9
+ - Updated dependencies [823809c6]
10
+ - @modern-js/utils@1.2.1
11
+
3
12
  ## 1.3.0
4
13
 
5
14
  ### Minor Changes
@@ -45,7 +45,7 @@ const showAdditionalPropertiesError = error => {
45
45
  /* eslint-disable max-statements, max-params */
46
46
 
47
47
 
48
- export const resolveConfig = async (loaded, configs, schemas, isRestart, argv) => {
48
+ export const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort, argv) => {
49
49
  var _validate$errors;
50
50
 
51
51
  const {
@@ -95,8 +95,14 @@ export const resolveConfig = async (loaded, configs, schemas, isRestart, argv) =
95
95
  const resolved = mergeConfig([defaults, ...configs, userConfig]);
96
96
  resolved._raw = loaded.config;
97
97
 
98
- if (isDev() && argv[0] === 'dev' && !isRestart) {
99
- resolved.server.port = await getPort(resolved.server.port);
98
+ if (isDev() && argv[0] === 'dev') {
99
+ if (restartWithExistingPort > 0) {
100
+ // dev server is restarted, should use existing port number
101
+ resolved.server.port = restartWithExistingPort;
102
+ } else {
103
+ // get port for new dev server
104
+ resolved.server.port = await getPort(resolved.server.port);
105
+ }
100
106
  }
101
107
 
102
108
  debug('resolved %o', resolved);
@@ -9,12 +9,12 @@ import { compatRequire, pkgUp, ensureAbsolutePath, logger } from '@modern-js/uti
9
9
  import { createAsyncManager, createAsyncWorkflow, createParallelWorkflow, createAsyncWaterfall } from '@modern-js/plugin';
10
10
  import { enable } from '@modern-js/plugin/node';
11
11
  import { program } from "./utils/commander";
12
- import { resolveConfig, defineConfig, loadUserConfig } from "./config";
12
+ import { resolveConfig, loadUserConfig } from "./config";
13
13
  import { loadPlugins } from "./loadPlugins";
14
14
  import { AppContext, ConfigContext, initAppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext } from "./context";
15
15
  import { initWatcher } from "./initWatcher";
16
16
  import { loadEnv } from "./loadEnv";
17
- export { defaultsConfig, mergeConfig } from "./config";
17
+ export * from "./config";
18
18
  export * from '@modern-js/plugin';
19
19
  export * from '@modern-js/plugin/node';
20
20
  program.name('modern').usage('<command> [options]').version(process.env.MODERN_JS_VERSION || '0.1.0');
@@ -37,7 +37,7 @@ export const {
37
37
  useRunner: mountHook
38
38
  } = manager;
39
39
  export const usePlugins = plugins => plugins.forEach(plugin => manager.usePlugin(compatRequire(require.resolve(plugin))));
40
- export { defineConfig, AppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext, ConfigContext };
40
+ export { AppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext, ConfigContext };
41
41
 
42
42
  const initAppDir = async cwd => {
43
43
  if (!cwd) {
@@ -59,6 +59,7 @@ const initAppDir = async cwd => {
59
59
  const createCli = () => {
60
60
  let hooksRunner;
61
61
  let isRestart = false;
62
+ let restartWithExistingPort = 0;
62
63
 
63
64
  const init = async (argv = [], options) => {
64
65
  enable();
@@ -95,7 +96,7 @@ const createCli = () => {
95
96
  });
96
97
  const extraConfigs = await hooksRunner.config();
97
98
  const extraSchemas = await hooksRunner.validateSchema();
98
- const config = await resolveConfig(loaded, extraConfigs, extraSchemas, isRestart, argv);
99
+ const config = await resolveConfig(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv);
99
100
  const {
100
101
  resolved
101
102
  } = await hooksRunner.resolvedConfig({
@@ -132,7 +133,10 @@ const createCli = () => {
132
133
  }
133
134
 
134
135
  async function restart() {
136
+ var _AppContext$use$value, _AppContext$use$value2;
137
+
135
138
  isRestart = true;
139
+ restartWithExistingPort = isRestart ? (_AppContext$use$value = (_AppContext$use$value2 = AppContext.use().value) === null || _AppContext$use$value2 === void 0 ? void 0 : _AppContext$use$value2.port) !== null && _AppContext$use$value !== void 0 ? _AppContext$use$value : 0 : 0;
136
140
  logger.info('Restart...\n');
137
141
  let hasGetError = false;
138
142
 
@@ -156,4 +160,4 @@ const createCli = () => {
156
160
  };
157
161
 
158
162
  export const cli = createCli();
159
- export { loadUserConfig, initAppDir, initAppContext };
163
+ export { initAppDir, initAppContext };
@@ -83,7 +83,7 @@ const showAdditionalPropertiesError = error => {
83
83
  /* eslint-disable max-statements, max-params */
84
84
 
85
85
 
86
- const resolveConfig = async (loaded, configs, schemas, isRestart, argv) => {
86
+ const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort, argv) => {
87
87
  var _validate$errors;
88
88
 
89
89
  const {
@@ -136,8 +136,14 @@ const resolveConfig = async (loaded, configs, schemas, isRestart, argv) => {
136
136
  const resolved = (0, _mergeConfig.mergeConfig)([_defaults.defaults, ...configs, userConfig]);
137
137
  resolved._raw = loaded.config;
138
138
 
139
- if ((0, _utils.isDev)() && argv[0] === 'dev' && !isRestart) {
140
- resolved.server.port = await (0, _utils.getPort)(resolved.server.port);
139
+ if ((0, _utils.isDev)() && argv[0] === 'dev') {
140
+ if (restartWithExistingPort > 0) {
141
+ // dev server is restarted, should use existing port number
142
+ resolved.server.port = restartWithExistingPort;
143
+ } else {
144
+ // get port for new dev server
145
+ resolved.server.port = await (0, _utils.getPort)(resolved.server.port);
146
+ }
141
147
  }
142
148
 
143
149
  debug('resolved %o', resolved);
@@ -11,10 +11,6 @@ var _exportNames = {
11
11
  usePlugins: true,
12
12
  cli: true,
13
13
  initAppDir: true,
14
- defineConfig: true,
15
- loadUserConfig: true,
16
- defaultsConfig: true,
17
- mergeConfig: true,
18
14
  AppContext: true,
19
15
  ConfigContext: true,
20
16
  initAppContext: true,
@@ -42,39 +38,13 @@ Object.defineProperty(exports, "ResolvedConfigContext", {
42
38
  }
43
39
  });
44
40
  exports.createPlugin = exports.cli = void 0;
45
- Object.defineProperty(exports, "defaultsConfig", {
46
- enumerable: true,
47
- get: function () {
48
- return _config.defaultsConfig;
49
- }
50
- });
51
- Object.defineProperty(exports, "defineConfig", {
52
- enumerable: true,
53
- get: function () {
54
- return _config.defineConfig;
55
- }
56
- });
57
41
  Object.defineProperty(exports, "initAppContext", {
58
42
  enumerable: true,
59
43
  get: function () {
60
44
  return _context.initAppContext;
61
45
  }
62
46
  });
63
- exports.initAppDir = void 0;
64
- Object.defineProperty(exports, "loadUserConfig", {
65
- enumerable: true,
66
- get: function () {
67
- return _config.loadUserConfig;
68
- }
69
- });
70
- exports.manager = void 0;
71
- Object.defineProperty(exports, "mergeConfig", {
72
- enumerable: true,
73
- get: function () {
74
- return _config.mergeConfig;
75
- }
76
- });
77
- exports.registerHook = exports.mountHook = void 0;
47
+ exports.registerHook = exports.mountHook = exports.manager = exports.initAppDir = void 0;
78
48
  Object.defineProperty(exports, "useAppContext", {
79
49
  enumerable: true,
80
50
  get: function () {
@@ -131,6 +101,18 @@ var _commander = require("./utils/commander");
131
101
 
132
102
  var _config = require("./config");
133
103
 
104
+ Object.keys(_config).forEach(function (key) {
105
+ if (key === "default" || key === "__esModule") return;
106
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
107
+ if (key in exports && exports[key] === _config[key]) return;
108
+ Object.defineProperty(exports, key, {
109
+ enumerable: true,
110
+ get: function () {
111
+ return _config[key];
112
+ }
113
+ });
114
+ });
115
+
134
116
  var _loadPlugins = require("./loadPlugins");
135
117
 
136
118
  var _context = require("./context");
@@ -198,6 +180,7 @@ exports.initAppDir = initAppDir;
198
180
  const createCli = () => {
199
181
  let hooksRunner;
200
182
  let isRestart = false;
183
+ let restartWithExistingPort = 0;
201
184
 
202
185
  const init = async (argv = [], options) => {
203
186
  (0, _node.enable)();
@@ -235,7 +218,7 @@ const createCli = () => {
235
218
  });
236
219
  const extraConfigs = await hooksRunner.config();
237
220
  const extraSchemas = await hooksRunner.validateSchema();
238
- const config = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, isRestart, argv);
221
+ const config = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv);
239
222
  const {
240
223
  resolved
241
224
  } = await hooksRunner.resolvedConfig({
@@ -274,7 +257,10 @@ const createCli = () => {
274
257
  }
275
258
 
276
259
  async function restart() {
260
+ var _AppContext$use$value, _AppContext$use$value2;
261
+
277
262
  isRestart = true;
263
+ restartWithExistingPort = isRestart ? (_AppContext$use$value = (_AppContext$use$value2 = _context.AppContext.use().value) === null || _AppContext$use$value2 === void 0 ? void 0 : _AppContext$use$value2.port) !== null && _AppContext$use$value !== void 0 ? _AppContext$use$value : 0 : 0;
278
264
 
279
265
  _utils.logger.info('Restart...\n');
280
266
 
@@ -5,7 +5,7 @@ import { mergeConfig, NormalizedConfig } from './mergeConfig';
5
5
  import { PluginValidateSchema } from './schema';
6
6
  export { defaults as defaultsConfig };
7
7
  export { mergeConfig };
8
- export interface SourceConfig {
8
+ interface SourceConfig {
9
9
  entries?: Record<string, string | {
10
10
  entry: string;
11
11
  enableFileSystemRoutes?: boolean;
@@ -21,7 +21,7 @@ export interface SourceConfig {
21
21
  moduleScopes?: Array<string | RegExp> | ((scopes: Array<string | RegExp>) => Array<string | RegExp>);
22
22
  include?: Array<string | RegExp>;
23
23
  }
24
- export interface OutputConfig {
24
+ interface OutputConfig {
25
25
  assetPrefix?: string;
26
26
  htmlPath?: string;
27
27
  jsPath?: string;
@@ -60,7 +60,7 @@ export interface OutputConfig {
60
60
  disableNodePolyfill?: boolean;
61
61
  enableTsLoader?: boolean;
62
62
  }
63
- export interface ServerConfig {
63
+ interface ServerConfig {
64
64
  routes?: Record<string, string | {
65
65
  route: string | string[];
66
66
  disableSpa?: boolean;
@@ -76,17 +76,17 @@ export interface ServerConfig {
76
76
  metrics?: Record<string, any>;
77
77
  enableMicroFrontendDebug?: boolean;
78
78
  }
79
- export interface DevConfig {
79
+ interface DevConfig {
80
80
  assetPrefix?: string | boolean;
81
81
  https?: boolean;
82
82
  }
83
- export interface DeployConfig {
83
+ interface DeployConfig {
84
84
  microFrontend?: boolean & Record<string, unknown>;
85
85
  domain?: string | Array<string>;
86
86
  domainByEntries?: Record<string, string | Array<string>>;
87
87
  }
88
88
  declare type ConfigFunction = Record<string, unknown> | ((config: Record<string, unknown>) => Record<string, unknown> | void);
89
- export interface ToolsConfig {
89
+ interface ToolsConfig {
90
90
  webpack?: ConfigFunction;
91
91
  babel?: ConfigFunction;
92
92
  autoprefixer?: ConfigFunction;
@@ -98,11 +98,11 @@ export interface ToolsConfig {
98
98
  minifyCss?: ConfigFunction;
99
99
  esbuild?: Record<string, unknown>;
100
100
  }
101
- export declare type RuntimeConfig = Record<string, any>;
102
- export interface RuntimeByEntriesConfig {
101
+ declare type RuntimeConfig = Record<string, any>;
102
+ interface RuntimeByEntriesConfig {
103
103
  [name: string]: RuntimeConfig;
104
104
  }
105
- export interface UserConfig {
105
+ interface UserConfig {
106
106
  source?: SourceConfig;
107
107
  output?: OutputConfig;
108
108
  server?: ServerConfig;
@@ -113,8 +113,8 @@ export interface UserConfig {
113
113
  runtime?: RuntimeConfig;
114
114
  runtimeByEntries?: RuntimeByEntriesConfig;
115
115
  }
116
- export declare type ConfigParam = UserConfig | Promise<UserConfig> | ((env: any) => UserConfig | Promise<UserConfig>);
117
- export interface LoadedConfig {
116
+ declare type ConfigParam = UserConfig | Promise<UserConfig> | ((env: any) => UserConfig | Promise<UserConfig>);
117
+ interface LoadedConfig {
118
118
  config: UserConfig;
119
119
  filePath: string | false;
120
120
  dependencies: string[];
@@ -123,4 +123,5 @@ export interface LoadedConfig {
123
123
  }
124
124
  export declare const defineConfig: (config: ConfigParam) => ConfigParam;
125
125
  export declare const loadUserConfig: (appDirectory: string, filePath?: string | undefined, packageJsonConfig?: string | undefined) => Promise<LoadedConfig>;
126
- export declare const resolveConfig: (loaded: LoadedConfig, configs: UserConfig[], schemas: PluginValidateSchema[], isRestart: boolean, argv: string[]) => Promise<NormalizedConfig>;
126
+ export declare const resolveConfig: (loaded: LoadedConfig, configs: UserConfig[], schemas: PluginValidateSchema[], restartWithExistingPort: number, argv: string[]) => Promise<NormalizedConfig>;
127
+ export type { SourceConfig, OutputConfig, ServerConfig, DevConfig, DeployConfig, ToolsConfig, RuntimeConfig, RuntimeByEntriesConfig, UserConfig, ConfigParam, LoadedConfig };
@@ -2,11 +2,10 @@ import { INTERNAL_PLUGINS } from '@modern-js/utils';
2
2
  import { ParallelWorkflow, AsyncWorkflow, Progresses2Runners, AsyncWaterfall } from '@modern-js/plugin';
3
3
  import type { Hooks } from '@modern-js/types';
4
4
  import { Command } from './utils/commander';
5
- import { defineConfig, loadUserConfig, UserConfig, ToolsConfig } from './config';
6
5
  import { AppContext, ConfigContext, IAppContext, initAppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext } from './context';
7
6
  import { NormalizedConfig } from './config/mergeConfig';
8
7
  export type { Hooks };
9
- export { defaultsConfig, mergeConfig } from './config';
8
+ export * from './config';
10
9
  export * from '@modern-js/plugin';
11
10
  export * from '@modern-js/plugin/node';
12
11
  export declare type HooksRunner = Progresses2Runners<{
@@ -88,8 +87,8 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
88
87
  beforeExit: AsyncWorkflow<void, void>;
89
88
  } & import("@modern-js/plugin").ClearDraftProgress<Hooks>>;
90
89
  export declare const usePlugins: (plugins: string[]) => void;
91
- export { defineConfig, AppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext, ConfigContext };
92
- export type { NormalizedConfig, IAppContext, UserConfig, ToolsConfig };
90
+ export { AppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext, ConfigContext };
91
+ export type { NormalizedConfig, IAppContext };
93
92
  declare const initAppDir: (cwd?: string | undefined) => Promise<string>;
94
93
  export interface CoreOptions {
95
94
  configFile?: string;
@@ -111,4 +110,4 @@ export declare const cli: {
111
110
  run: (argv: string[], options?: CoreOptions | undefined) => Promise<void>;
112
111
  restart: () => Promise<void>;
113
112
  };
114
- export { loadUserConfig, initAppDir, initAppContext };
113
+ export { initAppDir, initAppContext };
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.3.0",
14
+ "version": "1.3.1",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -44,7 +44,7 @@
44
44
  "@babel/runtime": "^7",
45
45
  "@modern-js/load-config": "^1.2.0",
46
46
  "@modern-js/plugin": "^1.2.0",
47
- "@modern-js/utils": "^1.2.0",
47
+ "@modern-js/utils": "^1.2.1",
48
48
  "address": "^1.1.2",
49
49
  "ajv": "^8.6.2",
50
50
  "ajv-keywords": "^5.0.0",
@@ -24,7 +24,7 @@ const debug = createDebugger('resolve-config');
24
24
  export { defaults as defaultsConfig };
25
25
  export { mergeConfig };
26
26
 
27
- export interface SourceConfig {
27
+ interface SourceConfig {
28
28
  entries?: Record<
29
29
  string,
30
30
  | string
@@ -49,7 +49,7 @@ export interface SourceConfig {
49
49
  include?: Array<string | RegExp>;
50
50
  }
51
51
 
52
- export interface OutputConfig {
52
+ interface OutputConfig {
53
53
  assetPrefix?: string;
54
54
  htmlPath?: string;
55
55
  jsPath?: string;
@@ -92,7 +92,7 @@ export interface OutputConfig {
92
92
  enableTsLoader?: boolean;
93
93
  }
94
94
 
95
- export interface ServerConfig {
95
+ interface ServerConfig {
96
96
  routes?: Record<
97
97
  string,
98
98
  | string
@@ -111,12 +111,12 @@ export interface ServerConfig {
111
111
  enableMicroFrontendDebug?: boolean;
112
112
  }
113
113
 
114
- export interface DevConfig {
114
+ interface DevConfig {
115
115
  assetPrefix?: string | boolean;
116
116
  https?: boolean;
117
117
  }
118
118
 
119
- export interface DeployConfig {
119
+ interface DeployConfig {
120
120
  microFrontend?: boolean & Record<string, unknown>;
121
121
  domain?: string | Array<string>;
122
122
  domainByEntries?: Record<string, string | Array<string>>;
@@ -126,7 +126,7 @@ type ConfigFunction =
126
126
  | Record<string, unknown>
127
127
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
128
128
  | ((config: Record<string, unknown>) => Record<string, unknown> | void);
129
- export interface ToolsConfig {
129
+ interface ToolsConfig {
130
130
  webpack?: ConfigFunction;
131
131
  babel?: ConfigFunction;
132
132
  autoprefixer?: ConfigFunction;
@@ -139,13 +139,13 @@ export interface ToolsConfig {
139
139
  esbuild?: Record<string, unknown>;
140
140
  }
141
141
 
142
- export type RuntimeConfig = Record<string, any>;
142
+ type RuntimeConfig = Record<string, any>;
143
143
 
144
- export interface RuntimeByEntriesConfig {
144
+ interface RuntimeByEntriesConfig {
145
145
  [name: string]: RuntimeConfig;
146
146
  }
147
147
 
148
- export interface UserConfig {
148
+ interface UserConfig {
149
149
  source?: SourceConfig;
150
150
  output?: OutputConfig;
151
151
  server?: ServerConfig;
@@ -157,12 +157,12 @@ export interface UserConfig {
157
157
  runtimeByEntries?: RuntimeByEntriesConfig;
158
158
  }
159
159
 
160
- export type ConfigParam =
160
+ type ConfigParam =
161
161
  | UserConfig
162
162
  | Promise<UserConfig>
163
163
  | ((env: any) => UserConfig | Promise<UserConfig>);
164
164
 
165
- export interface LoadedConfig {
165
+ interface LoadedConfig {
166
166
  config: UserConfig;
167
167
  filePath: string | false;
168
168
  dependencies: string[];
@@ -231,7 +231,7 @@ export const resolveConfig = async (
231
231
  loaded: LoadedConfig,
232
232
  configs: UserConfig[],
233
233
  schemas: PluginValidateSchema[],
234
- isRestart: boolean,
234
+ restartWithExistingPort: number,
235
235
  argv: string[],
236
236
  ): Promise<NormalizedConfig> => {
237
237
  const { config: userConfig, jsConfig, pkgConfig } = loaded;
@@ -291,8 +291,14 @@ export const resolveConfig = async (
291
291
 
292
292
  resolved._raw = loaded.config;
293
293
 
294
- if (isDev() && argv[0] === 'dev' && !isRestart) {
295
- resolved.server.port = await getPort(resolved.server.port!);
294
+ if (isDev() && argv[0] === 'dev') {
295
+ if (restartWithExistingPort > 0) {
296
+ // dev server is restarted, should use existing port number
297
+ resolved.server.port = restartWithExistingPort;
298
+ } else {
299
+ // get port for new dev server
300
+ resolved.server.port = await getPort(resolved.server.port!);
301
+ }
296
302
  }
297
303
 
298
304
  debug('resolved %o', resolved);
@@ -300,3 +306,17 @@ export const resolveConfig = async (
300
306
  return resolved;
301
307
  };
302
308
  /* eslint-enable max-statements, max-params */
309
+
310
+ export type {
311
+ SourceConfig,
312
+ OutputConfig,
313
+ ServerConfig,
314
+ DevConfig,
315
+ DeployConfig,
316
+ ToolsConfig,
317
+ RuntimeConfig,
318
+ RuntimeByEntriesConfig,
319
+ UserConfig,
320
+ ConfigParam,
321
+ LoadedConfig,
322
+ };
package/src/index.ts CHANGED
@@ -20,13 +20,7 @@ import { enable } from '@modern-js/plugin/node';
20
20
 
21
21
  import type { Hooks } from '@modern-js/types';
22
22
  import { program, Command } from './utils/commander';
23
- import {
24
- resolveConfig,
25
- defineConfig,
26
- loadUserConfig,
27
- UserConfig,
28
- ToolsConfig,
29
- } from './config';
23
+ import { resolveConfig, loadUserConfig } from './config';
30
24
  import { loadPlugins } from './loadPlugins';
31
25
  import {
32
26
  AppContext,
@@ -43,8 +37,7 @@ import { NormalizedConfig } from './config/mergeConfig';
43
37
  import { loadEnv } from './loadEnv';
44
38
 
45
39
  export type { Hooks };
46
- export { defaultsConfig, mergeConfig } from './config';
47
-
40
+ export * from './config';
48
41
  export * from '@modern-js/plugin';
49
42
  export * from '@modern-js/plugin/node';
50
43
 
@@ -117,7 +110,6 @@ export const usePlugins = (plugins: string[]) =>
117
110
  );
118
111
 
119
112
  export {
120
- defineConfig,
121
113
  AppContext,
122
114
  ResolvedConfigContext,
123
115
  useAppContext,
@@ -126,7 +118,7 @@ export {
126
118
  ConfigContext,
127
119
  };
128
120
 
129
- export type { NormalizedConfig, IAppContext, UserConfig, ToolsConfig };
121
+ export type { NormalizedConfig, IAppContext };
130
122
 
131
123
  const initAppDir = async (cwd?: string): Promise<string> => {
132
124
  if (!cwd) {
@@ -155,6 +147,7 @@ export interface CoreOptions {
155
147
  const createCli = () => {
156
148
  let hooksRunner: HooksRunner;
157
149
  let isRestart = false;
150
+ let restartWithExistingPort = 0;
158
151
 
159
152
  const init = async (argv: string[] = [], options?: CoreOptions) => {
160
153
  enable();
@@ -215,7 +208,7 @@ const createCli = () => {
215
208
  loaded,
216
209
  extraConfigs as any,
217
210
  extraSchemas as any,
218
- isRestart,
211
+ restartWithExistingPort,
219
212
  argv,
220
213
  );
221
214
 
@@ -256,6 +249,7 @@ const createCli = () => {
256
249
 
257
250
  async function restart() {
258
251
  isRestart = true;
252
+ restartWithExistingPort = isRestart ? AppContext.use().value?.port ?? 0 : 0;
259
253
 
260
254
  logger.info('Restart...\n');
261
255
 
@@ -281,4 +275,4 @@ const createCli = () => {
281
275
 
282
276
  export const cli = createCli();
283
277
 
284
- export { loadUserConfig, initAppDir, initAppContext };
278
+ export { initAppDir, initAppContext };
@@ -1,5 +1,6 @@
1
1
  import path from 'path';
2
2
  // import os from 'os';
3
+ import { isDev, getPort } from '@modern-js/utils';
3
4
  import { resolveConfig } from '../src/config';
4
5
  import {
5
6
  cli,
@@ -11,11 +12,67 @@ import {
11
12
  registerHook,
12
13
  useRunner,
13
14
  } from '../src';
15
+ import { defaults } from '../src/config/defaults';
16
+
17
+ jest.mock('@modern-js/utils', () => ({
18
+ __esModule: true,
19
+ ...jest.requireActual('@modern-js/utils'),
20
+ isDev: jest.fn(),
21
+ getPort: jest.fn(),
22
+ }));
14
23
 
15
24
  // const kOSRootDir =
16
25
  // os.platform() === 'win32' ? process.cwd().split(path.sep)[0] : '/';
17
26
 
18
27
  describe('config', () => {
28
+ /**
29
+ * Typescript Type annotations cannot be used for esbuild-jest
30
+ * test files that use jest.mock('@some/module')
31
+ * refer to this esbuild-jest issue:
32
+ * https://github.com/aelbore/esbuild-jest/issues/57
33
+ * TODO: find a better solution to solve this problem while allowing us
34
+ * to use esbuild, and have good TypeScript support
35
+ */
36
+ let loaded = {
37
+ config: {},
38
+ filePath: '',
39
+ dependencies: [],
40
+ pkgConfig: {},
41
+ jsConfig: {},
42
+ };
43
+ let schemas: any[] = [];
44
+ let restartWithExistingPort = 0;
45
+ let argv: string[] = ['dev'];
46
+ let configs: any[] = [];
47
+
48
+ const getResolvedConfig = async () =>
49
+ resolveConfig(loaded, configs, schemas, restartWithExistingPort, argv);
50
+
51
+ const resetParams = () => {
52
+ loaded = {
53
+ config: {},
54
+ filePath: '',
55
+ dependencies: [],
56
+ pkgConfig: {},
57
+ jsConfig: {},
58
+ };
59
+ schemas = [];
60
+ restartWithExistingPort = 0;
61
+ argv = ['dev'];
62
+ configs = [];
63
+ };
64
+ const resetMock = () => {
65
+ jest.resetAllMocks();
66
+ (isDev as jest.Mock).mockReturnValue(true);
67
+ (getPort as jest.Mock).mockReturnValue(
68
+ Promise.resolve(defaults.server.port),
69
+ );
70
+ };
71
+ beforeEach(() => {
72
+ resetParams();
73
+ resetMock();
74
+ });
75
+
19
76
  it('default', () => {
20
77
  expect(resolveConfig).toBeDefined();
21
78
  expect(cli).toBeDefined();
@@ -40,4 +97,41 @@ describe('config', () => {
40
97
  // expect(err.message).toMatch(/no package.json found in current work dir/);
41
98
  // }
42
99
  });
100
+
101
+ test('should use default port if not restarting in dev mode', async () => {
102
+ let resolved = await getResolvedConfig();
103
+ expect(resolved.server.port).toEqual(defaults.server.port);
104
+ expect(getPort).toHaveBeenCalledWith(defaults.server.port);
105
+
106
+ // getResolvedConfig should use the value givin by getPort
107
+ restartWithExistingPort = -1;
108
+ (getPort as jest.Mock).mockClear();
109
+ (getPort as jest.Mock).mockReturnValue(1111);
110
+ resolved = await getResolvedConfig();
111
+ expect(resolved.server.port).toEqual(1111);
112
+ expect(getPort).toHaveBeenCalledWith(defaults.server.port);
113
+
114
+ argv = ['start'];
115
+ (isDev as jest.Mock).mockReturnValue(false);
116
+ restartWithExistingPort = 0;
117
+ resolved = await getResolvedConfig();
118
+ expect(resolved.server.port).toEqual(defaults.server.port);
119
+
120
+ restartWithExistingPort = 1234;
121
+ resolved = await getResolvedConfig();
122
+ expect(resolved.server.port).toEqual(defaults.server.port);
123
+
124
+ restartWithExistingPort = -1;
125
+ resolved = await getResolvedConfig();
126
+ expect(resolved.server.port).toEqual(defaults.server.port);
127
+ });
128
+
129
+ test('should reuse existing port if restarting in dev mode', async () => {
130
+ restartWithExistingPort = 1234;
131
+ const resolved = await getResolvedConfig();
132
+ expect(resolved.server.port).toEqual(1234);
133
+ });
43
134
  });
135
+
136
+ // type TEST = Parameters<typeof resolveConfig>;
137
+ // type TypeC = TEST[1];
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": "index-test"
3
+ }
@@ -0,0 +1,74 @@
1
+ import path from 'path';
2
+ import { cli } from '../src';
3
+ import { resolveConfig, loadUserConfig } from '../src/config';
4
+ import { loadEnv } from '../src/loadEnv';
5
+
6
+ jest.mock('../src/config', () => ({
7
+ __esModule: true,
8
+ ...jest.requireActual('../src/config'),
9
+ loadUserConfig: jest.fn(),
10
+ resolveConfig: jest.fn(),
11
+ }));
12
+
13
+ jest.mock('../src/loadEnv', () => ({
14
+ __esModule: true,
15
+ ...jest.requireActual('../src/loadEnv'),
16
+ loadEnv: jest.fn(),
17
+ }));
18
+
19
+ describe('@modern-js/core test', () => {
20
+ let mockResolveConfig: any = {};
21
+ let mockLoadedConfig: any = {};
22
+ const cwdSpy = jest.spyOn(process, 'cwd');
23
+ const cwd = path.join(__dirname, './fixtures/index-test');
24
+
25
+ const resetMock = () => {
26
+ jest.resetAllMocks();
27
+ cwdSpy.mockReturnValue(cwd);
28
+ (resolveConfig as jest.Mock).mockReturnValue(
29
+ Promise.resolve(mockResolveConfig),
30
+ );
31
+ (loadUserConfig as jest.Mock).mockImplementation(() =>
32
+ Promise.resolve(mockLoadedConfig),
33
+ );
34
+ };
35
+
36
+ const resetValues = () => {
37
+ mockLoadedConfig = {
38
+ config: {},
39
+ filePath: false,
40
+ dependencies: [],
41
+ pkgConfig: {},
42
+ jsConfig: {},
43
+ };
44
+ mockResolveConfig = {
45
+ server: {
46
+ port: 8080,
47
+ },
48
+ output: {
49
+ path: './my/test/path',
50
+ },
51
+ };
52
+ };
53
+
54
+ beforeEach(() => {
55
+ resetValues();
56
+ resetMock();
57
+ });
58
+
59
+ it('test cli create', () => {
60
+ expect(cli).toBeTruthy();
61
+ });
62
+
63
+ it('test cli init dev', async () => {
64
+ cwdSpy.mockReturnValue(path.join(cwd, 'nested-folder'));
65
+ const options = {
66
+ beforeUsePlugins: jest.fn(),
67
+ };
68
+ options.beforeUsePlugins.mockImplementation((plugins, _) => plugins);
69
+ await cli.init(['dev'], options);
70
+ expect(loadEnv).toHaveBeenCalledWith(cwd);
71
+ expect(options.beforeUsePlugins).toHaveBeenCalledWith([], {});
72
+ // TODO: add more test cases
73
+ });
74
+ });