@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 +9 -0
- package/dist/js/modern/config/index.js +9 -3
- package/dist/js/modern/index.js +9 -5
- package/dist/js/node/config/index.js +9 -3
- package/dist/js/node/index.js +18 -32
- package/dist/types/config/index.d.ts +13 -12
- package/dist/types/index.d.ts +4 -5
- package/package.json +2 -2
- package/src/config/index.ts +34 -14
- package/src/index.ts +7 -13
- package/tests/config.test.ts +94 -0
- package/tests/fixtures/index-test/package.json +3 -0
- package/tests/index.test.ts +74 -0
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,
|
|
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'
|
|
99
|
-
|
|
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);
|
package/dist/js/modern/index.js
CHANGED
|
@@ -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,
|
|
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
|
|
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 {
|
|
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,
|
|
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 {
|
|
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,
|
|
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'
|
|
140
|
-
|
|
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);
|
package/dist/js/node/index.js
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
79
|
+
interface DevConfig {
|
|
80
80
|
assetPrefix?: string | boolean;
|
|
81
81
|
https?: boolean;
|
|
82
82
|
}
|
|
83
|
-
|
|
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
|
-
|
|
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
|
-
|
|
102
|
-
|
|
101
|
+
declare type RuntimeConfig = Record<string, any>;
|
|
102
|
+
interface RuntimeByEntriesConfig {
|
|
103
103
|
[name: string]: RuntimeConfig;
|
|
104
104
|
}
|
|
105
|
-
|
|
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
|
-
|
|
117
|
-
|
|
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[],
|
|
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 };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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
|
|
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 {
|
|
92
|
-
export type { NormalizedConfig, IAppContext
|
|
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 {
|
|
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.
|
|
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.
|
|
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",
|
package/src/config/index.ts
CHANGED
|
@@ -24,7 +24,7 @@ const debug = createDebugger('resolve-config');
|
|
|
24
24
|
export { defaults as defaultsConfig };
|
|
25
25
|
export { mergeConfig };
|
|
26
26
|
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
114
|
+
interface DevConfig {
|
|
115
115
|
assetPrefix?: string | boolean;
|
|
116
116
|
https?: boolean;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
|
|
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
|
-
|
|
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
|
-
|
|
142
|
+
type RuntimeConfig = Record<string, any>;
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
interface RuntimeByEntriesConfig {
|
|
145
145
|
[name: string]: RuntimeConfig;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
|
|
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
|
-
|
|
160
|
+
type ConfigParam =
|
|
161
161
|
| UserConfig
|
|
162
162
|
| Promise<UserConfig>
|
|
163
163
|
| ((env: any) => UserConfig | Promise<UserConfig>);
|
|
164
164
|
|
|
165
|
-
|
|
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
|
-
|
|
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'
|
|
295
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 {
|
|
278
|
+
export { initAppDir, initAppContext };
|
package/tests/config.test.ts
CHANGED
|
@@ -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,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
|
+
});
|