@modern-js/core 1.0.1 → 1.1.3

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,14 +1,58 @@
1
1
  # @modern-js/core
2
2
 
3
- ## 1.0.1
3
+ ## 1.1.3
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - release 1.0.1
8
- - Updated dependencies [undefined]
9
- - @modern-js/load-config@1.0.1
10
- - @modern-js/plugin@1.0.1
11
- - @modern-js/utils@1.0.1
7
+ - 085a6a58: refactor server plugin
8
+ - 085a6a58: refactor server plugin
9
+ - 085a6a58: refactor server conifg
10
+ - d4fcc73a: add options.plugins:
11
+ - 085a6a58: support server runtime
12
+ - ed1f6b12: feat: support build --analyze
13
+ - a5ebbb00: fix: remove enableUsageBuiltIns config
14
+ - 085a6a58: feat: refactor server plugin
15
+ - Updated dependencies [085a6a58]
16
+ - Updated dependencies [085a6a58]
17
+ - Updated dependencies [085a6a58]
18
+ - Updated dependencies [d280ea33]
19
+ - Updated dependencies [085a6a58]
20
+ - Updated dependencies [085a6a58]
21
+ - @modern-js/utils@1.1.3
22
+
23
+ ## 1.1.2
24
+
25
+ ### Patch Changes
26
+
27
+ - 6f7fe574: modern-js/core support extra options
28
+ - 0fa83663: support more .env files
29
+ - Updated dependencies [0fa83663]
30
+ - Updated dependencies [f594fbc8]
31
+ - @modern-js/load-config@1.1.1
32
+ - @modern-js/plugin@1.1.2
33
+ - @modern-js/utils@1.1.2
34
+
35
+ ## 1.1.1
36
+
37
+ ### Patch Changes
38
+
39
+ - 687c92c7: refactor: generator input questions
40
+ feat: add eslint generator
41
+ - Updated dependencies [c0fc0700]
42
+ - Updated dependencies [6ffd1a50]
43
+ - @modern-js/utils@1.1.1
44
+ - @modern-js/plugin@1.1.1
45
+
46
+ ## 1.1.0
47
+
48
+ ### Minor Changes
49
+
50
+ - 96119db2: Relese v1.1.0### Patch Changes
51
+
52
+ - Updated dependencies [96119db2]
53
+ - @modern-js/load-config@1.1.0
54
+ - @modern-js/plugin@1.1.0
55
+ - @modern-js/utils@1.1.0
12
56
 
13
57
  ## 1.0.0
14
58
 
@@ -18,6 +18,7 @@ import { mergeConfig } from "./mergeConfig";
18
18
  import { patchSchema } from "./schema";
19
19
  const debug = createDebugger('resolve-config');
20
20
  export { defaults as defaultsConfig };
21
+ export { mergeConfig };
21
22
  export const defineConfig = config => config;
22
23
  export const loadUserConfig = async (appDirectory, filePath) => {
23
24
  const loaded = await loadConfig(appDirectory, filePath);
@@ -107,9 +107,6 @@ export const output = {
107
107
  enableLatestDecorators: {
108
108
  type: 'boolean'
109
109
  },
110
- enableUsageBuiltIns: {
111
- type: 'boolean'
112
- },
113
110
  enableTsLoader: {
114
111
  type: 'boolean'
115
112
  },
@@ -6,7 +6,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
6
6
 
7
7
  import path from 'path';
8
8
  import { compatRequire, pkgUp, ensureAbsolutePath, logger } from '@modern-js/utils';
9
- import { createAsyncManager, createAsyncWorkflow, createParallelWorkflow } from '@modern-js/plugin';
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
12
  import { resolveConfig, defineConfig, loadUserConfig } from "./config";
@@ -14,12 +14,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 } from "./config";
17
+ export { defaultsConfig, mergeConfig } 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');
21
21
  const hooksMap = {
22
22
  config: createParallelWorkflow(),
23
+ resolvedConfig: createAsyncWaterfall(),
23
24
  validateSchema: createParallelWorkflow(),
24
25
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
25
26
  prepare: createAsyncWorkflow(),
@@ -36,7 +37,7 @@ export const {
36
37
  useRunner: mountHook
37
38
  } = manager;
38
39
  export const usePlugins = plugins => plugins.forEach(plugin => manager.usePlugin(compatRequire(require.resolve(plugin))));
39
- export { defineConfig, AppContext, useAppContext, useConfigContext, useResolvedConfigContext };
40
+ export { defineConfig, AppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext, ConfigContext };
40
41
 
41
42
  const initAppDir = async () => {
42
43
  const pkg = await pkgUp({
@@ -54,13 +55,18 @@ const createCli = () => {
54
55
  let hooksRunner;
55
56
  let isRestart = false;
56
57
 
57
- const init = async (argv = []) => {
58
+ const init = async (argv = [], options) => {
58
59
  enable();
59
60
  manager.clear();
60
61
  const appDirectory = await initAppDir();
61
62
  loadEnv(appDirectory);
62
- const loaded = await loadUserConfig(appDirectory);
63
- const plugins = loadPlugins(appDirectory, loaded.config.plugins || []);
63
+ const loaded = await loadUserConfig(appDirectory, options === null || options === void 0 ? void 0 : options.configFile);
64
+ let plugins = loadPlugins(appDirectory, loaded.config.plugins || [], options === null || options === void 0 ? void 0 : options.plugins);
65
+
66
+ if (options !== null && options !== void 0 && options.beforeUsePlugins) {
67
+ plugins = options.beforeUsePlugins(plugins, loaded.config);
68
+ }
69
+
64
70
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
65
71
  const appContext = initAppContext(appDirectory, plugins, loaded.filePath);
66
72
  manager.run(() => {
@@ -84,7 +90,12 @@ const createCli = () => {
84
90
  });
85
91
  const extraConfigs = await hooksRunner.config();
86
92
  const extraSchemas = await hooksRunner.validateSchema();
87
- const resolved = await resolveConfig(loaded, extraConfigs, extraSchemas, isRestart, argv); // update context value
93
+ const config = await resolveConfig(loaded, extraConfigs, extraSchemas, isRestart, argv);
94
+ const {
95
+ resolved
96
+ } = await hooksRunner.resolvedConfig({
97
+ resolved: config
98
+ }); // update context value
88
99
 
89
100
  manager.run(() => {
90
101
  ConfigContext.set(loaded.config);
@@ -102,12 +113,12 @@ const createCli = () => {
102
113
  };
103
114
  };
104
115
 
105
- async function run(argv) {
116
+ async function run(argv, options) {
106
117
  const {
107
118
  loadedConfig,
108
119
  appContext,
109
120
  resolved
110
- } = await init(argv);
121
+ } = await init(argv, options);
111
122
  await hooksRunner.commands({
112
123
  program
113
124
  });
@@ -139,4 +150,5 @@ const createCli = () => {
139
150
  };
140
151
  };
141
152
 
142
- export const cli = createCli();
153
+ export const cli = createCli();
154
+ export { loadUserConfig, initAppDir, initAppContext };
@@ -3,7 +3,9 @@ import path from 'path';
3
3
  import dotenv from 'dotenv';
4
4
  import dotenvExpand from 'dotenv-expand';
5
5
  export const loadEnv = (appDirectory, mode = process.env.NODE_ENV) => {
6
- [`.env.${mode}`, '.env'].map(name => path.resolve(appDirectory, name)).filter(filePath => fs.existsSync(filePath) && !fs.statSync(filePath).isDirectory()).forEach(filePath => {
6
+ // Don't change the order of the filenames, since they are ordered by the priority.
7
+ // Files on the left have more priority than files on the right.
8
+ [`.env.${mode}.local`, '.env.local', `.env.${mode}`, '.env'].map(name => path.resolve(appDirectory, name)).filter(filePath => fs.existsSync(filePath) && !fs.statSync(filePath).isDirectory()).forEach(filePath => {
7
9
  const envConfig = dotenv.config({
8
10
  path: filePath
9
11
  });
@@ -29,8 +29,8 @@ const resolvePlugin = (appDirectory, plugin) => {
29
29
 
30
30
  const resolved = {};
31
31
 
32
- if (plugin.cli) {
33
- resolved.cli = tryResolve(plugin.cli);
32
+ if (typeof plugin === 'string' || plugin.cli) {
33
+ resolved.cli = typeof plugin === 'string' ? tryResolve(plugin) : tryResolve(plugin.cli);
34
34
  }
35
35
 
36
36
  if (plugin.server) {
@@ -47,8 +47,8 @@ const resolvePlugin = (appDirectory, plugin) => {
47
47
  */
48
48
 
49
49
 
50
- export const loadPlugins = (appDirectory, pluginConfig) => {
51
- const plugins = [...Object.keys(INTERNAL_PLUGINS).filter(name => isDepExists(appDirectory, name)).map(name => INTERNAL_PLUGINS[name]), ...pluginConfig];
50
+ export const loadPlugins = (appDirectory, pluginConfig, internalPlugins) => {
51
+ const plugins = [...Object.keys(internalPlugins || INTERNAL_PLUGINS).filter(name => isDepExists(appDirectory, name)).map(name => (internalPlugins || INTERNAL_PLUGINS)[name]), ...pluginConfig];
52
52
  return plugins.map(plugin => {
53
53
  const {
54
54
  cli,
@@ -9,7 +9,14 @@ Object.defineProperty(exports, "defaultsConfig", {
9
9
  return _defaults.defaults;
10
10
  }
11
11
  });
12
- exports.resolveConfig = exports.loadUserConfig = exports.defineConfig = void 0;
12
+ exports.loadUserConfig = exports.defineConfig = void 0;
13
+ Object.defineProperty(exports, "mergeConfig", {
14
+ enumerable: true,
15
+ get: function () {
16
+ return _mergeConfig.mergeConfig;
17
+ }
18
+ });
19
+ exports.resolveConfig = void 0;
13
20
 
14
21
  var _loadConfig = require("@modern-js/load-config");
15
22
 
@@ -115,9 +115,6 @@ const output = {
115
115
  enableLatestDecorators: {
116
116
  type: 'boolean'
117
117
  },
118
- enableUsageBuiltIns: {
119
- type: 'boolean'
120
- },
121
118
  enableTsLoader: {
122
119
  type: 'boolean'
123
120
  },
@@ -10,9 +10,15 @@ var _exportNames = {
10
10
  mountHook: true,
11
11
  usePlugins: true,
12
12
  cli: true,
13
+ initAppDir: true,
13
14
  defineConfig: true,
15
+ loadUserConfig: true,
14
16
  defaultsConfig: true,
17
+ mergeConfig: true,
15
18
  AppContext: true,
19
+ ConfigContext: true,
20
+ initAppContext: true,
21
+ ResolvedConfigContext: true,
16
22
  useAppContext: true,
17
23
  useConfigContext: true,
18
24
  useResolvedConfigContext: true
@@ -23,6 +29,18 @@ Object.defineProperty(exports, "AppContext", {
23
29
  return _context.AppContext;
24
30
  }
25
31
  });
32
+ Object.defineProperty(exports, "ConfigContext", {
33
+ enumerable: true,
34
+ get: function () {
35
+ return _context.ConfigContext;
36
+ }
37
+ });
38
+ Object.defineProperty(exports, "ResolvedConfigContext", {
39
+ enumerable: true,
40
+ get: function () {
41
+ return _context.ResolvedConfigContext;
42
+ }
43
+ });
26
44
  exports.createPlugin = exports.cli = void 0;
27
45
  Object.defineProperty(exports, "defaultsConfig", {
28
46
  enumerable: true,
@@ -36,7 +54,27 @@ Object.defineProperty(exports, "defineConfig", {
36
54
  return _config.defineConfig;
37
55
  }
38
56
  });
39
- exports.registerHook = exports.mountHook = exports.manager = void 0;
57
+ Object.defineProperty(exports, "initAppContext", {
58
+ enumerable: true,
59
+ get: function () {
60
+ return _context.initAppContext;
61
+ }
62
+ });
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;
40
78
  Object.defineProperty(exports, "useAppContext", {
41
79
  enumerable: true,
42
80
  get: function () {
@@ -113,6 +151,7 @@ _commander.program.name('modern').usage('<command> [options]').version(process.e
113
151
 
114
152
  const hooksMap = {
115
153
  config: (0, _plugin.createParallelWorkflow)(),
154
+ resolvedConfig: (0, _plugin.createAsyncWaterfall)(),
116
155
  validateSchema: (0, _plugin.createParallelWorkflow)(),
117
156
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
118
157
  prepare: (0, _plugin.createAsyncWorkflow)(),
@@ -149,17 +188,24 @@ const initAppDir = async () => {
149
188
  return _path.default.dirname(pkg);
150
189
  };
151
190
 
191
+ exports.initAppDir = initAppDir;
192
+
152
193
  const createCli = () => {
153
194
  let hooksRunner;
154
195
  let isRestart = false;
155
196
 
156
- const init = async (argv = []) => {
197
+ const init = async (argv = [], options) => {
157
198
  (0, _node.enable)();
158
199
  manager.clear();
159
200
  const appDirectory = await initAppDir();
160
201
  (0, _loadEnv.loadEnv)(appDirectory);
161
- const loaded = await (0, _config.loadUserConfig)(appDirectory);
162
- const plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || []);
202
+ const loaded = await (0, _config.loadUserConfig)(appDirectory, options === null || options === void 0 ? void 0 : options.configFile);
203
+ let plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || [], options === null || options === void 0 ? void 0 : options.plugins);
204
+
205
+ if (options !== null && options !== void 0 && options.beforeUsePlugins) {
206
+ plugins = options.beforeUsePlugins(plugins, loaded.config);
207
+ }
208
+
163
209
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
164
210
  const appContext = (0, _context.initAppContext)(appDirectory, plugins, loaded.filePath);
165
211
  manager.run(() => {
@@ -184,7 +230,12 @@ const createCli = () => {
184
230
  });
185
231
  const extraConfigs = await hooksRunner.config();
186
232
  const extraSchemas = await hooksRunner.validateSchema();
187
- const resolved = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, isRestart, argv); // update context value
233
+ const config = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, isRestart, argv);
234
+ const {
235
+ resolved
236
+ } = await hooksRunner.resolvedConfig({
237
+ resolved: config
238
+ }); // update context value
188
239
 
189
240
  manager.run(() => {
190
241
  _context.ConfigContext.set(loaded.config);
@@ -204,12 +255,12 @@ const createCli = () => {
204
255
  };
205
256
  };
206
257
 
207
- async function run(argv) {
258
+ async function run(argv, options) {
208
259
  const {
209
260
  loadedConfig,
210
261
  appContext,
211
262
  resolved
212
- } = await init(argv);
263
+ } = await init(argv, options);
213
264
  await hooksRunner.commands({
214
265
  program: _commander.program
215
266
  });
@@ -16,7 +16,9 @@ var _dotenvExpand = _interopRequireDefault(require("dotenv-expand"));
16
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
17
 
18
18
  const loadEnv = (appDirectory, mode = process.env.NODE_ENV) => {
19
- [`.env.${mode}`, '.env'].map(name => _path.default.resolve(appDirectory, name)).filter(filePath => _fs.default.existsSync(filePath) && !_fs.default.statSync(filePath).isDirectory()).forEach(filePath => {
19
+ // Don't change the order of the filenames, since they are ordered by the priority.
20
+ // Files on the left have more priority than files on the right.
21
+ [`.env.${mode}.local`, '.env.local', `.env.${mode}`, '.env'].map(name => _path.default.resolve(appDirectory, name)).filter(filePath => _fs.default.existsSync(filePath) && !_fs.default.statSync(filePath).isDirectory()).forEach(filePath => {
20
22
  const envConfig = _dotenv.default.config({
21
23
  path: filePath
22
24
  });
@@ -37,8 +37,8 @@ const resolvePlugin = (appDirectory, plugin) => {
37
37
 
38
38
  const resolved = {};
39
39
 
40
- if (plugin.cli) {
41
- resolved.cli = tryResolve(plugin.cli);
40
+ if (typeof plugin === 'string' || plugin.cli) {
41
+ resolved.cli = typeof plugin === 'string' ? tryResolve(plugin) : tryResolve(plugin.cli);
42
42
  }
43
43
 
44
44
  if (plugin.server) {
@@ -55,8 +55,8 @@ const resolvePlugin = (appDirectory, plugin) => {
55
55
  */
56
56
 
57
57
 
58
- const loadPlugins = (appDirectory, pluginConfig) => {
59
- const plugins = [...Object.keys(_utils.INTERNAL_PLUGINS).filter(name => (0, _utils.isDepExists)(appDirectory, name)).map(name => _utils.INTERNAL_PLUGINS[name]), ...pluginConfig];
58
+ const loadPlugins = (appDirectory, pluginConfig, internalPlugins) => {
59
+ const plugins = [...Object.keys(internalPlugins || _utils.INTERNAL_PLUGINS).filter(name => (0, _utils.isDepExists)(appDirectory, name)).map(name => (internalPlugins || _utils.INTERNAL_PLUGINS)[name]), ...pluginConfig];
60
60
  return plugins.map(plugin => {
61
61
  const {
62
62
  cli,
@@ -1,9 +1,10 @@
1
1
  import { MetaOptions } from '@modern-js/utils';
2
2
  import { PluginConfig } from '../loadPlugins';
3
3
  import { defaults } from './defaults';
4
- import { NormalizedConfig } from './mergeConfig';
4
+ import { mergeConfig, NormalizedConfig } from './mergeConfig';
5
5
  import { PluginValidateSchema } from './schema';
6
6
  export { defaults as defaultsConfig };
7
+ export { mergeConfig };
7
8
  export interface SourceConfig {
8
9
  entries?: Record<string, string | {
9
10
  entry: string;
@@ -17,6 +17,7 @@ export interface NormalizedToolsConfig extends Omit<ToolsConfig, 'webpack' | 'ba
17
17
  export interface NormalizedConfig extends Omit<Required<UserConfig>, 'source' | 'tools'> {
18
18
  source: NormalizedSourceConfig;
19
19
  tools: NormalizedToolsConfig;
20
+ cliOptions?: Record<string, any>;
20
21
  _raw: UserConfig;
21
22
  }
22
23
  /**
@@ -173,9 +173,6 @@ export declare const patchSchema: (pluginSchemas: Array<PluginValidateSchema | P
173
173
  enableLatestDecorators: {
174
174
  type: string;
175
175
  };
176
- enableUsageBuiltIns: {
177
- type: string;
178
- };
179
176
  enableTsLoader: {
180
177
  type: string;
181
178
  };
@@ -106,9 +106,6 @@ export declare const output: {
106
106
  enableLatestDecorators: {
107
107
  type: string;
108
108
  };
109
- enableUsageBuiltIns: {
110
- type: string;
111
- };
112
109
  enableTsLoader: {
113
110
  type: string;
114
111
  };
@@ -1,15 +1,19 @@
1
- import { ParallelWorkflow, AsyncWorkflow, Progresses2Runners } from '@modern-js/plugin';
1
+ import { INTERNAL_PLUGINS } from '@modern-js/utils';
2
+ import { ParallelWorkflow, AsyncWorkflow, Progresses2Runners, AsyncWaterfall } from '@modern-js/plugin';
2
3
  import type { Hooks } from '@modern-js/types';
3
4
  import { Command } from './utils/commander';
4
- import { defineConfig, UserConfig, ToolsConfig } from './config';
5
- import { AppContext, IAppContext, useAppContext, useConfigContext, useResolvedConfigContext } from './context';
5
+ import { defineConfig, loadUserConfig, UserConfig, ToolsConfig } from './config';
6
+ import { AppContext, ConfigContext, IAppContext, initAppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext } from './context';
6
7
  import { NormalizedConfig } from './config/mergeConfig';
7
8
  export type { Hooks };
8
- export { defaultsConfig } from './config';
9
+ export { defaultsConfig, mergeConfig } from './config';
9
10
  export * from '@modern-js/plugin';
10
11
  export * from '@modern-js/plugin/node';
11
12
  export declare type HooksRunner = Progresses2Runners<{
12
13
  config: ParallelWorkflow<void>;
14
+ resolvedConfig: AsyncWaterfall<{
15
+ resolved: NormalizedConfig;
16
+ }>;
13
17
  validateSchema: ParallelWorkflow<void>;
14
18
  prepare: AsyncWorkflow<void, void>;
15
19
  commands: AsyncWorkflow<{
@@ -23,6 +27,9 @@ export declare type HooksRunner = Progresses2Runners<{
23
27
  }>;
24
28
  export declare const manager: import("@modern-js/plugin").AsyncManager<Hooks, {
25
29
  config: ParallelWorkflow<void, unknown>;
30
+ resolvedConfig: AsyncWaterfall<{
31
+ resolved: NormalizedConfig;
32
+ }>;
26
33
  validateSchema: ParallelWorkflow<void, unknown>;
27
34
  prepare: AsyncWorkflow<void, void>;
28
35
  commands: AsyncWorkflow<{
@@ -36,6 +43,9 @@ export declare const manager: import("@modern-js/plugin").AsyncManager<Hooks, {
36
43
  }>;
37
44
  export declare const createPlugin: (initializer: import("@modern-js/plugin").AsyncInitializer<Partial<import("@modern-js/plugin").Progresses2Threads<{
38
45
  config: ParallelWorkflow<void, unknown>;
46
+ resolvedConfig: AsyncWaterfall<{
47
+ resolved: NormalizedConfig;
48
+ }>;
39
49
  validateSchema: ParallelWorkflow<void, unknown>;
40
50
  prepare: AsyncWorkflow<void, void>;
41
51
  commands: AsyncWorkflow<{
@@ -48,6 +58,9 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
48
58
  beforeExit: AsyncWorkflow<void, void>;
49
59
  } & import("@modern-js/plugin").ClearDraftProgress<Hooks>>>>, options?: import("@modern-js/plugin").PluginOptions | undefined) => import("@modern-js/plugin").AsyncPlugin<Partial<import("@modern-js/plugin").Progresses2Threads<{
50
60
  config: ParallelWorkflow<void, unknown>;
61
+ resolvedConfig: AsyncWaterfall<{
62
+ resolved: NormalizedConfig;
63
+ }>;
51
64
  validateSchema: ParallelWorkflow<void, unknown>;
52
65
  prepare: AsyncWorkflow<void, void>;
53
66
  commands: AsyncWorkflow<{
@@ -60,6 +73,9 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
60
73
  beforeExit: AsyncWorkflow<void, void>;
61
74
  } & import("@modern-js/plugin").ClearDraftProgress<Hooks>>>>, registerHook: (newShape: Partial<Hooks>) => void, mountHook: () => Progresses2Runners<{
62
75
  config: ParallelWorkflow<void, unknown>;
76
+ resolvedConfig: AsyncWaterfall<{
77
+ resolved: NormalizedConfig;
78
+ }>;
63
79
  validateSchema: ParallelWorkflow<void, unknown>;
64
80
  prepare: AsyncWorkflow<void, void>;
65
81
  commands: AsyncWorkflow<{
@@ -72,17 +88,24 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
72
88
  beforeExit: AsyncWorkflow<void, void>;
73
89
  } & import("@modern-js/plugin").ClearDraftProgress<Hooks>>;
74
90
  export declare const usePlugins: (plugins: string[]) => void;
75
- export { defineConfig, AppContext, useAppContext, useConfigContext, useResolvedConfigContext };
91
+ export { defineConfig, AppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext, ConfigContext };
76
92
  export type { NormalizedConfig, IAppContext, UserConfig, ToolsConfig };
77
- export interface CoreOption {
78
- dryRun?: boolean;
93
+ declare const initAppDir: () => Promise<string>;
94
+ export interface CoreOptions {
95
+ configFile?: string;
96
+ plugins?: typeof INTERNAL_PLUGINS;
97
+ beforeUsePlugins: (plugins: any, config: any) => {
98
+ cli: any;
99
+ server: any;
100
+ }[];
79
101
  }
80
102
  export declare const cli: {
81
- init: (argv?: string[]) => Promise<{
103
+ init: (argv?: string[], options?: CoreOptions | undefined) => Promise<{
82
104
  loadedConfig: import("./config").LoadedConfig;
83
105
  appContext: IAppContext;
84
106
  resolved: NormalizedConfig;
85
107
  }>;
86
- run: (argv: string[]) => Promise<void>;
108
+ run: (argv: string[], options?: CoreOptions | undefined) => Promise<void>;
87
109
  restart: () => Promise<void>;
88
- };
110
+ };
111
+ export { loadUserConfig, initAppDir, initAppContext };
@@ -10,7 +10,12 @@ export declare type PluginConfig = Array<PluginConfigItem>;
10
10
  * @returns Plugin Objects has been required.
11
11
  */
12
12
 
13
- export declare const loadPlugins: (appDirectory: string, pluginConfig: PluginConfig) => {
13
+ export declare const loadPlugins: (appDirectory: string, pluginConfig: PluginConfig, internalPlugins?: {
14
+ [name: string]: {
15
+ cli?: string | undefined;
16
+ server?: string | undefined;
17
+ };
18
+ } | undefined) => {
14
19
  cli: any;
15
20
  server: any;
16
21
  }[];
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.0.1",
14
+ "version": "1.1.3",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -38,9 +38,9 @@
38
38
  "dependencies": {
39
39
  "@babel/code-frame": "^7.14.5",
40
40
  "@babel/runtime": "^7",
41
- "@modern-js/load-config": "^1.0.1",
42
- "@modern-js/plugin": "^1.0.1",
43
- "@modern-js/utils": "^1.0.1",
41
+ "@modern-js/load-config": "^1.1.1",
42
+ "@modern-js/plugin": "^1.1.2",
43
+ "@modern-js/utils": "^1.1.3",
44
44
  "address": "^1.1.2",
45
45
  "ajv": "^8.6.2",
46
46
  "ajv-keywords": "^5.0.0",
@@ -57,7 +57,7 @@
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/babel__code-frame": "^7.0.3",
60
- "@modern-js/types": "^1.0.1",
60
+ "@modern-js/types": "^1.1.2",
61
61
  "@types/jest": "^26",
62
62
  "@types/lodash.clonedeep": "^4.5.6",
63
63
  "@types/lodash.mergewith": "^4.6.6",
@@ -66,8 +66,8 @@
66
66
  "@types/react-dom": "^17",
67
67
  "@types/signale": "^1.4.2",
68
68
  "typescript": "^4",
69
- "@modern-js/plugin-testing": "^1.0.2",
70
- "@modern-js/module-tools": "^1.0.2"
69
+ "@modern-js/plugin-testing": "^1.1.1",
70
+ "@modern-js/module-tools": "^1.1.1"
71
71
  },
72
72
  "sideEffects": false,
73
73
  "modernConfig": {
@@ -22,6 +22,7 @@ import { patchSchema, PluginValidateSchema } from './schema';
22
22
  const debug = createDebugger('resolve-config');
23
23
 
24
24
  export { defaults as defaultsConfig };
25
+ export { mergeConfig };
25
26
 
26
27
  export interface SourceConfig {
27
28
  entries?: Record<
@@ -43,6 +43,7 @@ export interface NormalizedConfig
43
43
  extends Omit<Required<UserConfig>, 'source' | 'tools'> {
44
44
  source: NormalizedSourceConfig;
45
45
  tools: NormalizedToolsConfig;
46
+ cliOptions?: Record<string, any>;
46
47
  _raw: UserConfig;
47
48
  }
48
49
 
@@ -46,7 +46,6 @@ export const output = {
46
46
  disableInlineRuntimeChunk: { type: 'boolean' },
47
47
  disableAssetsCache: { type: 'boolean' },
48
48
  enableLatestDecorators: { type: 'boolean' },
49
- enableUsageBuiltIns: { type: 'boolean' },
50
49
  enableTsLoader: { type: 'boolean' },
51
50
  dataUriLimit: { type: 'number' },
52
51
  templateParameters: { type: 'object' },
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  pkgUp,
5
5
  ensureAbsolutePath,
6
6
  logger,
7
+ INTERNAL_PLUGINS,
7
8
  } from '@modern-js/utils';
8
9
  import {
9
10
  createAsyncManager,
@@ -12,6 +13,8 @@ import {
12
13
  ParallelWorkflow,
13
14
  AsyncWorkflow,
14
15
  Progresses2Runners,
16
+ createAsyncWaterfall,
17
+ AsyncWaterfall,
15
18
  } from '@modern-js/plugin';
16
19
  import { enable } from '@modern-js/plugin/node';
17
20
 
@@ -40,7 +43,7 @@ import { NormalizedConfig } from './config/mergeConfig';
40
43
  import { loadEnv } from './loadEnv';
41
44
 
42
45
  export type { Hooks };
43
- export { defaultsConfig } from './config';
46
+ export { defaultsConfig, mergeConfig } from './config';
44
47
 
45
48
  export * from '@modern-js/plugin';
46
49
  export * from '@modern-js/plugin/node';
@@ -52,6 +55,9 @@ program
52
55
 
53
56
  export type HooksRunner = Progresses2Runners<{
54
57
  config: ParallelWorkflow<void>;
58
+ resolvedConfig: AsyncWaterfall<{
59
+ resolved: NormalizedConfig;
60
+ }>;
55
61
  validateSchema: ParallelWorkflow<void>;
56
62
  prepare: AsyncWorkflow<void, void>;
57
63
  commands: AsyncWorkflow<
@@ -72,6 +78,9 @@ export type HooksRunner = Progresses2Runners<{
72
78
 
73
79
  const hooksMap = {
74
80
  config: createParallelWorkflow(),
81
+ resolvedConfig: createAsyncWaterfall<{
82
+ resolved: NormalizedConfig;
83
+ }>(),
75
84
  validateSchema: createParallelWorkflow(),
76
85
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
77
86
  prepare: createAsyncWorkflow<void, void>(),
@@ -110,9 +119,11 @@ export const usePlugins = (plugins: string[]) =>
110
119
  export {
111
120
  defineConfig,
112
121
  AppContext,
122
+ ResolvedConfigContext,
113
123
  useAppContext,
114
124
  useConfigContext,
115
125
  useResolvedConfigContext,
126
+ ConfigContext,
116
127
  };
117
128
 
118
129
  export type { NormalizedConfig, IAppContext, UserConfig, ToolsConfig };
@@ -129,15 +140,17 @@ const initAppDir = async (): Promise<string> => {
129
140
  return path.dirname(pkg);
130
141
  };
131
142
 
132
- export interface CoreOption {
133
- dryRun?: boolean;
143
+ export interface CoreOptions {
144
+ configFile?: string;
145
+ plugins?: typeof INTERNAL_PLUGINS;
146
+ beforeUsePlugins: (plugins: any, config: any) => { cli: any; server: any }[];
134
147
  }
135
148
 
136
149
  const createCli = () => {
137
150
  let hooksRunner: HooksRunner;
138
151
  let isRestart = false;
139
152
 
140
- const init = async (argv: string[] = []) => {
153
+ const init = async (argv: string[] = [], options?: CoreOptions) => {
141
154
  enable();
142
155
 
143
156
  manager.clear();
@@ -146,9 +159,17 @@ const createCli = () => {
146
159
 
147
160
  loadEnv(appDirectory);
148
161
 
149
- const loaded = await loadUserConfig(appDirectory);
162
+ const loaded = await loadUserConfig(appDirectory, options?.configFile);
163
+
164
+ let plugins = loadPlugins(
165
+ appDirectory,
166
+ loaded.config.plugins || [],
167
+ options?.plugins,
168
+ );
150
169
 
151
- const plugins = loadPlugins(appDirectory, loaded.config.plugins || []);
170
+ if (options?.beforeUsePlugins) {
171
+ plugins = options.beforeUsePlugins(plugins, loaded.config);
172
+ }
152
173
 
153
174
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
154
175
 
@@ -180,7 +201,7 @@ const createCli = () => {
180
201
 
181
202
  const extraSchemas = await hooksRunner.validateSchema();
182
203
 
183
- const resolved = await resolveConfig(
204
+ const config = await resolveConfig(
184
205
  loaded,
185
206
  extraConfigs as any,
186
207
  extraSchemas as any,
@@ -188,6 +209,10 @@ const createCli = () => {
188
209
  argv,
189
210
  );
190
211
 
212
+ const { resolved } = await hooksRunner.resolvedConfig({
213
+ resolved: config,
214
+ });
215
+
191
216
  // update context value
192
217
  manager.run(() => {
193
218
  ConfigContext.set(loaded.config);
@@ -204,8 +229,8 @@ const createCli = () => {
204
229
  return { loadedConfig: loaded, appContext, resolved };
205
230
  };
206
231
 
207
- async function run(argv: string[]) {
208
- const { loadedConfig, appContext, resolved } = await init(argv);
232
+ async function run(argv: string[], options?: CoreOptions) {
233
+ const { loadedConfig, appContext, resolved } = await init(argv, options);
209
234
 
210
235
  await hooksRunner.commands({ program });
211
236
 
@@ -245,3 +270,5 @@ const createCli = () => {
245
270
  };
246
271
 
247
272
  export const cli = createCli();
273
+
274
+ export { loadUserConfig, initAppDir, initAppContext };
package/src/loadEnv.ts CHANGED
@@ -7,7 +7,9 @@ export const loadEnv = (
7
7
  appDirectory: string,
8
8
  mode: string = process.env.NODE_ENV as string,
9
9
  ) => {
10
- [`.env.${mode}`, '.env']
10
+ // Don't change the order of the filenames, since they are ordered by the priority.
11
+ // Files on the left have more priority than files on the right.
12
+ [`.env.${mode}.local`, '.env.local', `.env.${mode}`, '.env']
11
13
  .map(name => path.resolve(appDirectory, name))
12
14
  .filter(
13
15
  filePath =>
@@ -37,8 +37,9 @@ const resolvePlugin = (appDirectory: string, plugin: PluginConfigItem) => {
37
37
 
38
38
  const resolved: PluginConfigItem = {};
39
39
 
40
- if (plugin.cli) {
41
- resolved.cli = tryResolve(plugin.cli);
40
+ if (typeof plugin === 'string' || plugin.cli) {
41
+ resolved.cli =
42
+ typeof plugin === 'string' ? tryResolve(plugin) : tryResolve(plugin.cli!);
42
43
  }
43
44
 
44
45
  if (plugin.server) {
@@ -57,11 +58,12 @@ const resolvePlugin = (appDirectory: string, plugin: PluginConfigItem) => {
57
58
  export const loadPlugins = (
58
59
  appDirectory: string,
59
60
  pluginConfig: PluginConfig,
61
+ internalPlugins?: typeof INTERNAL_PLUGINS,
60
62
  ) => {
61
63
  const plugins = [
62
- ...Object.keys(INTERNAL_PLUGINS)
64
+ ...Object.keys(internalPlugins || INTERNAL_PLUGINS)
63
65
  .filter(name => isDepExists(appDirectory, name))
64
- .map(name => INTERNAL_PLUGINS[name]),
66
+ .map(name => (internalPlugins || INTERNAL_PLUGINS)[name]),
65
67
  ...pluginConfig,
66
68
  ];
67
69
 
@@ -1,5 +1,4 @@
1
1
  import fs from 'fs';
2
- import { exec } from 'child_process';
3
2
  import path from 'path';
4
3
  import { loadEnv } from '@/loadEnv';
5
4
 
@@ -27,7 +26,7 @@ describe('load environment variables', () => {
27
26
 
28
27
  afterAll(() => {
29
28
  process.env = { ...defaultEnv };
30
- exec(`rm -rf ${fixture}`);
29
+ fs.rmSync(fixture, { force: true, recursive: true });
31
30
  });
32
31
 
33
32
  test(`support .env file`, () => {
@@ -79,6 +78,52 @@ describe('load environment variables', () => {
79
78
  delete process.env.NODE_ENV;
80
79
  });
81
80
 
81
+ test(`should have correct priority`, () => {
82
+ createFixtures('priority', [
83
+ {
84
+ name: '.env',
85
+ content: `DB_HOST=localhost
86
+ DB_USER=user
87
+ DB_PASS=pass
88
+ `,
89
+ },
90
+ {
91
+ name: '.env.production',
92
+ content: `DB_USER=user_production
93
+ DB_PASS=pass_production
94
+ FOO=foo
95
+ BAR=bar
96
+ `,
97
+ },
98
+ {
99
+ name: '.env.local',
100
+ content: `FOO=foo_local
101
+ BAR=bar_local
102
+ `,
103
+ },
104
+ {
105
+ name: '.env.production.local',
106
+ content: `BAR=bar_production_local`,
107
+ },
108
+ ]);
109
+
110
+ process.env.NODE_ENV = 'production';
111
+
112
+ loadEnv(path.join(fixture, 'priority'));
113
+
114
+ expect(process.env.DB_HOST).toBe('localhost');
115
+
116
+ expect(process.env.DB_USER).toBe('user_production');
117
+
118
+ expect(process.env.DB_PASS).toBe('pass_production');
119
+
120
+ expect(process.env.FOO).toBe('foo_local');
121
+
122
+ expect(process.env.BAR).toBe('bar_production_local');
123
+
124
+ delete process.env.NODE_ENV;
125
+ });
126
+
82
127
  test(`support dotenv-expand`, () => {
83
128
  createFixtures('expand', [
84
129
  {