@modern-js/core 1.3.2 → 1.4.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.
- package/CHANGELOG.md +43 -0
- package/dist/js/modern/config/index.js +4 -4
- package/dist/js/modern/config/schema/tools.js +3 -0
- package/dist/js/modern/context.js +9 -4
- package/dist/js/modern/index.js +13 -4
- package/dist/js/modern/initWatcher.js +19 -3
- package/dist/js/modern/loadPlugins.js +5 -4
- package/dist/js/node/config/index.js +4 -4
- package/dist/js/node/config/schema/tools.js +3 -0
- package/dist/js/node/context.js +9 -4
- package/dist/js/node/index.js +13 -4
- package/dist/js/node/initWatcher.js +18 -2
- package/dist/js/node/loadPlugins.js +5 -4
- package/dist/types/config/index.d.ts +8 -2
- package/dist/types/config/schema/index.d.ts +3 -0
- package/dist/types/config/schema/tools.d.ts +3 -0
- package/dist/types/context.d.ts +1 -1
- package/dist/types/index.d.ts +12 -1
- package/dist/types/initWatcher.d.ts +2 -1
- package/dist/types/loadPlugins.d.ts +3 -1
- package/package.json +4 -5
- package/tests/context.test.ts +12 -5
- package/tests/index.test.ts +1 -1
- package/tests/initWatcher.test.ts +63 -0
- package/tests/loadEnv.test.ts +28 -0
- package/tests/loadPlugin.test.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# @modern-js/core
|
|
2
2
|
|
|
3
|
+
## 1.4.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b376c8d6: feat: enhance custom env
|
|
8
|
+
- e62c4efd: fix error typo for 'styledComponents'
|
|
9
|
+
- e2a8233f: support add schem error hook to core.init
|
|
10
|
+
|
|
11
|
+
## 1.4.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 53aca274: modify garfish-plugin config type
|
|
16
|
+
- 78279953: compiler entry bug fix and dev build console
|
|
17
|
+
- e116ace5: fix: coreOptions types
|
|
18
|
+
- 4d72edea: support dev compiler by entry
|
|
19
|
+
- Updated dependencies [78279953]
|
|
20
|
+
- Updated dependencies [4d72edea]
|
|
21
|
+
- @modern-js/utils@1.3.1
|
|
22
|
+
|
|
23
|
+
## 1.4.0
|
|
24
|
+
|
|
25
|
+
### Minor Changes
|
|
26
|
+
|
|
27
|
+
- bada2879: refactor plugin-garfish:
|
|
28
|
+
- change @modern-js/plugin-micro-frontend => @modern-js/plugin-garfish
|
|
29
|
+
- remove disableCustomerRouter logic
|
|
30
|
+
- adding unit test
|
|
31
|
+
- fix plugin-garfish type error
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- d9cc5ea9: support resatrt options transfer
|
|
36
|
+
- bd819a8d: fix: file route changed not trigger hot reload
|
|
37
|
+
- d099e5c5: fix error when modify modern.config.js
|
|
38
|
+
- 24f616ca: feat: support custom meta info
|
|
39
|
+
- Updated dependencies [ec4dbffb]
|
|
40
|
+
- Updated dependencies [d099e5c5]
|
|
41
|
+
- Updated dependencies [bada2879]
|
|
42
|
+
- Updated dependencies [24f616ca]
|
|
43
|
+
- Updated dependencies [bd819a8d]
|
|
44
|
+
- @modern-js/utils@1.3.0
|
|
45
|
+
|
|
3
46
|
## 1.3.2
|
|
4
47
|
|
|
5
48
|
### Patch Changes
|
|
@@ -33,8 +33,8 @@ export const loadUserConfig = async (appDirectory, filePath, packageJsonConfig)
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
const showAdditionalPropertiesError = error => {
|
|
36
|
-
if (error.keyword === 'additionalProperties' && error.
|
|
37
|
-
const target =
|
|
36
|
+
if (error.keyword === 'additionalProperties' && error.params.additionalProperty) {
|
|
37
|
+
const target = [error.instancePath.slice(1), error.params.additionalProperty].filter(Boolean).join('.');
|
|
38
38
|
const name = Object.keys(PLUGIN_SCHEMAS).find(key => PLUGIN_SCHEMAS[key].some(schemaItem => schemaItem.target === target));
|
|
39
39
|
|
|
40
40
|
if (name) {
|
|
@@ -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, restartWithExistingPort, argv) => {
|
|
48
|
+
export const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort, argv, onSchemaError = showAdditionalPropertiesError) => {
|
|
49
49
|
var _validate$errors;
|
|
50
50
|
|
|
51
51
|
const {
|
|
@@ -67,7 +67,7 @@ export const resolveConfig = async (loaded, configs, schemas, restartWithExistin
|
|
|
67
67
|
if (!valid && (_validate$errors = validate.errors) !== null && _validate$errors !== void 0 && _validate$errors.length) {
|
|
68
68
|
var _validate$errors2;
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
onSchemaError(validate === null || validate === void 0 ? void 0 : validate.errors[0]);
|
|
71
71
|
const errors = betterAjvErrors(validateSchema, userConfig, (_validate$errors2 = validate.errors) === null || _validate$errors2 === void 0 ? void 0 : _validate$errors2.map(e => _objectSpread(_objectSpread({}, e), {}, {
|
|
72
72
|
dataPath: e.instancePath
|
|
73
73
|
})), {
|
|
@@ -9,12 +9,13 @@ export const useConfigContext = () => ConfigContext.use().value;
|
|
|
9
9
|
export const useResolvedConfigContext = () => ResolvedConfigContext.use().value;
|
|
10
10
|
export const initAppContext = (appDirectory, plugins, configFile, options) => {
|
|
11
11
|
const {
|
|
12
|
+
metaName = 'modern-js',
|
|
12
13
|
srcDir = 'src',
|
|
13
14
|
distDir = '',
|
|
14
|
-
sharedDir = 'shared'
|
|
15
|
-
internalDir = '.modern-js'
|
|
15
|
+
sharedDir = 'shared'
|
|
16
16
|
} = options || {};
|
|
17
17
|
return {
|
|
18
|
+
metaName,
|
|
18
19
|
appDirectory,
|
|
19
20
|
configFile,
|
|
20
21
|
ip: address.ip(),
|
|
@@ -24,10 +25,14 @@ export const initAppContext = (appDirectory, plugins, configFile, options) => {
|
|
|
24
25
|
distDirectory: distDir,
|
|
25
26
|
sharedDirectory: path.resolve(appDirectory, sharedDir),
|
|
26
27
|
nodeModulesDirectory: path.resolve(appDirectory, './node_modules'),
|
|
27
|
-
internalDirectory: path.resolve(appDirectory, `./node_modules
|
|
28
|
+
internalDirectory: path.resolve(appDirectory, `./node_modules/.${metaName}`),
|
|
28
29
|
plugins,
|
|
29
30
|
htmlTemplates: {},
|
|
30
31
|
serverRoutes: [],
|
|
31
|
-
entrypoints: []
|
|
32
|
+
entrypoints: [],
|
|
33
|
+
checkedEntries: [],
|
|
34
|
+
existSrc: true,
|
|
35
|
+
internalDirAlias: `@_${metaName.replace(/-/g, '_')}_internal`,
|
|
36
|
+
internalSrcAlias: `@_${metaName.replace(/-/g, '_')}_src`
|
|
32
37
|
};
|
|
33
38
|
};
|
package/dist/js/modern/index.js
CHANGED
|
@@ -28,7 +28,9 @@ const hooksMap = {
|
|
|
28
28
|
watchFiles: createParallelWorkflow(),
|
|
29
29
|
fileChange: createAsyncWorkflow(),
|
|
30
30
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
31
|
-
beforeExit: createAsyncWorkflow()
|
|
31
|
+
beforeExit: createAsyncWorkflow(),
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
33
|
+
beforeRestart: createAsyncWorkflow()
|
|
32
34
|
};
|
|
33
35
|
export const manager = createAsyncManager(hooksMap);
|
|
34
36
|
export const {
|
|
@@ -60,12 +62,17 @@ const createCli = () => {
|
|
|
60
62
|
let hooksRunner;
|
|
61
63
|
let isRestart = false;
|
|
62
64
|
let restartWithExistingPort = 0;
|
|
65
|
+
let restartOptions; // eslint-disable-next-line max-statements
|
|
63
66
|
|
|
64
67
|
const init = async (argv = [], options) => {
|
|
68
|
+
var _options$options$meta, _options$options;
|
|
69
|
+
|
|
65
70
|
enable();
|
|
66
71
|
manager.clear();
|
|
72
|
+
restartOptions = options;
|
|
67
73
|
const appDirectory = await initAppDir();
|
|
68
|
-
|
|
74
|
+
const metaName = (_options$options$meta = options === null || options === void 0 ? void 0 : (_options$options = options.options) === null || _options$options === void 0 ? void 0 : _options$options.metaName) !== null && _options$options$meta !== void 0 ? _options$options$meta : 'MODERN';
|
|
75
|
+
loadEnv(appDirectory, process.env[`${metaName.toUpperCase()}_ENV`]);
|
|
69
76
|
const loaded = await loadUserConfig(appDirectory, options === null || options === void 0 ? void 0 : options.configFile, options === null || options === void 0 ? void 0 : options.packageJsonConfig);
|
|
70
77
|
let plugins = loadPlugins(appDirectory, loaded.config.plugins || [], options === null || options === void 0 ? void 0 : options.plugins);
|
|
71
78
|
|
|
@@ -96,7 +103,7 @@ const createCli = () => {
|
|
|
96
103
|
});
|
|
97
104
|
const extraConfigs = await hooksRunner.config();
|
|
98
105
|
const extraSchemas = await hooksRunner.validateSchema();
|
|
99
|
-
const config = await resolveConfig(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv);
|
|
106
|
+
const config = await resolveConfig(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv, options === null || options === void 0 ? void 0 : options.onSchemaError);
|
|
100
107
|
const {
|
|
101
108
|
resolved
|
|
102
109
|
} = await hooksRunner.resolvedConfig({
|
|
@@ -139,9 +146,11 @@ const createCli = () => {
|
|
|
139
146
|
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;
|
|
140
147
|
logger.info('Restart...\n');
|
|
141
148
|
let hasGetError = false;
|
|
149
|
+
const runner = manager.useRunner();
|
|
150
|
+
await runner.beforeRestart();
|
|
142
151
|
|
|
143
152
|
try {
|
|
144
|
-
await init(process.argv.slice(2));
|
|
153
|
+
await init(process.argv.slice(2), restartOptions);
|
|
145
154
|
} catch (err) {
|
|
146
155
|
console.error(err);
|
|
147
156
|
hasGetError = true;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { isDev, createDebugger } from '@modern-js/utils';
|
|
4
|
+
import { isDev, createDebugger, isTest } from '@modern-js/utils';
|
|
5
5
|
import chokidar from 'chokidar';
|
|
6
6
|
const debug = createDebugger('watch-files');
|
|
7
7
|
|
|
@@ -10,7 +10,7 @@ const md5 = data => crypto.createHash('md5').update(data).digest('hex');
|
|
|
10
10
|
const hashMap = new Map();
|
|
11
11
|
export const initWatcher = async (loaded, appDirectory, configDir, hooksRunner, argv) => {
|
|
12
12
|
// only add fs watcher on dev mode.
|
|
13
|
-
if (isDev() && argv[0] === 'dev') {
|
|
13
|
+
if ((isDev() || isTest()) && argv[0] === 'dev') {
|
|
14
14
|
const extraFiles = await hooksRunner.watchFiles();
|
|
15
15
|
const configPath = path.join(appDirectory, configDir);
|
|
16
16
|
const watched = [`${configPath}/html`, ...extraFiles, loaded === null || loaded === void 0 ? void 0 : loaded.filePath, ...loaded.dependencies].filter(Boolean);
|
|
@@ -28,19 +28,35 @@ export const initWatcher = async (loaded, appDirectory, configDir, hooksRunner,
|
|
|
28
28
|
debug(`file change: %s`, changed);
|
|
29
29
|
hashMap.set(changed, currentHash);
|
|
30
30
|
hooksRunner.fileChange({
|
|
31
|
-
filename: changed
|
|
31
|
+
filename: changed,
|
|
32
|
+
eventType: 'change'
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
});
|
|
36
|
+
watcher.on('add', name => {
|
|
37
|
+
debug(`add file: %s`, name);
|
|
38
|
+
const currentHash = md5(fs.readFileSync(path.join(appDirectory, name), 'utf8'));
|
|
39
|
+
hashMap.set(name, currentHash);
|
|
40
|
+
hooksRunner.fileChange({
|
|
41
|
+
filename: name,
|
|
42
|
+
eventType: 'add'
|
|
43
|
+
});
|
|
44
|
+
});
|
|
35
45
|
watcher.on('unlink', name => {
|
|
36
46
|
debug(`remove file: %s`, name);
|
|
37
47
|
|
|
38
48
|
if (hashMap.has(name)) {
|
|
39
49
|
hashMap.delete(name);
|
|
40
50
|
}
|
|
51
|
+
|
|
52
|
+
hooksRunner.fileChange({
|
|
53
|
+
filename: name,
|
|
54
|
+
eventType: 'unlink'
|
|
55
|
+
});
|
|
41
56
|
});
|
|
42
57
|
watcher.on('error', err => {
|
|
43
58
|
throw err;
|
|
44
59
|
});
|
|
60
|
+
return watcher;
|
|
45
61
|
}
|
|
46
62
|
};
|
|
@@ -81,12 +81,13 @@ export const loadPlugins = (appDirectory, pluginConfig, internalPlugins) => {
|
|
|
81
81
|
|
|
82
82
|
const cliPlugin = cli && _objectSpread(_objectSpread({}, compatRequire(cli)), {}, {
|
|
83
83
|
pluginPath: cli
|
|
84
|
-
});
|
|
84
|
+
}); // server plugin should be required by server
|
|
85
85
|
|
|
86
|
-
const serverPlugin = server && _objectSpread(_objectSpread({}, compatRequire(server)), {}, {
|
|
87
|
-
pluginPath: server
|
|
88
|
-
});
|
|
89
86
|
|
|
87
|
+
const serverPlugin = server && {
|
|
88
|
+
// ...compatRequire(server),
|
|
89
|
+
pluginPath: server
|
|
90
|
+
};
|
|
90
91
|
return {
|
|
91
92
|
cli: cliPlugin,
|
|
92
93
|
cliPath: typeof plugin === 'string' ? plugin : plugin.cli,
|
|
@@ -71,8 +71,8 @@ const loadUserConfig = async (appDirectory, filePath, packageJsonConfig) => {
|
|
|
71
71
|
exports.loadUserConfig = loadUserConfig;
|
|
72
72
|
|
|
73
73
|
const showAdditionalPropertiesError = error => {
|
|
74
|
-
if (error.keyword === 'additionalProperties' && error.
|
|
75
|
-
const target =
|
|
74
|
+
if (error.keyword === 'additionalProperties' && error.params.additionalProperty) {
|
|
75
|
+
const target = [error.instancePath.slice(1), error.params.additionalProperty].filter(Boolean).join('.');
|
|
76
76
|
const name = Object.keys(_utils.PLUGIN_SCHEMAS).find(key => _utils.PLUGIN_SCHEMAS[key].some(schemaItem => schemaItem.target === target));
|
|
77
77
|
|
|
78
78
|
if (name) {
|
|
@@ -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, restartWithExistingPort, argv) => {
|
|
86
|
+
const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort, argv, onSchemaError = showAdditionalPropertiesError) => {
|
|
87
87
|
var _validate$errors;
|
|
88
88
|
|
|
89
89
|
const {
|
|
@@ -105,7 +105,7 @@ const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort,
|
|
|
105
105
|
if (!valid && (_validate$errors = validate.errors) !== null && _validate$errors !== void 0 && _validate$errors.length) {
|
|
106
106
|
var _validate$errors2;
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
onSchemaError(validate === null || validate === void 0 ? void 0 : validate.errors[0]);
|
|
109
109
|
const errors = (0, _betterAjvErrors.default)(validateSchema, userConfig, (_validate$errors2 = validate.errors) === null || _validate$errors2 === void 0 ? void 0 : _validate$errors2.map(e => _objectSpread(_objectSpread({}, e), {}, {
|
|
110
110
|
dataPath: e.instancePath
|
|
111
111
|
})), {
|
package/dist/js/node/context.js
CHANGED
|
@@ -34,12 +34,13 @@ exports.useResolvedConfigContext = useResolvedConfigContext;
|
|
|
34
34
|
|
|
35
35
|
const initAppContext = (appDirectory, plugins, configFile, options) => {
|
|
36
36
|
const {
|
|
37
|
+
metaName = 'modern-js',
|
|
37
38
|
srcDir = 'src',
|
|
38
39
|
distDir = '',
|
|
39
|
-
sharedDir = 'shared'
|
|
40
|
-
internalDir = '.modern-js'
|
|
40
|
+
sharedDir = 'shared'
|
|
41
41
|
} = options || {};
|
|
42
42
|
return {
|
|
43
|
+
metaName,
|
|
43
44
|
appDirectory,
|
|
44
45
|
configFile,
|
|
45
46
|
ip: _address.default.ip(),
|
|
@@ -49,11 +50,15 @@ const initAppContext = (appDirectory, plugins, configFile, options) => {
|
|
|
49
50
|
distDirectory: distDir,
|
|
50
51
|
sharedDirectory: _path.default.resolve(appDirectory, sharedDir),
|
|
51
52
|
nodeModulesDirectory: _path.default.resolve(appDirectory, './node_modules'),
|
|
52
|
-
internalDirectory: _path.default.resolve(appDirectory, `./node_modules
|
|
53
|
+
internalDirectory: _path.default.resolve(appDirectory, `./node_modules/.${metaName}`),
|
|
53
54
|
plugins,
|
|
54
55
|
htmlTemplates: {},
|
|
55
56
|
serverRoutes: [],
|
|
56
|
-
entrypoints: []
|
|
57
|
+
entrypoints: [],
|
|
58
|
+
checkedEntries: [],
|
|
59
|
+
existSrc: true,
|
|
60
|
+
internalDirAlias: `@_${metaName.replace(/-/g, '_')}_internal`,
|
|
61
|
+
internalSrcAlias: `@_${metaName.replace(/-/g, '_')}_src`
|
|
57
62
|
};
|
|
58
63
|
};
|
|
59
64
|
|
package/dist/js/node/index.js
CHANGED
|
@@ -141,7 +141,9 @@ const hooksMap = {
|
|
|
141
141
|
watchFiles: (0, _plugin.createParallelWorkflow)(),
|
|
142
142
|
fileChange: (0, _plugin.createAsyncWorkflow)(),
|
|
143
143
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
144
|
-
beforeExit: (0, _plugin.createAsyncWorkflow)()
|
|
144
|
+
beforeExit: (0, _plugin.createAsyncWorkflow)(),
|
|
145
|
+
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
146
|
+
beforeRestart: (0, _plugin.createAsyncWorkflow)()
|
|
145
147
|
};
|
|
146
148
|
const manager = (0, _plugin.createAsyncManager)(hooksMap);
|
|
147
149
|
exports.manager = manager;
|
|
@@ -181,12 +183,17 @@ const createCli = () => {
|
|
|
181
183
|
let hooksRunner;
|
|
182
184
|
let isRestart = false;
|
|
183
185
|
let restartWithExistingPort = 0;
|
|
186
|
+
let restartOptions; // eslint-disable-next-line max-statements
|
|
184
187
|
|
|
185
188
|
const init = async (argv = [], options) => {
|
|
189
|
+
var _options$options$meta, _options$options;
|
|
190
|
+
|
|
186
191
|
(0, _node.enable)();
|
|
187
192
|
manager.clear();
|
|
193
|
+
restartOptions = options;
|
|
188
194
|
const appDirectory = await initAppDir();
|
|
189
|
-
(0
|
|
195
|
+
const metaName = (_options$options$meta = options === null || options === void 0 ? void 0 : (_options$options = options.options) === null || _options$options === void 0 ? void 0 : _options$options.metaName) !== null && _options$options$meta !== void 0 ? _options$options$meta : 'MODERN';
|
|
196
|
+
(0, _loadEnv.loadEnv)(appDirectory, process.env[`${metaName.toUpperCase()}_ENV`]);
|
|
190
197
|
const loaded = await (0, _config.loadUserConfig)(appDirectory, options === null || options === void 0 ? void 0 : options.configFile, options === null || options === void 0 ? void 0 : options.packageJsonConfig);
|
|
191
198
|
let plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || [], options === null || options === void 0 ? void 0 : options.plugins);
|
|
192
199
|
|
|
@@ -218,7 +225,7 @@ const createCli = () => {
|
|
|
218
225
|
});
|
|
219
226
|
const extraConfigs = await hooksRunner.config();
|
|
220
227
|
const extraSchemas = await hooksRunner.validateSchema();
|
|
221
|
-
const config = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv);
|
|
228
|
+
const config = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv, options === null || options === void 0 ? void 0 : options.onSchemaError);
|
|
222
229
|
const {
|
|
223
230
|
resolved
|
|
224
231
|
} = await hooksRunner.resolvedConfig({
|
|
@@ -265,9 +272,11 @@ const createCli = () => {
|
|
|
265
272
|
_utils.logger.info('Restart...\n');
|
|
266
273
|
|
|
267
274
|
let hasGetError = false;
|
|
275
|
+
const runner = manager.useRunner();
|
|
276
|
+
await runner.beforeRestart();
|
|
268
277
|
|
|
269
278
|
try {
|
|
270
|
-
await init(process.argv.slice(2));
|
|
279
|
+
await init(process.argv.slice(2), restartOptions);
|
|
271
280
|
} catch (err) {
|
|
272
281
|
console.error(err);
|
|
273
282
|
hasGetError = true;
|
|
@@ -25,7 +25,7 @@ const hashMap = new Map();
|
|
|
25
25
|
|
|
26
26
|
const initWatcher = async (loaded, appDirectory, configDir, hooksRunner, argv) => {
|
|
27
27
|
// only add fs watcher on dev mode.
|
|
28
|
-
if ((0, _utils.isDev)() && argv[0] === 'dev') {
|
|
28
|
+
if (((0, _utils.isDev)() || (0, _utils.isTest)()) && argv[0] === 'dev') {
|
|
29
29
|
const extraFiles = await hooksRunner.watchFiles();
|
|
30
30
|
|
|
31
31
|
const configPath = _path.default.join(appDirectory, configDir);
|
|
@@ -47,20 +47,36 @@ const initWatcher = async (loaded, appDirectory, configDir, hooksRunner, argv) =
|
|
|
47
47
|
debug(`file change: %s`, changed);
|
|
48
48
|
hashMap.set(changed, currentHash);
|
|
49
49
|
hooksRunner.fileChange({
|
|
50
|
-
filename: changed
|
|
50
|
+
filename: changed,
|
|
51
|
+
eventType: 'change'
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
54
|
});
|
|
55
|
+
watcher.on('add', name => {
|
|
56
|
+
debug(`add file: %s`, name);
|
|
57
|
+
const currentHash = md5(_fs.default.readFileSync(_path.default.join(appDirectory, name), 'utf8'));
|
|
58
|
+
hashMap.set(name, currentHash);
|
|
59
|
+
hooksRunner.fileChange({
|
|
60
|
+
filename: name,
|
|
61
|
+
eventType: 'add'
|
|
62
|
+
});
|
|
63
|
+
});
|
|
54
64
|
watcher.on('unlink', name => {
|
|
55
65
|
debug(`remove file: %s`, name);
|
|
56
66
|
|
|
57
67
|
if (hashMap.has(name)) {
|
|
58
68
|
hashMap.delete(name);
|
|
59
69
|
}
|
|
70
|
+
|
|
71
|
+
hooksRunner.fileChange({
|
|
72
|
+
filename: name,
|
|
73
|
+
eventType: 'unlink'
|
|
74
|
+
});
|
|
60
75
|
});
|
|
61
76
|
watcher.on('error', err => {
|
|
62
77
|
throw err;
|
|
63
78
|
});
|
|
79
|
+
return watcher;
|
|
64
80
|
}
|
|
65
81
|
};
|
|
66
82
|
|
|
@@ -91,12 +91,13 @@ const loadPlugins = (appDirectory, pluginConfig, internalPlugins) => {
|
|
|
91
91
|
|
|
92
92
|
const cliPlugin = cli && _objectSpread(_objectSpread({}, (0, _utils.compatRequire)(cli)), {}, {
|
|
93
93
|
pluginPath: cli
|
|
94
|
-
});
|
|
94
|
+
}); // server plugin should be required by server
|
|
95
95
|
|
|
96
|
-
const serverPlugin = server && _objectSpread(_objectSpread({}, (0, _utils.compatRequire)(server)), {}, {
|
|
97
|
-
pluginPath: server
|
|
98
|
-
});
|
|
99
96
|
|
|
97
|
+
const serverPlugin = server && {
|
|
98
|
+
// ...compatRequire(server),
|
|
99
|
+
pluginPath: server
|
|
100
|
+
};
|
|
100
101
|
return {
|
|
101
102
|
cli: cliPlugin,
|
|
102
103
|
cliPath: typeof plugin === 'string' ? plugin : plugin.cli,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ErrorObject } from 'ajv';
|
|
1
2
|
import { MetaOptions } from '@modern-js/utils';
|
|
2
3
|
import { PluginConfig } from '../loadPlugins';
|
|
3
4
|
import { defaults } from './defaults';
|
|
@@ -80,8 +81,13 @@ interface DevConfig {
|
|
|
80
81
|
assetPrefix?: string | boolean;
|
|
81
82
|
https?: boolean;
|
|
82
83
|
}
|
|
84
|
+
interface MicroFrontend {
|
|
85
|
+
enableHtmlEntry?: boolean;
|
|
86
|
+
externalBasicLibrary?: boolean;
|
|
87
|
+
moduleApp?: string;
|
|
88
|
+
}
|
|
83
89
|
interface DeployConfig {
|
|
84
|
-
microFrontend?:
|
|
90
|
+
microFrontend?: false | MicroFrontend;
|
|
85
91
|
domain?: string | Array<string>;
|
|
86
92
|
domainByEntries?: Record<string, string | Array<string>>;
|
|
87
93
|
}
|
|
@@ -123,5 +129,5 @@ interface LoadedConfig {
|
|
|
123
129
|
}
|
|
124
130
|
export declare const defineConfig: (config: ConfigParam) => ConfigParam;
|
|
125
131
|
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[], restartWithExistingPort: number, argv: string[]) => Promise<NormalizedConfig>;
|
|
132
|
+
export declare const resolveConfig: (loaded: LoadedConfig, configs: UserConfig[], schemas: PluginValidateSchema[], restartWithExistingPort: number, argv: string[], onSchemaError?: (error: ErrorObject) => void) => Promise<NormalizedConfig>;
|
|
127
133
|
export type { SourceConfig, OutputConfig, ServerConfig, DevConfig, DeployConfig, ToolsConfig, RuntimeConfig, RuntimeByEntriesConfig, UserConfig, ConfigParam, LoadedConfig };
|
package/dist/types/context.d.ts
CHANGED
|
@@ -12,8 +12,8 @@ export declare const initAppContext: (appDirectory: string, plugins: Array<{
|
|
|
12
12
|
cli: any;
|
|
13
13
|
server: any;
|
|
14
14
|
}>, configFile: string | false, options?: {
|
|
15
|
+
metaName?: string | undefined;
|
|
15
16
|
srcDir?: string | undefined;
|
|
16
17
|
distDir?: string | undefined;
|
|
17
18
|
sharedDir?: string | undefined;
|
|
18
|
-
internalDir?: string | undefined;
|
|
19
19
|
} | undefined) => IAppContext;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
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
|
+
import { ErrorObject } from 'ajv';
|
|
4
5
|
import { Command } from './utils/commander';
|
|
5
6
|
import { AppContext, ConfigContext, IAppContext, initAppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext } from './context';
|
|
6
7
|
import { NormalizedConfig } from './config/mergeConfig';
|
|
@@ -21,6 +22,7 @@ export declare type HooksRunner = Progresses2Runners<{
|
|
|
21
22
|
watchFiles: ParallelWorkflow<void>;
|
|
22
23
|
fileChange: AsyncWorkflow<{
|
|
23
24
|
filename: string;
|
|
25
|
+
eventType: 'add' | 'change' | 'unlink';
|
|
24
26
|
}, void>;
|
|
25
27
|
beforeExit: AsyncWorkflow<void, void>;
|
|
26
28
|
}>;
|
|
@@ -37,8 +39,10 @@ export declare const manager: import("@modern-js/plugin").AsyncManager<Hooks, {
|
|
|
37
39
|
watchFiles: ParallelWorkflow<void, unknown>;
|
|
38
40
|
fileChange: AsyncWorkflow<{
|
|
39
41
|
filename: string;
|
|
42
|
+
eventType: 'add' | 'change' | 'unlink';
|
|
40
43
|
}, void>;
|
|
41
44
|
beforeExit: AsyncWorkflow<void, void>;
|
|
45
|
+
beforeRestart: AsyncWorkflow<void, void>;
|
|
42
46
|
}>;
|
|
43
47
|
export declare const createPlugin: (initializer: import("@modern-js/plugin").AsyncInitializer<Partial<import("@modern-js/plugin").Progresses2Threads<{
|
|
44
48
|
config: ParallelWorkflow<void, unknown>;
|
|
@@ -53,8 +57,10 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
|
|
|
53
57
|
watchFiles: ParallelWorkflow<void, unknown>;
|
|
54
58
|
fileChange: AsyncWorkflow<{
|
|
55
59
|
filename: string;
|
|
60
|
+
eventType: 'add' | 'change' | 'unlink';
|
|
56
61
|
}, void>;
|
|
57
62
|
beforeExit: AsyncWorkflow<void, void>;
|
|
63
|
+
beforeRestart: AsyncWorkflow<void, void>;
|
|
58
64
|
} & import("@modern-js/plugin").ClearDraftProgress<Hooks>>>>, options?: import("@modern-js/plugin").PluginOptions | undefined) => import("@modern-js/plugin").AsyncPlugin<Partial<import("@modern-js/plugin").Progresses2Threads<{
|
|
59
65
|
config: ParallelWorkflow<void, unknown>;
|
|
60
66
|
resolvedConfig: AsyncWaterfall<{
|
|
@@ -68,8 +74,10 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
|
|
|
68
74
|
watchFiles: ParallelWorkflow<void, unknown>;
|
|
69
75
|
fileChange: AsyncWorkflow<{
|
|
70
76
|
filename: string;
|
|
77
|
+
eventType: 'add' | 'change' | 'unlink';
|
|
71
78
|
}, void>;
|
|
72
79
|
beforeExit: AsyncWorkflow<void, void>;
|
|
80
|
+
beforeRestart: AsyncWorkflow<void, void>;
|
|
73
81
|
} & import("@modern-js/plugin").ClearDraftProgress<Hooks>>>>, registerHook: (newShape: Partial<Hooks>) => void, mountHook: () => Progresses2Runners<{
|
|
74
82
|
config: ParallelWorkflow<void, unknown>;
|
|
75
83
|
resolvedConfig: AsyncWaterfall<{
|
|
@@ -83,8 +91,10 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
|
|
|
83
91
|
watchFiles: ParallelWorkflow<void, unknown>;
|
|
84
92
|
fileChange: AsyncWorkflow<{
|
|
85
93
|
filename: string;
|
|
94
|
+
eventType: 'add' | 'change' | 'unlink';
|
|
86
95
|
}, void>;
|
|
87
96
|
beforeExit: AsyncWorkflow<void, void>;
|
|
97
|
+
beforeRestart: AsyncWorkflow<void, void>;
|
|
88
98
|
} & import("@modern-js/plugin").ClearDraftProgress<Hooks>>;
|
|
89
99
|
export declare const usePlugins: (plugins: string[]) => void;
|
|
90
100
|
export { AppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext, ConfigContext };
|
|
@@ -100,11 +110,12 @@ export interface CoreOptions {
|
|
|
100
110
|
server: any;
|
|
101
111
|
serverPath: any;
|
|
102
112
|
}[];
|
|
113
|
+
onSchemaError?: (error: ErrorObject) => void;
|
|
103
114
|
options?: {
|
|
115
|
+
metaName?: string;
|
|
104
116
|
srcDir?: string;
|
|
105
117
|
distDir?: string;
|
|
106
118
|
sharedDir?: string;
|
|
107
|
-
internalDir?: string;
|
|
108
119
|
};
|
|
109
120
|
}
|
|
110
121
|
export declare const cli: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import chokidar from 'chokidar';
|
|
1
2
|
import { LoadedConfig } from './config';
|
|
2
3
|
import { HooksRunner } from '.';
|
|
3
|
-
export declare const initWatcher: (loaded: LoadedConfig, appDirectory: string, configDir: string | undefined, hooksRunner: HooksRunner, argv: string[]) => Promise<
|
|
4
|
+
export declare const initWatcher: (loaded: LoadedConfig, appDirectory: string, configDir: string | undefined, hooksRunner: HooksRunner, argv: string[]) => Promise<chokidar.FSWatcher | undefined>;
|
|
@@ -23,6 +23,8 @@ export declare const loadPlugins: (appDirectory: string, pluginConfig: PluginCon
|
|
|
23
23
|
} | undefined) => {
|
|
24
24
|
cli: any;
|
|
25
25
|
cliPath: string | undefined;
|
|
26
|
-
server:
|
|
26
|
+
server: "" | {
|
|
27
|
+
pluginPath: string;
|
|
28
|
+
} | undefined;
|
|
27
29
|
serverPath: string | undefined;
|
|
28
30
|
}[];
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.4.2",
|
|
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.1",
|
|
46
46
|
"@modern-js/plugin": "^1.2.1",
|
|
47
|
-
"@modern-js/utils": "^1.
|
|
47
|
+
"@modern-js/utils": "^1.3.1",
|
|
48
48
|
"address": "^1.1.2",
|
|
49
49
|
"ajv": "^8.6.2",
|
|
50
50
|
"ajv-keywords": "^5.0.0",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"btsm": "2.2.2",
|
|
64
64
|
"@types/babel__code-frame": "^7.0.3",
|
|
65
|
-
"@modern-js/types": "^1.2
|
|
65
|
+
"@modern-js/types": "^1.3.2",
|
|
66
66
|
"@types/jest": "^26",
|
|
67
67
|
"@types/lodash.clonedeep": "^4.5.6",
|
|
68
68
|
"@types/lodash.mergewith": "^4.6.6",
|
|
@@ -83,8 +83,7 @@
|
|
|
83
83
|
},
|
|
84
84
|
"publishConfig": {
|
|
85
85
|
"registry": "https://registry.npmjs.org/",
|
|
86
|
-
"access": "public"
|
|
87
|
-
"types": "./dist/types/index.d.ts"
|
|
86
|
+
"access": "public"
|
|
88
87
|
},
|
|
89
88
|
"scripts": {
|
|
90
89
|
"new": "modern new",
|
package/tests/context.test.ts
CHANGED
|
@@ -23,6 +23,11 @@ describe('context', () => {
|
|
|
23
23
|
htmlTemplates: {},
|
|
24
24
|
serverRoutes: [],
|
|
25
25
|
entrypoints: [],
|
|
26
|
+
checkedEntries: [],
|
|
27
|
+
existSrc: true,
|
|
28
|
+
internalDirAlias: '@_modern_js_internal',
|
|
29
|
+
internalSrcAlias: '@_modern_js_src',
|
|
30
|
+
metaName: 'modern-js',
|
|
26
31
|
});
|
|
27
32
|
});
|
|
28
33
|
|
|
@@ -36,7 +41,7 @@ describe('context', () => {
|
|
|
36
41
|
srcDir: 'source',
|
|
37
42
|
distDir: 'dist',
|
|
38
43
|
sharedDir: 'myShared',
|
|
39
|
-
|
|
44
|
+
metaName: 'jupiter',
|
|
40
45
|
};
|
|
41
46
|
|
|
42
47
|
const appContext = initAppContext(appDirectory, [], false, customOptions);
|
|
@@ -50,14 +55,16 @@ describe('context', () => {
|
|
|
50
55
|
distDirectory: 'dist',
|
|
51
56
|
sharedDirectory: path.resolve(appDirectory, './myShared'),
|
|
52
57
|
nodeModulesDirectory: expect.any(String),
|
|
53
|
-
internalDirectory: path.resolve(
|
|
54
|
-
appDirectory,
|
|
55
|
-
'./node_modules/myInternal',
|
|
56
|
-
),
|
|
58
|
+
internalDirectory: path.resolve(appDirectory, './node_modules/.jupiter'),
|
|
57
59
|
plugins: [],
|
|
58
60
|
htmlTemplates: {},
|
|
59
61
|
serverRoutes: [],
|
|
60
62
|
entrypoints: [],
|
|
63
|
+
checkedEntries: [],
|
|
64
|
+
existSrc: true,
|
|
65
|
+
internalDirAlias: '@_jupiter_internal',
|
|
66
|
+
internalSrcAlias: '@_jupiter_src',
|
|
67
|
+
metaName: 'jupiter',
|
|
61
68
|
});
|
|
62
69
|
});
|
|
63
70
|
});
|
package/tests/index.test.ts
CHANGED
|
@@ -67,7 +67,7 @@ describe('@modern-js/core test', () => {
|
|
|
67
67
|
};
|
|
68
68
|
options.beforeUsePlugins.mockImplementation((plugins, _) => plugins);
|
|
69
69
|
await cli.init(['dev'], options);
|
|
70
|
-
expect(loadEnv).toHaveBeenCalledWith(cwd);
|
|
70
|
+
expect(loadEnv).toHaveBeenCalledWith(cwd, undefined);
|
|
71
71
|
expect(options.beforeUsePlugins).toHaveBeenCalledWith([], {});
|
|
72
72
|
// TODO: add more test cases
|
|
73
73
|
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { fs, wait } from '@modern-js/utils';
|
|
3
|
+
import { initWatcher } from '../src/initWatcher';
|
|
4
|
+
|
|
5
|
+
jest.useRealTimers();
|
|
6
|
+
|
|
7
|
+
const mockAppDirectory = path.join(__dirname, './fixtures/index-test');
|
|
8
|
+
const mockConfigDir = './config';
|
|
9
|
+
const mockSrcDirectory = path.join(mockAppDirectory, './src');
|
|
10
|
+
|
|
11
|
+
describe('initWatcher', () => {
|
|
12
|
+
afterAll(() => {
|
|
13
|
+
const file = path.join(mockSrcDirectory, './index.ts');
|
|
14
|
+
if (fs.existsSync(file)) {
|
|
15
|
+
fs.unlinkSync(file);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('will trigger add event', async () => {
|
|
20
|
+
let triggeredType = '';
|
|
21
|
+
let triggeredFile = '';
|
|
22
|
+
const loaded = {
|
|
23
|
+
filePath: '',
|
|
24
|
+
dependencies: [],
|
|
25
|
+
};
|
|
26
|
+
const hooksRunner = {
|
|
27
|
+
watchFiles: async () => [mockSrcDirectory],
|
|
28
|
+
fileChange: jest.fn(({ filename, eventType }) => {
|
|
29
|
+
triggeredType = eventType;
|
|
30
|
+
triggeredFile = filename;
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
if (await fs.pathExists(mockSrcDirectory)) {
|
|
35
|
+
await fs.remove(mockSrcDirectory);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const watcher = await initWatcher(
|
|
39
|
+
loaded as any,
|
|
40
|
+
mockAppDirectory,
|
|
41
|
+
mockConfigDir,
|
|
42
|
+
hooksRunner as any,
|
|
43
|
+
['dev'],
|
|
44
|
+
);
|
|
45
|
+
await wait(100);
|
|
46
|
+
|
|
47
|
+
const file = path.join(mockSrcDirectory, './index.ts');
|
|
48
|
+
await fs.outputFile(file, '');
|
|
49
|
+
await wait(100);
|
|
50
|
+
// expect(hooksRunner.fileChange).toBeCalledTimes(1);
|
|
51
|
+
// expect(triggeredType).toBe('add');
|
|
52
|
+
expect(file.includes(triggeredFile)).toBeTruthy();
|
|
53
|
+
|
|
54
|
+
await wait(100);
|
|
55
|
+
await fs.remove(file);
|
|
56
|
+
await wait(200);
|
|
57
|
+
expect(hooksRunner.fileChange).toBeCalledTimes(2);
|
|
58
|
+
expect(triggeredType).toBe('unlink');
|
|
59
|
+
expect(file.includes(triggeredFile)).toBeTruthy();
|
|
60
|
+
|
|
61
|
+
watcher?.close();
|
|
62
|
+
});
|
|
63
|
+
});
|
package/tests/loadEnv.test.ts
CHANGED
|
@@ -124,6 +124,34 @@ describe('load environment variables', () => {
|
|
|
124
124
|
delete process.env.NODE_ENV;
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
test(`get custom .env file by MODERN_ENV`, () => {
|
|
128
|
+
createFixtures('custom_environment', [
|
|
129
|
+
{
|
|
130
|
+
name: '.env',
|
|
131
|
+
content: `DB_HOST=localhost
|
|
132
|
+
DB_USER=root
|
|
133
|
+
DB_PASS=root
|
|
134
|
+
`,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: '.env.staging',
|
|
138
|
+
content: `DB_HOST=localhost
|
|
139
|
+
DB_USER=root-local-dev
|
|
140
|
+
`,
|
|
141
|
+
},
|
|
142
|
+
]);
|
|
143
|
+
|
|
144
|
+
loadEnv(path.join(fixture, 'custom_environment'), 'staging');
|
|
145
|
+
|
|
146
|
+
expect(process.env.DB_HOST).toBe('localhost');
|
|
147
|
+
|
|
148
|
+
expect(process.env.DB_USER).toBe('root-local-dev');
|
|
149
|
+
|
|
150
|
+
expect(process.env.DB_PASS).toBe('root');
|
|
151
|
+
|
|
152
|
+
delete process.env.MODERN_ENV;
|
|
153
|
+
});
|
|
154
|
+
|
|
127
155
|
test(`support dotenv-expand`, () => {
|
|
128
156
|
createFixtures('expand', [
|
|
129
157
|
{
|