@modern-js/core 1.4.1 → 1.4.4

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,37 @@
1
1
  # @modern-js/core
2
2
 
3
+ ## 1.4.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 969f172f: support tools.styledComponents for module-tools,support close tsc process with disbaleTsChecker
8
+ - 4b5d4bf4: fix: output.copy type
9
+ - 62f5b8c8: fix: types
10
+ - 55e18278: chore: remove unused dependencies and devDependencies
11
+ - 4499a674: feat: support to pass options to plugins
12
+ - 403f5169: fix source.moduleScopes type
13
+ - Updated dependencies [4c792f68]
14
+ - Updated dependencies [55e18278]
15
+ - Updated dependencies [a7f42f48]
16
+ - @modern-js/utils@1.3.3
17
+ - @modern-js/load-config@1.2.2
18
+
19
+ ## 1.4.3
20
+
21
+ ### Patch Changes
22
+
23
+ - 54786e58: add ts check
24
+ - Updated dependencies [deeaa602]
25
+ - @modern-js/utils@1.3.2
26
+
27
+ ## 1.4.2
28
+
29
+ ### Patch Changes
30
+
31
+ - b376c8d6: feat: enhance custom env
32
+ - e62c4efd: fix error typo for 'styledComponents'
33
+ - e2a8233f: support add schem error hook to core.init
34
+
3
35
  ## 1.4.1
4
36
 
5
37
  ### Patch Changes
@@ -33,8 +33,8 @@ export const loadUserConfig = async (appDirectory, filePath, packageJsonConfig)
33
33
  };
34
34
 
35
35
  const showAdditionalPropertiesError = error => {
36
- if (error.keyword === 'additionalProperties' && error.instancePath && error.params.additionalProperty) {
37
- const target = `${error.instancePath.substr(1)}.${error.params.additionalProperty}`;
36
+ if (error.keyword === 'additionalProperties' && error.params.additionalProperty) {
37
+ const target = [error.instancePath.slice(1), error.params.additionalProperty].filter(Boolean).join('.');
38
38
  const name = Object.keys(PLUGIN_SCHEMAS).find(key => PLUGIN_SCHEMAS[key].some(schemaItem => schemaItem.target === target));
39
39
 
40
40
  if (name) {
@@ -45,7 +45,7 @@ const showAdditionalPropertiesError = error => {
45
45
  /* eslint-disable max-statements, max-params */
46
46
 
47
47
 
48
- export const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort, argv) => {
48
+ export const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort, argv, onSchemaError = showAdditionalPropertiesError) => {
49
49
  var _validate$errors;
50
50
 
51
51
  const {
@@ -67,7 +67,7 @@ export const resolveConfig = async (loaded, configs, schemas, restartWithExistin
67
67
  if (!valid && (_validate$errors = validate.errors) !== null && _validate$errors !== void 0 && _validate$errors.length) {
68
68
  var _validate$errors2;
69
69
 
70
- showAdditionalPropertiesError(validate === null || validate === void 0 ? void 0 : validate.errors[0]);
70
+ onSchemaError(validate === null || validate === void 0 ? void 0 : validate.errors[0]);
71
71
  const errors = betterAjvErrors(validateSchema, userConfig, (_validate$errors2 = validate.errors) === null || _validate$errors2 === void 0 ? void 0 : _validate$errors2.map(e => _objectSpread(_objectSpread({}, e), {}, {
72
72
  dataPath: e.instancePath
73
73
  })), {
@@ -74,6 +74,9 @@ export const output = {
74
74
  scriptExt: {
75
75
  type: 'object'
76
76
  },
77
+ disableTsChecker: {
78
+ type: 'boolean'
79
+ },
77
80
  disableHtmlFolder: {
78
81
  type: 'boolean'
79
82
  },
@@ -28,6 +28,9 @@ export const tools = {
28
28
  },
29
29
  minifyCss: {
30
30
  typeof: ['object', 'function']
31
+ },
32
+ styledComponents: {
33
+ typeof: ['object', 'function']
31
34
  }
32
35
  }
33
36
  };
@@ -62,21 +62,22 @@ const createCli = () => {
62
62
  let hooksRunner;
63
63
  let isRestart = false;
64
64
  let restartWithExistingPort = 0;
65
- let restartOptions; // eslint-disable-next-line max-statements
65
+ let restartOptions;
66
66
 
67
67
  const init = async (argv = [], options) => {
68
+ var _options$options$meta, _options$options;
69
+
68
70
  enable();
69
71
  manager.clear();
70
72
  restartOptions = options;
71
73
  const appDirectory = await initAppDir();
72
- loadEnv(appDirectory);
74
+ const metaName = (_options$options$meta = options === null || options === void 0 ? void 0 : (_options$options = options.options) === null || _options$options === void 0 ? void 0 : _options$options.metaName) !== null && _options$options$meta !== void 0 ? _options$options$meta : 'MODERN';
75
+ loadEnv(appDirectory, process.env[`${metaName.toUpperCase()}_ENV`]);
73
76
  const loaded = await loadUserConfig(appDirectory, options === null || options === void 0 ? void 0 : options.configFile, options === null || options === void 0 ? void 0 : options.packageJsonConfig);
74
- let plugins = loadPlugins(appDirectory, loaded.config.plugins || [], options === null || options === void 0 ? void 0 : options.plugins);
75
-
76
- if (options !== null && options !== void 0 && options.beforeUsePlugins) {
77
- plugins = options.beforeUsePlugins(plugins, loaded.config);
78
- }
79
-
77
+ const plugins = loadPlugins(appDirectory, loaded.config, {
78
+ internalPlugins: options === null || options === void 0 ? void 0 : options.plugins,
79
+ transformPlugin: options === null || options === void 0 ? void 0 : options.transformPlugin
80
+ });
80
81
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
81
82
  const appContext = initAppContext(appDirectory, plugins, loaded.filePath, options === null || options === void 0 ? void 0 : options.options);
82
83
  manager.run(() => {
@@ -100,7 +101,7 @@ const createCli = () => {
100
101
  });
101
102
  const extraConfigs = await hooksRunner.config();
102
103
  const extraSchemas = await hooksRunner.validateSchema();
103
- const config = await resolveConfig(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv);
104
+ const config = await resolveConfig(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv, options === null || options === void 0 ? void 0 : options.onSchemaError);
104
105
  const {
105
106
  resolved
106
107
  } = await hooksRunner.resolvedConfig({
@@ -9,41 +9,27 @@ const debug = createDebugger('load-plugins');
9
9
 
10
10
  /**
11
11
  * Try to resolve plugin entry file path.
12
+ * @param name - Plugin name.
12
13
  * @param appDirectory - Application root directory.
13
- * @param plugin - Plugin name or plugin name with options.
14
14
  * @returns Resolved file path.
15
15
  */
16
- const resolvePlugin = (appDirectory, plugin) => {
17
- const tryResolve = name => {
18
- let filePath = '';
16
+ const tryResolve = (name, appDirectory) => {
17
+ let filePath = '';
19
18
 
20
- try {
21
- filePath = require.resolve(name, {
22
- paths: [appDirectory]
23
- });
24
- delete require.cache[filePath];
25
- } catch (err) {
26
- if (err.code === 'MODULE_NOT_FOUND') {
27
- throw new Error(`Can not find plugin ${name}.`);
28
- }
29
-
30
- throw err;
19
+ try {
20
+ filePath = require.resolve(name, {
21
+ paths: [appDirectory]
22
+ });
23
+ delete require.cache[filePath];
24
+ } catch (err) {
25
+ if (err.code === 'MODULE_NOT_FOUND') {
26
+ throw new Error(`Can not find plugin ${name}.`);
31
27
  }
32
28
 
33
- return filePath;
34
- };
35
-
36
- const resolved = {};
37
-
38
- if (typeof plugin === 'string' || plugin.cli) {
39
- resolved.cli = typeof plugin === 'string' ? tryResolve(plugin) : tryResolve(plugin.cli);
29
+ throw err;
40
30
  }
41
31
 
42
- if (plugin.server) {
43
- resolved.server = tryResolve(plugin.server);
44
- }
45
-
46
- return resolved;
32
+ return filePath;
47
33
  };
48
34
 
49
35
  export function getAppPlugins(appDirectory, pluginConfig, internalPlugins) {
@@ -63,36 +49,74 @@ export function getAppPlugins(appDirectory, pluginConfig, internalPlugins) {
63
49
  /**
64
50
  * Load internal plugins which in @modern-js scope and user's custom plugins.
65
51
  * @param appDirectory - Application root directory.
66
- * @param pluginsConfig - Plugins declared in the user configuration.
52
+ * @param userConfig - Resolved user config.
53
+ * @param options.internalPlugins - Internal plugins.
54
+ * @param options.transformPlugin - transform plugin before using it.
67
55
  * @returns Plugin Objects has been required.
68
56
  */
69
57
 
70
- export const loadPlugins = (appDirectory, pluginConfig, internalPlugins) => {
71
- const plugins = getAppPlugins(appDirectory, pluginConfig, internalPlugins);
58
+ export const loadPlugins = (appDirectory, userConfig, options = {}) => {
59
+ const {
60
+ internalPlugins,
61
+ transformPlugin
62
+ } = options;
63
+
64
+ const resolvePlugin = p => {
65
+ const pkg = typeof p === 'string' ? p : p[0];
66
+ const path = tryResolve(pkg, appDirectory);
67
+ let module = compatRequire(path);
68
+ const pluginOptions = Array.isArray(p) ? p[1] : undefined;
69
+
70
+ if (transformPlugin) {
71
+ module = transformPlugin(module, userConfig, pluginOptions);
72
+ } else {
73
+ module = typeof module === 'function' ? module(pluginOptions) : module;
74
+ }
75
+
76
+ return {
77
+ pkg,
78
+ path,
79
+ module
80
+ };
81
+ };
82
+
83
+ const plugins = getAppPlugins(appDirectory, userConfig.plugins || [], internalPlugins);
72
84
  return plugins.map(plugin => {
85
+ const _plugin = typeof plugin === 'string' ? {
86
+ cli: plugin
87
+ } : plugin;
88
+
73
89
  const {
74
90
  cli,
75
91
  server
76
- } = resolvePlugin(appDirectory, plugin);
77
- debug(`resolve plugin %s: %s`, plugin, {
78
- cli,
79
- server
80
- });
92
+ } = _plugin;
93
+ const loadedPlugin = {};
94
+
95
+ if (cli) {
96
+ const {
97
+ pkg,
98
+ path,
99
+ module
100
+ } = resolvePlugin(cli);
101
+ loadedPlugin.cli = _objectSpread(_objectSpread({}, module), {}, {
102
+ pluginPath: path
103
+ });
104
+ loadedPlugin.cliPkg = pkg;
105
+ } // server plugins don't support to accept params
81
106
 
82
- const cliPlugin = cli && _objectSpread(_objectSpread({}, compatRequire(cli)), {}, {
83
- pluginPath: cli
84
- }); // server plugin should be required by server
85
107
 
108
+ if (server && typeof server === 'string') {
109
+ const path = tryResolve(server, appDirectory);
110
+ loadedPlugin.server = {
111
+ pluginPath: path
112
+ };
113
+ loadedPlugin.serverPkg = server;
114
+ }
86
115
 
87
- const serverPlugin = server && {
88
- // ...compatRequire(server),
89
- pluginPath: server
90
- };
91
- return {
92
- cli: cliPlugin,
93
- cliPath: typeof plugin === 'string' ? plugin : plugin.cli,
94
- server: serverPlugin,
95
- serverPath: typeof plugin === 'string' ? undefined : plugin.server
96
- };
116
+ debug(`resolve plugin %s: %s`, plugin, {
117
+ cli: loadedPlugin.cli,
118
+ server: loadedPlugin.server
119
+ });
120
+ return loadedPlugin;
97
121
  });
98
122
  };
@@ -71,8 +71,8 @@ const loadUserConfig = async (appDirectory, filePath, packageJsonConfig) => {
71
71
  exports.loadUserConfig = loadUserConfig;
72
72
 
73
73
  const showAdditionalPropertiesError = error => {
74
- if (error.keyword === 'additionalProperties' && error.instancePath && error.params.additionalProperty) {
75
- const target = `${error.instancePath.substr(1)}.${error.params.additionalProperty}`;
74
+ if (error.keyword === 'additionalProperties' && error.params.additionalProperty) {
75
+ const target = [error.instancePath.slice(1), error.params.additionalProperty].filter(Boolean).join('.');
76
76
  const name = Object.keys(_utils.PLUGIN_SCHEMAS).find(key => _utils.PLUGIN_SCHEMAS[key].some(schemaItem => schemaItem.target === target));
77
77
 
78
78
  if (name) {
@@ -83,7 +83,7 @@ const showAdditionalPropertiesError = error => {
83
83
  /* eslint-disable max-statements, max-params */
84
84
 
85
85
 
86
- const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort, argv) => {
86
+ const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort, argv, onSchemaError = showAdditionalPropertiesError) => {
87
87
  var _validate$errors;
88
88
 
89
89
  const {
@@ -105,7 +105,7 @@ const resolveConfig = async (loaded, configs, schemas, restartWithExistingPort,
105
105
  if (!valid && (_validate$errors = validate.errors) !== null && _validate$errors !== void 0 && _validate$errors.length) {
106
106
  var _validate$errors2;
107
107
 
108
- showAdditionalPropertiesError(validate === null || validate === void 0 ? void 0 : validate.errors[0]);
108
+ onSchemaError(validate === null || validate === void 0 ? void 0 : validate.errors[0]);
109
109
  const errors = (0, _betterAjvErrors.default)(validateSchema, userConfig, (_validate$errors2 = validate.errors) === null || _validate$errors2 === void 0 ? void 0 : _validate$errors2.map(e => _objectSpread(_objectSpread({}, e), {}, {
110
110
  dataPath: e.instancePath
111
111
  })), {
@@ -82,6 +82,9 @@ const output = {
82
82
  scriptExt: {
83
83
  type: 'object'
84
84
  },
85
+ disableTsChecker: {
86
+ type: 'boolean'
87
+ },
85
88
  disableHtmlFolder: {
86
89
  type: 'boolean'
87
90
  },
@@ -34,6 +34,9 @@ const tools = {
34
34
  },
35
35
  minifyCss: {
36
36
  typeof: ['object', 'function']
37
+ },
38
+ styledComponents: {
39
+ typeof: ['object', 'function']
37
40
  }
38
41
  }
39
42
  };
@@ -183,21 +183,22 @@ const createCli = () => {
183
183
  let hooksRunner;
184
184
  let isRestart = false;
185
185
  let restartWithExistingPort = 0;
186
- let restartOptions; // eslint-disable-next-line max-statements
186
+ let restartOptions;
187
187
 
188
188
  const init = async (argv = [], options) => {
189
+ var _options$options$meta, _options$options;
190
+
189
191
  (0, _node.enable)();
190
192
  manager.clear();
191
193
  restartOptions = options;
192
194
  const appDirectory = await initAppDir();
193
- (0, _loadEnv.loadEnv)(appDirectory);
195
+ const metaName = (_options$options$meta = options === null || options === void 0 ? void 0 : (_options$options = options.options) === null || _options$options === void 0 ? void 0 : _options$options.metaName) !== null && _options$options$meta !== void 0 ? _options$options$meta : 'MODERN';
196
+ (0, _loadEnv.loadEnv)(appDirectory, process.env[`${metaName.toUpperCase()}_ENV`]);
194
197
  const loaded = await (0, _config.loadUserConfig)(appDirectory, options === null || options === void 0 ? void 0 : options.configFile, options === null || options === void 0 ? void 0 : options.packageJsonConfig);
195
- let plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config.plugins || [], options === null || options === void 0 ? void 0 : options.plugins);
196
-
197
- if (options !== null && options !== void 0 && options.beforeUsePlugins) {
198
- plugins = options.beforeUsePlugins(plugins, loaded.config);
199
- }
200
-
198
+ const plugins = (0, _loadPlugins.loadPlugins)(appDirectory, loaded.config, {
199
+ internalPlugins: options === null || options === void 0 ? void 0 : options.plugins,
200
+ transformPlugin: options === null || options === void 0 ? void 0 : options.transformPlugin
201
+ });
201
202
  plugins.forEach(plugin => plugin.cli && manager.usePlugin(plugin.cli));
202
203
  const appContext = (0, _context.initAppContext)(appDirectory, plugins, loaded.filePath, options === null || options === void 0 ? void 0 : options.options);
203
204
  manager.run(() => {
@@ -222,7 +223,7 @@ const createCli = () => {
222
223
  });
223
224
  const extraConfigs = await hooksRunner.config();
224
225
  const extraSchemas = await hooksRunner.validateSchema();
225
- const config = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv);
226
+ const config = await (0, _config.resolveConfig)(loaded, extraConfigs, extraSchemas, restartWithExistingPort, argv, options === null || options === void 0 ? void 0 : options.onSchemaError);
226
227
  const {
227
228
  resolved
228
229
  } = await hooksRunner.resolvedConfig({
@@ -18,41 +18,27 @@ const debug = (0, _utils.createDebugger)('load-plugins');
18
18
 
19
19
  /**
20
20
  * Try to resolve plugin entry file path.
21
+ * @param name - Plugin name.
21
22
  * @param appDirectory - Application root directory.
22
- * @param plugin - Plugin name or plugin name with options.
23
23
  * @returns Resolved file path.
24
24
  */
25
- const resolvePlugin = (appDirectory, plugin) => {
26
- const tryResolve = name => {
27
- let filePath = '';
25
+ const tryResolve = (name, appDirectory) => {
26
+ let filePath = '';
28
27
 
29
- try {
30
- filePath = require.resolve(name, {
31
- paths: [appDirectory]
32
- });
33
- delete require.cache[filePath];
34
- } catch (err) {
35
- if (err.code === 'MODULE_NOT_FOUND') {
36
- throw new Error(`Can not find plugin ${name}.`);
37
- }
38
-
39
- throw err;
28
+ try {
29
+ filePath = require.resolve(name, {
30
+ paths: [appDirectory]
31
+ });
32
+ delete require.cache[filePath];
33
+ } catch (err) {
34
+ if (err.code === 'MODULE_NOT_FOUND') {
35
+ throw new Error(`Can not find plugin ${name}.`);
40
36
  }
41
37
 
42
- return filePath;
43
- };
44
-
45
- const resolved = {};
46
-
47
- if (typeof plugin === 'string' || plugin.cli) {
48
- resolved.cli = typeof plugin === 'string' ? tryResolve(plugin) : tryResolve(plugin.cli);
49
- }
50
-
51
- if (plugin.server) {
52
- resolved.server = tryResolve(plugin.server);
38
+ throw err;
53
39
  }
54
40
 
55
- return resolved;
41
+ return filePath;
56
42
  };
57
43
 
58
44
  function getAppPlugins(appDirectory, pluginConfig, internalPlugins) {
@@ -72,38 +58,76 @@ function getAppPlugins(appDirectory, pluginConfig, internalPlugins) {
72
58
  /**
73
59
  * Load internal plugins which in @modern-js scope and user's custom plugins.
74
60
  * @param appDirectory - Application root directory.
75
- * @param pluginsConfig - Plugins declared in the user configuration.
61
+ * @param userConfig - Resolved user config.
62
+ * @param options.internalPlugins - Internal plugins.
63
+ * @param options.transformPlugin - transform plugin before using it.
76
64
  * @returns Plugin Objects has been required.
77
65
  */
78
66
 
79
67
 
80
- const loadPlugins = (appDirectory, pluginConfig, internalPlugins) => {
81
- const plugins = getAppPlugins(appDirectory, pluginConfig, internalPlugins);
68
+ const loadPlugins = (appDirectory, userConfig, options = {}) => {
69
+ const {
70
+ internalPlugins,
71
+ transformPlugin
72
+ } = options;
73
+
74
+ const resolvePlugin = p => {
75
+ const pkg = typeof p === 'string' ? p : p[0];
76
+ const path = tryResolve(pkg, appDirectory);
77
+ let module = (0, _utils.compatRequire)(path);
78
+ const pluginOptions = Array.isArray(p) ? p[1] : undefined;
79
+
80
+ if (transformPlugin) {
81
+ module = transformPlugin(module, userConfig, pluginOptions);
82
+ } else {
83
+ module = typeof module === 'function' ? module(pluginOptions) : module;
84
+ }
85
+
86
+ return {
87
+ pkg,
88
+ path,
89
+ module
90
+ };
91
+ };
92
+
93
+ const plugins = getAppPlugins(appDirectory, userConfig.plugins || [], internalPlugins);
82
94
  return plugins.map(plugin => {
95
+ const _plugin = typeof plugin === 'string' ? {
96
+ cli: plugin
97
+ } : plugin;
98
+
83
99
  const {
84
100
  cli,
85
101
  server
86
- } = resolvePlugin(appDirectory, plugin);
87
- debug(`resolve plugin %s: %s`, plugin, {
88
- cli,
89
- server
90
- });
102
+ } = _plugin;
103
+ const loadedPlugin = {};
104
+
105
+ if (cli) {
106
+ const {
107
+ pkg,
108
+ path,
109
+ module
110
+ } = resolvePlugin(cli);
111
+ loadedPlugin.cli = _objectSpread(_objectSpread({}, module), {}, {
112
+ pluginPath: path
113
+ });
114
+ loadedPlugin.cliPkg = pkg;
115
+ } // server plugins don't support to accept params
91
116
 
92
- const cliPlugin = cli && _objectSpread(_objectSpread({}, (0, _utils.compatRequire)(cli)), {}, {
93
- pluginPath: cli
94
- }); // server plugin should be required by server
95
117
 
118
+ if (server && typeof server === 'string') {
119
+ const path = tryResolve(server, appDirectory);
120
+ loadedPlugin.server = {
121
+ pluginPath: path
122
+ };
123
+ loadedPlugin.serverPkg = server;
124
+ }
96
125
 
97
- const serverPlugin = server && {
98
- // ...compatRequire(server),
99
- pluginPath: server
100
- };
101
- return {
102
- cli: cliPlugin,
103
- cliPath: typeof plugin === 'string' ? plugin : plugin.cli,
104
- server: serverPlugin,
105
- serverPath: typeof plugin === 'string' ? undefined : plugin.server
106
- };
126
+ debug(`resolve plugin %s: %s`, plugin, {
127
+ cli: loadedPlugin.cli,
128
+ server: loadedPlugin.server
129
+ });
130
+ return loadedPlugin;
107
131
  });
108
132
  };
109
133
 
@@ -1,3 +1,4 @@
1
+ import { ErrorObject } from 'ajv';
1
2
  import { MetaOptions } from '@modern-js/utils';
2
3
  import { PluginConfig } from '../loadPlugins';
3
4
  import { defaults } from './defaults';
@@ -18,7 +19,7 @@ interface SourceConfig {
18
19
  envVars?: Array<string>;
19
20
  globalVars?: Record<string, string>;
20
21
  alias?: Record<string, string> | ((aliases: Record<string, string>) => Record<string, unknown>);
21
- moduleScopes?: Array<string | RegExp> | ((scopes: Array<string | RegExp>) => Array<string | RegExp>);
22
+ moduleScopes?: Array<string | RegExp> | ((scopes: Array<string | RegExp>) => void) | ((scopes: Array<string | RegExp>) => Array<string | RegExp>);
22
23
  include?: Array<string | RegExp>;
23
24
  }
24
25
  interface OutputConfig {
@@ -37,8 +38,11 @@ interface OutputConfig {
37
38
  mountId?: string;
38
39
  favicon?: string;
39
40
  faviconByEntries?: Record<string, string | undefined>;
40
- copy?: Record<string, unknown>;
41
+ copy?: Array<Record<string, unknown> & {
42
+ from: string;
43
+ }>;
41
44
  scriptExt?: Record<string, unknown>;
45
+ disableTsChecker?: boolean;
42
46
  disableHtmlFolder?: boolean;
43
47
  disableCssModuleExtension?: boolean;
44
48
  disableCssExtract?: boolean;
@@ -96,6 +100,7 @@ interface ToolsConfig {
96
100
  babel?: ConfigFunction;
97
101
  autoprefixer?: ConfigFunction;
98
102
  postcss?: ConfigFunction;
103
+ styledComponents?: ConfigFunction;
99
104
  lodash?: ConfigFunction;
100
105
  devServer?: Record<string, unknown>;
101
106
  tsLoader?: ConfigFunction;
@@ -128,5 +133,5 @@ interface LoadedConfig {
128
133
  }
129
134
  export declare const defineConfig: (config: ConfigParam) => ConfigParam;
130
135
  export declare const loadUserConfig: (appDirectory: string, filePath?: string | undefined, packageJsonConfig?: string | undefined) => Promise<LoadedConfig>;
131
- export declare const resolveConfig: (loaded: LoadedConfig, configs: UserConfig[], schemas: PluginValidateSchema[], restartWithExistingPort: number, argv: string[]) => Promise<NormalizedConfig>;
136
+ export declare const resolveConfig: (loaded: LoadedConfig, configs: UserConfig[], schemas: PluginValidateSchema[], restartWithExistingPort: number, argv: string[], onSchemaError?: (error: ErrorObject) => void) => Promise<NormalizedConfig>;
132
137
  export type { SourceConfig, OutputConfig, ServerConfig, DevConfig, DeployConfig, ToolsConfig, RuntimeConfig, RuntimeByEntriesConfig, UserConfig, ConfigParam, LoadedConfig };
@@ -3,10 +3,11 @@ export interface NormalizedSourceConfig extends Omit<SourceConfig, 'alias' | 'mo
3
3
  alias: SourceConfig['alias'] | Array<SourceConfig['alias']>;
4
4
  moduleScopes: SourceConfig['moduleScopes'] | Array<SourceConfig['moduleScopes']>;
5
5
  }
6
- export interface NormalizedToolsConfig extends Omit<ToolsConfig, 'webpack' | 'babel' | 'postcss' | 'autoprefixer' | 'lodash' | 'tsLoader' | 'terser' | 'minifyCss' | 'esbuild'> {
6
+ export interface NormalizedToolsConfig extends Omit<ToolsConfig, 'webpack' | 'babel' | 'postcss' | 'autoprefixer' | 'lodash' | 'tsLoader' | 'terser' | 'minifyCss' | 'esbuild' | 'styledComponents'> {
7
7
  webpack: ToolsConfig['webpack'] | Array<NonNullable<ToolsConfig['webpack']>>;
8
8
  babel: ToolsConfig['babel'] | Array<NonNullable<ToolsConfig['babel']>>;
9
9
  postcss: ToolsConfig['postcss'] | Array<NonNullable<ToolsConfig['postcss']>>;
10
+ styledComponents: ToolsConfig['styledComponents'] | Array<NonNullable<ToolsConfig['styledComponents']>>;
10
11
  autoprefixer: ToolsConfig['autoprefixer'] | Array<NonNullable<ToolsConfig['autoprefixer']>>;
11
12
  lodash: ToolsConfig['lodash'] | Array<ToolsConfig['lodash']>;
12
13
  tsLoader: ToolsConfig['tsLoader'] | Array<NonNullable<ToolsConfig['tsLoader']>>;
@@ -140,6 +140,9 @@ export declare const patchSchema: (pluginSchemas: Array<PluginValidateSchema | P
140
140
  scriptExt: {
141
141
  type: string;
142
142
  };
143
+ disableTsChecker: {
144
+ type: string;
145
+ };
143
146
  disableHtmlFolder: {
144
147
  type: string;
145
148
  };
@@ -456,6 +459,9 @@ export declare const patchSchema: (pluginSchemas: Array<PluginValidateSchema | P
456
459
  minifyCss: {
457
460
  typeof: string[];
458
461
  };
462
+ styledComponents: {
463
+ typeof: string[];
464
+ };
459
465
  };
460
466
  };
461
467
  };
@@ -73,6 +73,9 @@ export declare const output: {
73
73
  scriptExt: {
74
74
  type: string;
75
75
  };
76
+ disableTsChecker: {
77
+ type: string;
78
+ };
76
79
  disableHtmlFolder: {
77
80
  type: string;
78
81
  };
@@ -29,5 +29,8 @@ export declare const tools: {
29
29
  minifyCss: {
30
30
  typeof: string[];
31
31
  };
32
+ styledComponents: {
33
+ typeof: string[];
34
+ };
32
35
  };
33
36
  };
@@ -1,6 +1,7 @@
1
1
  import type { IAppContext } from '@modern-js/types';
2
2
  import { UserConfig } from './config';
3
3
  import { NormalizedConfig } from './config/mergeConfig';
4
+ import type { LoadedPlugin } from './loadPlugins';
4
5
  export type { IAppContext };
5
6
  export declare const AppContext: import("@modern-js/plugin").Context<IAppContext>;
6
7
  export declare const ConfigContext: import("@modern-js/plugin").Context<UserConfig>;
@@ -8,10 +9,7 @@ export declare const ResolvedConfigContext: import("@modern-js/plugin").Context<
8
9
  export declare const useAppContext: () => IAppContext;
9
10
  export declare const useConfigContext: () => UserConfig;
10
11
  export declare const useResolvedConfigContext: () => NormalizedConfig;
11
- export declare const initAppContext: (appDirectory: string, plugins: Array<{
12
- cli: any;
13
- server: any;
14
- }>, configFile: string | false, options?: {
12
+ export declare const initAppContext: (appDirectory: string, plugins: Array<LoadedPlugin>, configFile: string | false, options?: {
15
13
  metaName?: string | undefined;
16
14
  srcDir?: string | undefined;
17
15
  distDir?: string | undefined;
@@ -1,7 +1,9 @@
1
1
  import { INTERNAL_PLUGINS } from '@modern-js/utils';
2
2
  import { ParallelWorkflow, AsyncWorkflow, Progresses2Runners, AsyncWaterfall } from '@modern-js/plugin';
3
3
  import type { Hooks } from '@modern-js/types';
4
+ import { ErrorObject } from 'ajv';
4
5
  import { Command } from './utils/commander';
6
+ import { TransformPlugin } from './loadPlugins';
5
7
  import { AppContext, ConfigContext, IAppContext, initAppContext, ResolvedConfigContext, useAppContext, useConfigContext, useResolvedConfigContext } from './context';
6
8
  import { NormalizedConfig } from './config/mergeConfig';
7
9
  export type { Hooks };
@@ -103,12 +105,8 @@ export interface CoreOptions {
103
105
  configFile?: string;
104
106
  packageJsonConfig?: string;
105
107
  plugins?: typeof INTERNAL_PLUGINS;
106
- beforeUsePlugins?: (plugins: any, config: any) => {
107
- cli: any;
108
- cliPath: any;
109
- server: any;
110
- serverPath: any;
111
- }[];
108
+ transformPlugin?: TransformPlugin;
109
+ onSchemaError?: (error: ErrorObject) => void;
112
110
  options?: {
113
111
  metaName?: string;
114
112
  srcDir?: string;
@@ -1,30 +1,30 @@
1
1
  import { INTERNAL_PLUGINS } from '@modern-js/utils';
2
- export interface PluginConfigItem {
3
- cli?: string;
4
- server?: string;
5
- }
2
+ import type { UserConfig } from './config';
3
+ declare type Plugin = string | [string, any];
4
+ export declare type LoadedPlugin = {
5
+ cli?: any;
6
+ cliPkg?: string;
7
+ server?: any;
8
+ serverPkg?: string;
9
+ };
10
+ export declare type PluginConfigItem = {
11
+ cli?: Plugin;
12
+ server?: Plugin;
13
+ } | string;
6
14
  export declare type PluginConfig = Array<PluginConfigItem>;
7
- export declare function getAppPlugins(appDirectory: string, pluginConfig: PluginConfig, internalPlugins?: typeof INTERNAL_PLUGINS): {
8
- cli?: string | undefined;
9
- server?: string | undefined;
10
- }[];
15
+ export declare type TransformPlugin = (plugin: PluginConfig, resolvedConfig: UserConfig, pluginOptions?: any) => PluginConfig;
16
+ export declare function getAppPlugins(appDirectory: string, pluginConfig: PluginConfig, internalPlugins?: typeof INTERNAL_PLUGINS): PluginConfigItem[];
11
17
  /**
12
18
  * Load internal plugins which in @modern-js scope and user's custom plugins.
13
19
  * @param appDirectory - Application root directory.
14
- * @param pluginsConfig - Plugins declared in the user configuration.
20
+ * @param userConfig - Resolved user config.
21
+ * @param options.internalPlugins - Internal plugins.
22
+ * @param options.transformPlugin - transform plugin before using it.
15
23
  * @returns Plugin Objects has been required.
16
24
  */
17
25
 
18
- export declare const loadPlugins: (appDirectory: string, pluginConfig: PluginConfig, internalPlugins?: {
19
- [name: string]: {
20
- cli?: string | undefined;
21
- server?: string | undefined;
22
- };
23
- } | undefined) => {
24
- cli: any;
25
- cliPath: string | undefined;
26
- server: "" | {
27
- pluginPath: string;
28
- } | undefined;
29
- serverPath: string | undefined;
30
- }[];
26
+ export declare const loadPlugins: (appDirectory: string, userConfig: UserConfig, options?: {
27
+ internalPlugins?: typeof INTERNAL_PLUGINS;
28
+ transformPlugin?: TransformPlugin;
29
+ }) => LoadedPlugin[];
30
+ export {};
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.4.1",
14
+ "version": "1.4.4",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -42,9 +42,9 @@
42
42
  "dependencies": {
43
43
  "@babel/code-frame": "^7.14.5",
44
44
  "@babel/runtime": "^7",
45
- "@modern-js/load-config": "^1.2.1",
45
+ "@modern-js/load-config": "^1.2.2",
46
46
  "@modern-js/plugin": "^1.2.1",
47
- "@modern-js/utils": "^1.3.1",
47
+ "@modern-js/utils": "^1.3.3",
48
48
  "address": "^1.1.2",
49
49
  "ajv": "^8.6.2",
50
50
  "ajv-keywords": "^5.0.0",
@@ -55,14 +55,13 @@
55
55
  "dotenv-expand": "^5.1.0",
56
56
  "lodash.clonedeep": "^4.5.0",
57
57
  "lodash.mergewith": "^4.6.2",
58
- "minimist": "^1.2.5",
59
58
  "signale": "^1.4.0",
60
59
  "v8-compile-cache": "^2.3.0"
61
60
  },
62
61
  "devDependencies": {
63
62
  "btsm": "2.2.2",
64
63
  "@types/babel__code-frame": "^7.0.3",
65
- "@modern-js/types": "^1.3.1",
64
+ "@modern-js/types": "^1.3.4",
66
65
  "@types/jest": "^26",
67
66
  "@types/lodash.clonedeep": "^4.5.6",
68
67
  "@types/lodash.mergewith": "^4.6.6",
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
3
+ exports.default = name => ({ name });
@@ -62,13 +62,8 @@ describe('@modern-js/core test', () => {
62
62
 
63
63
  it('test cli init dev', async () => {
64
64
  cwdSpy.mockReturnValue(path.join(cwd, 'nested-folder'));
65
- const options = {
66
- beforeUsePlugins: jest.fn(),
67
- };
68
- options.beforeUsePlugins.mockImplementation((plugins, _) => plugins);
69
- await cli.init(['dev'], options);
70
- expect(loadEnv).toHaveBeenCalledWith(cwd);
71
- expect(options.beforeUsePlugins).toHaveBeenCalledWith([], {});
65
+ await cli.init(['dev']);
66
+ expect(loadEnv).toHaveBeenCalledWith(cwd, undefined);
72
67
  // TODO: add more test cases
73
68
  });
74
69
  });
@@ -124,6 +124,34 @@ describe('load environment variables', () => {
124
124
  delete process.env.NODE_ENV;
125
125
  });
126
126
 
127
+ test(`get custom .env file by MODERN_ENV`, () => {
128
+ createFixtures('custom_environment', [
129
+ {
130
+ name: '.env',
131
+ content: `DB_HOST=localhost
132
+ DB_USER=root
133
+ DB_PASS=root
134
+ `,
135
+ },
136
+ {
137
+ name: '.env.staging',
138
+ content: `DB_HOST=localhost
139
+ DB_USER=root-local-dev
140
+ `,
141
+ },
142
+ ]);
143
+
144
+ loadEnv(path.join(fixture, 'custom_environment'), 'staging');
145
+
146
+ expect(process.env.DB_HOST).toBe('localhost');
147
+
148
+ expect(process.env.DB_USER).toBe('root-local-dev');
149
+
150
+ expect(process.env.DB_PASS).toBe('root');
151
+
152
+ delete process.env.MODERN_ENV;
153
+ });
154
+
127
155
  test(`support dotenv-expand`, () => {
128
156
  createFixtures('expand', [
129
157
  {
@@ -22,10 +22,12 @@ describe('load plugins', () => {
22
22
  './fixtures/load-plugin/user-plugins',
23
23
  );
24
24
 
25
- const plugins = loadPlugins(fixture, [
26
- { cli: path.join(fixture, './test-plugin-a.js') },
27
- { server: './test-plugin-b' },
28
- ]);
25
+ const plugins = loadPlugins(fixture, {
26
+ plugins: [
27
+ { cli: path.join(fixture, './test-plugin-a.js') },
28
+ { server: './test-plugin-b' },
29
+ ],
30
+ });
29
31
 
30
32
  expect(plugins).toEqual([
31
33
  {
@@ -33,26 +35,47 @@ describe('load plugins', () => {
33
35
  name: 'a',
34
36
  pluginPath: path.join(fixture, './test-plugin-a.js'),
35
37
  },
36
- cliPath: path.join(fixture, './test-plugin-a.js'),
38
+ cliPkg: path.join(fixture, './test-plugin-a.js'),
37
39
  },
38
40
  {
39
41
  server: {
40
42
  pluginPath: path.join(fixture, './test-plugin-b.js'),
41
43
  },
42
- serverPath: './test-plugin-b',
44
+ serverPkg: './test-plugin-b',
43
45
  },
44
46
  ]);
45
47
  });
46
48
 
47
- test('should load user string plugin successfully', () => {
49
+ test('should pass options to Plugin', () => {
48
50
  const fixture = path.resolve(
49
51
  __dirname,
50
52
  './fixtures/load-plugin/user-plugins',
51
53
  );
52
54
 
53
- const plugins = loadPlugins(fixture, [
54
- path.join(fixture, './test-plugin-a.js') as any,
55
+ const plugins = loadPlugins(fixture, {
56
+ plugins: [{ cli: ['./test-plugin-c', 'c'] }],
57
+ });
58
+
59
+ expect(plugins).toEqual([
60
+ {
61
+ cli: {
62
+ name: 'c',
63
+ pluginPath: path.join(fixture, './test-plugin-c.js'),
64
+ },
65
+ cliPkg: './test-plugin-c',
66
+ },
55
67
  ]);
68
+ });
69
+
70
+ test('should load user string plugin successfully', () => {
71
+ const fixture = path.resolve(
72
+ __dirname,
73
+ './fixtures/load-plugin/user-plugins',
74
+ );
75
+
76
+ const plugins = loadPlugins(fixture, {
77
+ plugins: [path.join(fixture, './test-plugin-a.js') as any],
78
+ });
56
79
 
57
80
  expect(plugins).toEqual([
58
81
  {
@@ -60,16 +83,38 @@ describe('load plugins', () => {
60
83
  name: 'a',
61
84
  pluginPath: path.join(fixture, './test-plugin-a.js'),
62
85
  },
63
- cliPath: path.join(fixture, './test-plugin-a.js'),
86
+ cliPkg: path.join(fixture, './test-plugin-a.js'),
64
87
  },
65
88
  ]);
66
89
  });
67
90
 
91
+ test('should call transformPlugin', () => {
92
+ const fixture = path.resolve(
93
+ __dirname,
94
+ './fixtures/load-plugin/user-plugins',
95
+ );
96
+
97
+ const options = {
98
+ transformPlugin: jest.fn(),
99
+ };
100
+ options.transformPlugin.mockImplementation((plugins, _) => plugins);
101
+
102
+ loadPlugins(
103
+ fixture,
104
+ { plugins: [{ cli: path.join(fixture, './test-plugin-a.js') }] },
105
+ options,
106
+ );
107
+
108
+ expect(options.transformPlugin).toHaveBeenCalled();
109
+ });
110
+
68
111
  test(`should throw error when plugin not found `, () => {
69
112
  const fixture = path.resolve(__dirname, './fixtures/load-plugin/not-found');
70
113
 
71
114
  expect(() => {
72
- loadPlugins(fixture, [{ cli: './test-plugin-a' }, { cli: './plugin-b' }]);
115
+ loadPlugins(fixture, {
116
+ plugins: [{ cli: './test-plugin-a' }, { cli: './plugin-b' }],
117
+ });
73
118
  }).toThrowError(/^Can not find plugin /);
74
119
  });
75
120
  });