Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support to spawn multiple compilers with different configs #1765

Merged
merged 9 commits into from
Aug 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/webpack-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ yarn add webpack-cli --dev

```
--entry string[] The entry point(s) of your application.
-c, --config string Provide path to a webpack configuration file
-c, --config string[] Provide path to webpack configuration file(s)
--config-name string[] Name of the configuration to use
-m, --merge string Merge a configuration file using webpack-merge
--progress Print compilation progress during build
Expand Down
49 changes: 37 additions & 12 deletions packages/webpack-cli/lib/groups/ConfigGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,34 @@ class ConfigGroup extends GroupHelper {

async resolveConfigFiles() {
const { config, mode } = this.args;
if (config) {
const configPath = resolve(process.cwd(), config);
const configFiles = getConfigInfoFromFileName(configPath);
if (!configFiles.length) {
throw new ConfigError(`The specified config file doesn't exist in ${configPath}`);
if (config.length > 0) {
const resolvedOptions = [];
const finalizedConfigs = config.map(async (webpackConfig) => {
const configPath = resolve(webpackConfig);
const configFiles = getConfigInfoFromFileName(configPath);
if (!configFiles.length) {
throw new ConfigError(`The specified config file doesn't exist in ${configPath}`);
anshumanv marked this conversation as resolved.
Show resolved Hide resolved
}
const foundConfig = configFiles[0];
const resolvedConfig = this.requireConfig(foundConfig);
return this.finalize(resolvedConfig);
});
// resolve all the configs
for await (const resolvedOption of finalizedConfigs) {
if (Array.isArray(resolvedOption.options)) {
resolvedOptions.push(...resolvedOption.options);
} else {
resolvedOptions.push(resolvedOption.options);
}
}
const foundConfig = configFiles[0];
const resolvedConfig = this.requireConfig(foundConfig);
this.opts = await this.finalize(resolvedConfig);
// When the resolved configs are more than 1, then pass them as Array [{...}, {...}] else pass the first config object {...}
const finalOptions = resolvedOptions.length > 1 ? resolvedOptions : resolvedOptions[0] || {};

this.opts['options'] = finalOptions;
return;
}

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

async resolveConfigMerging() {
// eslint-disable-next-line no-prototype-builtins
if (Object.keys(this.args).some((arg) => arg === 'merge')) {
const { merge } = this.args;

const { merge } = this.args;
if (merge) {
// try resolving merge config
const newConfigPath = this.resolveFilePath(merge);

Expand All @@ -189,7 +204,17 @@ class ConfigGroup extends GroupHelper {
const foundConfig = configFiles[0];
const resolvedConfig = this.requireConfig(foundConfig);
const newConfigurationsObject = await this.finalize(resolvedConfig);
this.opts['options'] = webpackMerge(this.opts['options'], newConfigurationsObject.options);
let resolvedOptions = this.opts['options'];
let mergedOptions;
if (Array.isArray(resolvedOptions)) {
mergedOptions = [];
resolvedOptions.forEach((resolvedOption) => {
mergedOptions.push(webpackMerge(resolvedOption, newConfigurationsObject.options));
});
} else {
mergedOptions = webpackMerge(resolvedOptions, newConfigurationsObject.options);
}
this.opts['options'] = mergedOptions;
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/webpack-cli/lib/utils/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ const core = [
usage: '--config <path to webpack configuration file>',
alias: 'c',
type: String,
defaultValue: null,
defaultValue: [],
anshumanv marked this conversation as resolved.
Show resolved Hide resolved
anshumanv marked this conversation as resolved.
Show resolved Hide resolved
group: CONFIG_GROUP,
multiple: true,
description: 'Provide path to a webpack configuration file e.g. ./webpack.config.js',
link: 'https://webpack.js.org/configuration/',
},
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { stat } = require('fs');
const { resolve } = require('path');
const { run } = require('../../../utils/test-utils');

describe('multiple config files', () => {
describe('Default configuration files: ', () => {
it('Uses prod config from dot folder if present', (done) => {
const { stdout, stderr } = run(__dirname, [], false);
expect(stderr).toBeFalsy();
Expand Down
1 change: 1 addition & 0 deletions test/config/multiple/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('Monkey D Luffy');
21 changes: 21 additions & 0 deletions test/config/multiple/multiple-config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { existsSync } = require('fs');
const { resolve } = require('path');
// eslint-disable-next-line node/no-missing-require
const { run } = require('../../utils/test-utils');

describe('Multiple config flag: ', () => {
it('spawns multiple compilers for multiple configs', () => {
const { stdout, stderr, exitCode } = run(__dirname, ['-c', 'webpack1.config.js', '-c', 'webpack2.config.js'], false);
// Should contain the correct exit code
expect(exitCode).toEqual(0);
// Should spawn multiple compilers
expect(stdout).toContain('Child amd:');
expect(stdout).toContain('Child commonjs:');

expect(stderr).toBeFalsy();

// should generate the correct output files
expect(existsSync(resolve(__dirname, './dist/dist-commonjs.js'))).toBeTruthy();
expect(existsSync(resolve(__dirname, './dist/dist-amd.js'))).toBeTruthy();
});
});
10 changes: 10 additions & 0 deletions test/config/multiple/webpack1.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
output: {
filename: './dist-amd.js',
libraryTarget: 'amd',
},
name: 'amd',
entry: './init.js',
mode: 'production',
devtool: 'eval-cheap-module-source-map',
};
10 changes: 10 additions & 0 deletions test/config/multiple/webpack2.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
output: {
filename: './dist-commonjs.js',
libraryTarget: 'commonjs',
},
name: 'commonjs',
entry: './init.js',
mode: 'production',
target: 'node',
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe('function configuration', () => {
const { stderr, stdout } = run(__dirname, ['--mode', 'development'], false);
expect(stderr).toBeFalsy();
expect(stdout).toBeTruthy();
expect(stdout).toContain("argv: { config: null, color: true, mode: 'development' }");
expect(stdout).toContain("argv: { config: [], color: true, mode: 'development' }");
// Should generate the appropriate files
expect(existsSync(resolve(__dirname, './dist/dev.js'))).toBeTruthy();
});
Expand Down