@modern-js/core 0.0.0-bundle-deps-2021101244657 → 0.0.0-options-202112031434

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,27 @@
1
1
  # @modern-js/core
2
2
 
3
- ## 0.0.0-bundle-deps-2021101244657
3
+ ## 1.1.2
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - test
8
- - Updated dependencies [undefined]
9
- - @modern-js/load-config@0.0.0-bundle-deps-2021101244657
10
- - @modern-js/utils@0.0.0-bundle-deps-2021101244657
11
- - @modern-js/plugin@0.0.0-bundle-deps-2021101244657
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
20
+ feat: add eslint generator
21
+ - Updated dependencies [c0fc0700]
22
+ - Updated dependencies [6ffd1a50]
23
+ - @modern-js/utils@1.1.1
24
+ - @modern-js/plugin@1.1.1
12
25
 
13
26
  ## 1.1.0
14
27
 
@@ -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);
@@ -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(),
@@ -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
63
  const loaded = await loadUserConfig(appDirectory);
63
- const plugins = loadPlugins(appDirectory, loaded.config.plugins || []);
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,
@@ -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
 
@@ -12,6 +12,7 @@ var _exportNames = {
12
12
  cli: true,
13
13
  defineConfig: true,
14
14
  defaultsConfig: true,
15
+ mergeConfig: true,
15
16
  AppContext: true,
16
17
  useAppContext: true,
17
18
  useConfigContext: true,
@@ -36,7 +37,14 @@ Object.defineProperty(exports, "defineConfig", {
36
37
  return _config.defineConfig;
37
38
  }
38
39
  });
39
- exports.registerHook = exports.mountHook = exports.manager = void 0;
40
+ exports.manager = void 0;
41
+ Object.defineProperty(exports, "mergeConfig", {
42
+ enumerable: true,
43
+ get: function () {
44
+ return _config.mergeConfig;
45
+ }
46
+ });
47
+ exports.registerHook = exports.mountHook = void 0;
40
48
  Object.defineProperty(exports, "useAppContext", {
41
49
  enumerable: true,
42
50
  get: function () {
@@ -113,6 +121,7 @@ _commander.program.name('modern').usage('<command> [options]').version(process.e
113
121
 
114
122
  const hooksMap = {
115
123
  config: (0, _plugin.createParallelWorkflow)(),
124
+ resolvedConfig: (0, _plugin.createAsyncWaterfall)(),
116
125
  validateSchema: (0, _plugin.createParallelWorkflow)(),
117
126
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
118
127
  prepare: (0, _plugin.createAsyncWorkflow)(),
@@ -153,13 +162,18 @@ const createCli = () => {
153
162
  let hooksRunner;
154
163
  let isRestart = false;
155
164
 
156
- const init = async (argv = []) => {
165
+ const init = async (argv = [], options) => {
157
166
  (0, _node.enable)();
158
167
  manager.clear();
159
168
  const appDirectory = await initAppDir();
160
169
  (0, _loadEnv.loadEnv)(appDirectory);
161
170
  const loaded = await (0, _config.loadUserConfig)(appDirectory);
162
- const plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || []);
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
+
163
177
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
164
178
  const appContext = (0, _context.initAppContext)(appDirectory, plugins, loaded.filePath);
165
179
  manager.run(() => {
@@ -184,7 +198,12 @@ const createCli = () => {
184
198
  });
185
199
  const extraConfigs = await hooksRunner.config();
186
200
  const extraSchemas = await hooksRunner.validateSchema();
187
- 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
188
207
 
189
208
  manager.run(() => {
190
209
  _context.ConfigContext.set(loaded.config);
@@ -204,12 +223,12 @@ const createCli = () => {
204
223
  };
205
224
  };
206
225
 
207
- async function run(argv) {
226
+ async function run(argv, options) {
208
227
  const {
209
228
  loadedConfig,
210
229
  appContext,
211
230
  resolved
212
- } = await init(argv);
231
+ } = await init(argv, options);
213
232
  await hooksRunner.commands({
214
233
  program: _commander.program
215
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,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;
@@ -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
5
  import { defineConfig, UserConfig, ToolsConfig } from './config';
5
6
  import { AppContext, IAppContext, 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<{
@@ -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
+ name?: 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-bundle-deps-2021101244657",
14
+ "version": "0.0.0-options-202112031434",
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": "0.0.0-bundle-deps-2021101244657",
42
- "@modern-js/plugin": "0.0.0-bundle-deps-2021101244657",
43
- "@modern-js/utils": "0.0.0-bundle-deps-2021101244657",
49
+ "@modern-js/load-config": "workspace:^1.1.1",
50
+ "@modern-js/plugin": "workspace:^1.1.2",
51
+ "@modern-js/utils": "workspace:^1.1.2",
44
52
  "address": "^1.1.2",
45
53
  "ajv": "^8.6.2",
46
54
  "ajv-keywords": "^5.0.0",
@@ -53,12 +61,11 @@
53
61
  "lodash.mergewith": "^4.6.2",
54
62
  "minimist": "^1.2.5",
55
63
  "signale": "^1.4.0",
56
- "v8-compile-cache": "^2.3.0",
57
- "esbuild": "^0.13.12"
64
+ "v8-compile-cache": "^2.3.0"
58
65
  },
59
66
  "devDependencies": {
60
67
  "@types/babel__code-frame": "^7.0.3",
61
- "@modern-js/types": "0.0.0-bundle-deps-2021101244657",
68
+ "@modern-js/types": "workspace:^1.1.2",
62
69
  "@types/jest": "^26",
63
70
  "@types/lodash.clonedeep": "^4.5.6",
64
71
  "@types/lodash.mergewith": "^4.6.6",
@@ -67,8 +74,8 @@
67
74
  "@types/react-dom": "^17",
68
75
  "@types/signale": "^1.4.2",
69
76
  "typescript": "^4",
70
- "@modern-js/plugin-testing": "^0.0.0-bundle-deps-2021101244657",
71
- "@modern-js/module-tools": "^0.0.0-bundle-deps-2021101244657"
77
+ "@modern-js/plugin-testing": "^1.1.1",
78
+ "@modern-js/module-tools": "^1.1.1"
72
79
  },
73
80
  "sideEffects": false,
74
81
  "modernConfig": {
@@ -79,11 +86,5 @@
79
86
  "publishConfig": {
80
87
  "registry": "https://registry.npmjs.org/",
81
88
  "access": "public"
82
- },
83
- "scripts": {
84
- "new": "modern new",
85
- "build": "modern build",
86
- "dev": "modern build --watch",
87
- "test": "modern test --passWithNoTests"
88
89
  }
89
- }
90
+ }
@@ -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<
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>(),
@@ -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
+ name?: 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();
@@ -148,7 +159,15 @@ const createCli = () => {
148
159
 
149
160
  const loaded = await loadUserConfig(appDirectory);
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
  {