@modern-js/core 0.0.0-canary-2021101982333 → 0.0.0-options-202112031520

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,13 +1,27 @@
1
1
  # @modern-js/core
2
2
 
3
- ## 0.0.0-canary-2021101982333
3
+ ## 1.1.2
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - 687c92c: refactor: generator input questions
7
+ - 6f7fe574: modern-js/core support extra options
8
+ - 0fa83663: support more .env files
9
+ - Updated dependencies [0fa83663]
10
+ - Updated dependencies [f594fbc8]
11
+ - @modern-js/load-config@1.1.1
12
+ - @modern-js/plugin@1.1.2
13
+ - @modern-js/utils@1.1.2
14
+
15
+ ## 1.1.1
16
+
17
+ ### Patch Changes
18
+
19
+ - 687c92c7: refactor: generator input questions
8
20
  feat: add eslint generator
9
- - Updated dependencies [6ffd1a5]
10
- - @modern-js/plugin@0.0.0-canary-2021101982333
21
+ - Updated dependencies [c0fc0700]
22
+ - Updated dependencies [6ffd1a50]
23
+ - @modern-js/utils@1.1.1
24
+ - @modern-js/plugin@1.1.1
11
25
 
12
26
  ## 1.1.0
13
27
 
@@ -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";
@@ -20,6 +20,7 @@ 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(),
@@ -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
  });
@@ -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,
@@ -121,6 +121,7 @@ _commander.program.name('modern').usage('<command> [options]').version(process.e
121
121
 
122
122
  const hooksMap = {
123
123
  config: (0, _plugin.createParallelWorkflow)(),
124
+ resolvedConfig: (0, _plugin.createAsyncWaterfall)(),
124
125
  validateSchema: (0, _plugin.createParallelWorkflow)(),
125
126
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
126
127
  prepare: (0, _plugin.createAsyncWorkflow)(),
@@ -161,13 +162,18 @@ const createCli = () => {
161
162
  let hooksRunner;
162
163
  let isRestart = false;
163
164
 
164
- const init = async (argv = []) => {
165
+ const init = async (argv = [], options) => {
165
166
  (0, _node.enable)();
166
167
  manager.clear();
167
168
  const appDirectory = await initAppDir();
168
169
  (0, _loadEnv.loadEnv)(appDirectory);
169
- const loaded = await (0, _config.loadUserConfig)(appDirectory);
170
- const plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || []);
170
+ const loaded = await (0, _config.loadUserConfig)(appDirectory, options === null || options === void 0 ? void 0 : options.configFile);
171
+ let plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || [], options === null || options === void 0 ? void 0 : options.plugins);
172
+
173
+ if (options !== null && options !== void 0 && options.beforeUsePlugins) {
174
+ plugins = options.beforeUsePlugins(plugins, loaded.config);
175
+ }
176
+
171
177
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
172
178
  const appContext = (0, _context.initAppContext)(appDirectory, plugins, loaded.filePath);
173
179
  manager.run(() => {
@@ -192,7 +198,12 @@ const createCli = () => {
192
198
  });
193
199
  const extraConfigs = await hooksRunner.config();
194
200
  const extraSchemas = await hooksRunner.validateSchema();
195
- const resolved = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, isRestart, argv); // update context value
201
+ const config = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, isRestart, argv);
202
+ const {
203
+ resolved
204
+ } = await hooksRunner.resolvedConfig({
205
+ resolved: config
206
+ }); // update context value
196
207
 
197
208
  manager.run(() => {
198
209
  _context.ConfigContext.set(loaded.config);
@@ -212,12 +223,12 @@ const createCli = () => {
212
223
  };
213
224
  };
214
225
 
215
- async function run(argv) {
226
+ async function run(argv, options) {
216
227
  const {
217
228
  loadedConfig,
218
229
  appContext,
219
230
  resolved
220
- } = await init(argv);
231
+ } = await init(argv, options);
221
232
  await hooksRunner.commands({
222
233
  program: _commander.program
223
234
  });
@@ -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,4 +1,5 @@
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
5
  import { defineConfig, UserConfig, ToolsConfig } from './config';
@@ -10,6 +11,9 @@ 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<{
@@ -74,15 +90,20 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
74
90
  export declare const usePlugins: (plugins: string[]) => void;
75
91
  export { defineConfig, AppContext, useAppContext, useConfigContext, useResolvedConfigContext };
76
92
  export type { NormalizedConfig, IAppContext, UserConfig, ToolsConfig };
77
- export interface CoreOption {
78
- dryRun?: boolean;
93
+ export interface CoreOptions {
94
+ configFile?: string;
95
+ plugins?: typeof INTERNAL_PLUGINS;
96
+ beforeUsePlugins: (plugins: any, config: any) => {
97
+ cli: any;
98
+ server: any;
99
+ }[];
79
100
  }
80
101
  export declare const cli: {
81
- init: (argv?: string[]) => Promise<{
102
+ init: (argv?: string[], options?: CoreOptions | undefined) => Promise<{
82
103
  loadedConfig: import("./config").LoadedConfig;
83
104
  appContext: IAppContext;
84
105
  resolved: NormalizedConfig;
85
106
  }>;
86
- run: (argv: string[]) => Promise<void>;
107
+ run: (argv: string[], options?: CoreOptions | undefined) => Promise<void>;
87
108
  restart: () => Promise<void>;
88
109
  };
@@ -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": "0.0.0-canary-2021101982333",
14
+ "version": "0.0.0-options-202112031520",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -35,12 +35,20 @@
35
35
  }
36
36
  },
37
37
  "bin": "./bin/modern-js.js",
38
+ "scripts": {
39
+ "prepare": "pnpm build",
40
+ "prepublishOnly": "pnpm build -- --platform",
41
+ "new": "modern new",
42
+ "build": "modern build",
43
+ "dev": "modern build --watch",
44
+ "test": "modern test --passWithNoTests"
45
+ },
38
46
  "dependencies": {
39
47
  "@babel/code-frame": "^7.14.5",
40
48
  "@babel/runtime": "^7",
41
- "@modern-js/load-config": "^1.1.0",
42
- "@modern-js/plugin": "^0.0.0-canary-2021101982333",
43
- "@modern-js/utils": "^1.1.0",
49
+ "@modern-js/load-config": "^1.1.1",
50
+ "@modern-js/plugin": "^1.1.2",
51
+ "@modern-js/utils": "^1.1.2",
44
52
  "address": "^1.1.2",
45
53
  "ajv": "^8.6.2",
46
54
  "ajv-keywords": "^5.0.0",
@@ -57,7 +65,7 @@
57
65
  },
58
66
  "devDependencies": {
59
67
  "@types/babel__code-frame": "^7.0.3",
60
- "@modern-js/types": "^1.1.0",
68
+ "@modern-js/types": "^1.1.2",
61
69
  "@types/jest": "^26",
62
70
  "@types/lodash.clonedeep": "^4.5.6",
63
71
  "@types/lodash.mergewith": "^4.6.6",
@@ -66,8 +74,8 @@
66
74
  "@types/react-dom": "^17",
67
75
  "@types/signale": "^1.4.2",
68
76
  "typescript": "^4",
69
- "@modern-js/plugin-testing": "^1.1.0",
70
- "@modern-js/module-tools": "^1.1.0"
77
+ "@modern-js/plugin-testing": "^1.1.1",
78
+ "@modern-js/module-tools": "^1.1.1"
71
79
  },
72
80
  "sideEffects": false,
73
81
  "modernConfig": {
@@ -78,11 +86,5 @@
78
86
  "publishConfig": {
79
87
  "registry": "https://registry.npmjs.org/",
80
88
  "access": "public"
81
- },
82
- "scripts": {
83
- "new": "modern new",
84
- "build": "modern build",
85
- "dev": "modern build --watch",
86
- "test": "modern test --passWithNoTests"
87
89
  }
88
- }
90
+ }
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
 
@@ -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>(),
@@ -129,15 +138,17 @@ const initAppDir = async (): Promise<string> => {
129
138
  return path.dirname(pkg);
130
139
  };
131
140
 
132
- export interface CoreOption {
133
- dryRun?: boolean;
141
+ export interface CoreOptions {
142
+ configFile?: string;
143
+ plugins?: typeof INTERNAL_PLUGINS;
144
+ beforeUsePlugins: (plugins: any, config: any) => { cli: any; server: any }[];
134
145
  }
135
146
 
136
147
  const createCli = () => {
137
148
  let hooksRunner: HooksRunner;
138
149
  let isRestart = false;
139
150
 
140
- const init = async (argv: string[] = []) => {
151
+ const init = async (argv: string[] = [], options?: CoreOptions) => {
141
152
  enable();
142
153
 
143
154
  manager.clear();
@@ -146,9 +157,17 @@ const createCli = () => {
146
157
 
147
158
  loadEnv(appDirectory);
148
159
 
149
- const loaded = await loadUserConfig(appDirectory);
160
+ const loaded = await loadUserConfig(appDirectory, options?.configFile);
150
161
 
151
- const plugins = loadPlugins(appDirectory, loaded.config.plugins || []);
162
+ let plugins = loadPlugins(
163
+ appDirectory,
164
+ loaded.config.plugins || [],
165
+ options?.plugins,
166
+ );
167
+
168
+ if (options?.beforeUsePlugins) {
169
+ plugins = options.beforeUsePlugins(plugins, loaded.config);
170
+ }
152
171
 
153
172
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
154
173
 
@@ -180,7 +199,7 @@ const createCli = () => {
180
199
 
181
200
  const extraSchemas = await hooksRunner.validateSchema();
182
201
 
183
- const resolved = await resolveConfig(
202
+ const config = await resolveConfig(
184
203
  loaded,
185
204
  extraConfigs as any,
186
205
  extraSchemas as any,
@@ -188,6 +207,10 @@ const createCli = () => {
188
207
  argv,
189
208
  );
190
209
 
210
+ const { resolved } = await hooksRunner.resolvedConfig({
211
+ resolved: config,
212
+ });
213
+
191
214
  // update context value
192
215
  manager.run(() => {
193
216
  ConfigContext.set(loaded.config);
@@ -204,8 +227,8 @@ const createCli = () => {
204
227
  return { loadedConfig: loaded, appContext, resolved };
205
228
  };
206
229
 
207
- async function run(argv: string[]) {
208
- const { loadedConfig, appContext, resolved } = await init(argv);
230
+ async function run(argv: string[], options?: CoreOptions) {
231
+ const { loadedConfig, appContext, resolved } = await init(argv, options);
209
232
 
210
233
  await hooksRunner.commands({ program });
211
234
 
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
 
@@ -26,7 +26,7 @@ describe('load environment variables', () => {
26
26
 
27
27
  afterAll(() => {
28
28
  process.env = { ...defaultEnv };
29
- fs.rmSync(fixture, {force: true, recursive: true})
29
+ fs.rmSync(fixture, { force: true, recursive: true });
30
30
  });
31
31
 
32
32
  test(`support .env file`, () => {
@@ -78,6 +78,52 @@ describe('load environment variables', () => {
78
78
  delete process.env.NODE_ENV;
79
79
  });
80
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
+
81
127
  test(`support dotenv-expand`, () => {
82
128
  createFixtures('expand', [
83
129
  {