Skip to content

Commit c63ab29

Browse files
authored
feat: add support to spawn multiple compilers with different configs (#1765)
1 parent ff0a657 commit c63ab29

27 files changed

+84
-16
lines changed

packages/webpack-cli/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ yarn add webpack-cli --dev
3737

3838
```
3939
--entry string[] The entry point(s) of your application.
40-
-c, --config string Provide path to a webpack configuration file
40+
-c, --config string[] Provide path to webpack configuration file(s)
4141
--config-name string[] Name of the configuration to use
4242
-m, --merge string Merge a configuration file using webpack-merge
4343
--progress Print compilation progress during build

packages/webpack-cli/lib/groups/ConfigGroup.js

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,34 @@ class ConfigGroup extends GroupHelper {
143143

144144
async resolveConfigFiles() {
145145
const { config, mode } = this.args;
146-
if (config) {
147-
const configPath = resolve(process.cwd(), config);
148-
const configFiles = getConfigInfoFromFileName(configPath);
149-
if (!configFiles.length) {
150-
throw new ConfigError(`The specified config file doesn't exist in ${configPath}`);
146+
if (config.length > 0) {
147+
const resolvedOptions = [];
148+
const finalizedConfigs = config.map(async (webpackConfig) => {
149+
const configPath = resolve(webpackConfig);
150+
const configFiles = getConfigInfoFromFileName(configPath);
151+
if (!configFiles.length) {
152+
throw new ConfigError(`The specified config file doesn't exist in ${configPath}`);
153+
}
154+
const foundConfig = configFiles[0];
155+
const resolvedConfig = this.requireConfig(foundConfig);
156+
return this.finalize(resolvedConfig);
157+
});
158+
// resolve all the configs
159+
for await (const resolvedOption of finalizedConfigs) {
160+
if (Array.isArray(resolvedOption.options)) {
161+
resolvedOptions.push(...resolvedOption.options);
162+
} else {
163+
resolvedOptions.push(resolvedOption.options);
164+
}
151165
}
152-
const foundConfig = configFiles[0];
153-
const resolvedConfig = this.requireConfig(foundConfig);
154-
this.opts = await this.finalize(resolvedConfig);
166+
// When the resolved configs are more than 1, then pass them as Array [{...}, {...}] else pass the first config object {...}
167+
const finalOptions = resolvedOptions.length > 1 ? resolvedOptions : resolvedOptions[0] || {};
168+
169+
this.opts['options'] = finalOptions;
155170
return;
156171
}
157172

173+
// When no config is supplied, lookup for default configs
158174
const defaultConfigFiles = getDefaultConfigFiles();
159175
const tmpConfigFiles = defaultConfigFiles.filter((file) => {
160176
return existsSync(file.path);
@@ -175,9 +191,8 @@ class ConfigGroup extends GroupHelper {
175191

176192
async resolveConfigMerging() {
177193
// eslint-disable-next-line no-prototype-builtins
178-
if (Object.keys(this.args).some((arg) => arg === 'merge')) {
179-
const { merge } = this.args;
180-
194+
const { merge } = this.args;
195+
if (merge) {
181196
// try resolving merge config
182197
const newConfigPath = this.resolveFilePath(merge);
183198

@@ -189,7 +204,17 @@ class ConfigGroup extends GroupHelper {
189204
const foundConfig = configFiles[0];
190205
const resolvedConfig = this.requireConfig(foundConfig);
191206
const newConfigurationsObject = await this.finalize(resolvedConfig);
192-
this.opts['options'] = webpackMerge(this.opts['options'], newConfigurationsObject.options);
207+
let resolvedOptions = this.opts['options'];
208+
let mergedOptions;
209+
if (Array.isArray(resolvedOptions)) {
210+
mergedOptions = [];
211+
resolvedOptions.forEach((resolvedOption) => {
212+
mergedOptions.push(webpackMerge(resolvedOption, newConfigurationsObject.options));
213+
});
214+
} else {
215+
mergedOptions = webpackMerge(resolvedOptions, newConfigurationsObject.options);
216+
}
217+
this.opts['options'] = mergedOptions;
193218
}
194219
}
195220

packages/webpack-cli/lib/utils/cli-flags.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ const core = [
9191
usage: '--config <path to webpack configuration file>',
9292
alias: 'c',
9393
type: String,
94-
defaultValue: null,
94+
defaultValue: [],
9595
group: CONFIG_GROUP,
96+
multiple: true,
9697
description: 'Provide path to a webpack configuration file e.g. ./webpack.config.js',
9798
link: 'https://webpack.js.org/configuration/',
9899
},

test/config/multiple/all/.webpack/webpack.config.dev.js renamed to test/config/defaults/all/.webpack/webpack.config.dev.js

File renamed without changes.

test/config/multiple/all/.webpack/webpack.config.none.js renamed to test/config/defaults/all/.webpack/webpack.config.none.js

File renamed without changes.

test/config/multiple/all/.webpack/webpack.config.prod.js renamed to test/config/defaults/all/.webpack/webpack.config.prod.js

File renamed without changes.

test/config/multiple/all/multiple-config.test.js renamed to test/config/defaults/all/multiple-config.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const { stat } = require('fs');
33
const { resolve } = require('path');
44
const { run } = require('../../../utils/test-utils');
55

6-
describe('multiple config files', () => {
6+
describe('Default configuration files: ', () => {
77
it('Uses prod config from dot folder if present', (done) => {
88
const { stdout, stderr } = run(__dirname, [], false);
99
expect(stderr).toBeFalsy();

test/config/multiple/multiple-location/.webpack/webpack.config.development.js renamed to test/config/defaults/multiple-location/.webpack/webpack.config.development.js

File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)