@modern-js/core 1.1.1 → 1.1.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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @modern-js/core
2
2
 
3
+ ## 1.1.2
4
+
5
+ ### Patch Changes
6
+
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
+
3
15
  ## 1.1.1
4
16
 
5
17
  ### Patch Changes
@@ -54,13 +54,18 @@ const createCli = () => {
54
54
  let hooksRunner;
55
55
  let isRestart = false;
56
56
 
57
- const init = async (argv = []) => {
57
+ const init = async (argv = [], options) => {
58
58
  enable();
59
59
  manager.clear();
60
60
  const appDirectory = await initAppDir();
61
61
  loadEnv(appDirectory);
62
62
  const loaded = await loadUserConfig(appDirectory);
63
- const plugins = loadPlugins(appDirectory, loaded.config.plugins || []);
63
+ let plugins = loadPlugins(appDirectory, loaded.config.plugins || []);
64
+
65
+ if (options !== null && options !== void 0 && options.beforeUsePlugins) {
66
+ plugins = options.beforeUsePlugins(plugins, loaded.config);
67
+ }
68
+
64
69
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
65
70
  const appContext = initAppContext(appDirectory, plugins, loaded.filePath);
66
71
  manager.run(() => {
@@ -102,12 +107,12 @@ const createCli = () => {
102
107
  };
103
108
  };
104
109
 
105
- async function run(argv) {
110
+ async function run(argv, options) {
106
111
  const {
107
112
  loadedConfig,
108
113
  appContext,
109
114
  resolved
110
- } = await init(argv);
115
+ } = await init(argv, options);
111
116
  await hooksRunner.commands({
112
117
  program
113
118
  });
@@ -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,
@@ -161,13 +161,18 @@ const createCli = () => {
161
161
  let hooksRunner;
162
162
  let isRestart = false;
163
163
 
164
- const init = async (argv = []) => {
164
+ const init = async (argv = [], options) => {
165
165
  (0, _node.enable)();
166
166
  manager.clear();
167
167
  const appDirectory = await initAppDir();
168
168
  (0, _loadEnv.loadEnv)(appDirectory);
169
169
  const loaded = await (0, _config.loadUserConfig)(appDirectory);
170
- const plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || []);
170
+ let plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || []);
171
+
172
+ if (options !== null && options !== void 0 && options.beforeUsePlugins) {
173
+ plugins = options.beforeUsePlugins(plugins, loaded.config);
174
+ }
175
+
171
176
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
172
177
  const appContext = (0, _context.initAppContext)(appDirectory, plugins, loaded.filePath);
173
178
  manager.run(() => {
@@ -212,12 +217,12 @@ const createCli = () => {
212
217
  };
213
218
  };
214
219
 
215
- async function run(argv) {
220
+ async function run(argv, options) {
216
221
  const {
217
222
  loadedConfig,
218
223
  appContext,
219
224
  resolved
220
- } = await init(argv);
225
+ } = await init(argv, options);
221
226
  await hooksRunner.commands({
222
227
  program: _commander.program
223
228
  });
@@ -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,3 +1,4 @@
1
+ import { INTERNAL_PLUGINS } from '@modern-js/utils';
1
2
  import { ParallelWorkflow, AsyncWorkflow, Progresses2Runners } from '@modern-js/plugin';
2
3
  import type { Hooks } from '@modern-js/types';
3
4
  import { Command } from './utils/commander';
@@ -74,15 +75,20 @@ export declare const createPlugin: (initializer: import("@modern-js/plugin").Asy
74
75
  export declare const usePlugins: (plugins: string[]) => void;
75
76
  export { defineConfig, AppContext, useAppContext, useConfigContext, useResolvedConfigContext };
76
77
  export type { NormalizedConfig, IAppContext, UserConfig, ToolsConfig };
77
- export interface CoreOption {
78
- dryRun?: boolean;
78
+ export interface CoreOptions {
79
+ name?: string;
80
+ plugins?: typeof INTERNAL_PLUGINS;
81
+ beforeUsePlugins: (plugins: any, config: any) => {
82
+ cli: any;
83
+ server: any;
84
+ }[];
79
85
  }
80
86
  export declare const cli: {
81
- init: (argv?: string[]) => Promise<{
87
+ init: (argv?: string[], options?: CoreOptions | undefined) => Promise<{
82
88
  loadedConfig: import("./config").LoadedConfig;
83
89
  appContext: IAppContext;
84
90
  resolved: NormalizedConfig;
85
91
  }>;
86
- run: (argv: string[]) => Promise<void>;
92
+ run: (argv: string[], options?: CoreOptions | undefined) => Promise<void>;
87
93
  restart: () => Promise<void>;
88
94
  };
@@ -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.1.1",
14
+ "version": "1.1.2",
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.1.0",
42
- "@modern-js/plugin": "^1.1.1",
43
- "@modern-js/utils": "^1.1.1",
41
+ "@modern-js/load-config": "^1.1.1",
42
+ "@modern-js/plugin": "^1.1.2",
43
+ "@modern-js/utils": "^1.1.2",
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.1.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",
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,
@@ -129,15 +130,17 @@ const initAppDir = async (): Promise<string> => {
129
130
  return path.dirname(pkg);
130
131
  };
131
132
 
132
- export interface CoreOption {
133
- dryRun?: boolean;
133
+ export interface CoreOptions {
134
+ name?: string;
135
+ plugins?: typeof INTERNAL_PLUGINS;
136
+ beforeUsePlugins: (plugins: any, config: any) => { cli: any; server: any }[];
134
137
  }
135
138
 
136
139
  const createCli = () => {
137
140
  let hooksRunner: HooksRunner;
138
141
  let isRestart = false;
139
142
 
140
- const init = async (argv: string[] = []) => {
143
+ const init = async (argv: string[] = [], options?: CoreOptions) => {
141
144
  enable();
142
145
 
143
146
  manager.clear();
@@ -148,7 +151,11 @@ const createCli = () => {
148
151
 
149
152
  const loaded = await loadUserConfig(appDirectory);
150
153
 
151
- const plugins = loadPlugins(appDirectory, loaded.config.plugins || []);
154
+ let plugins = loadPlugins(appDirectory, loaded.config.plugins || []);
155
+
156
+ if (options?.beforeUsePlugins) {
157
+ plugins = options.beforeUsePlugins(plugins, loaded.config);
158
+ }
152
159
 
153
160
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
154
161
 
@@ -204,8 +211,8 @@ const createCli = () => {
204
211
  return { loadedConfig: loaded, appContext, resolved };
205
212
  };
206
213
 
207
- async function run(argv: string[]) {
208
- const { loadedConfig, appContext, resolved } = await init(argv);
214
+ async function run(argv: string[], options?: CoreOptions) {
215
+ const { loadedConfig, appContext, resolved } = await init(argv, options);
209
216
 
210
217
  await hooksRunner.commands({ program });
211
218
 
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
  {