Skip to content

Commit d3ed19a

Browse files
authored
feat: add --config-name flag (#1753)
1 parent 83f73b0 commit d3ed19a

File tree

8 files changed

+95
-0
lines changed

8 files changed

+95
-0
lines changed

packages/webpack-cli/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ yarn add webpack-cli --dev
3838
```
3939
--entry string[] The entry point(s) of your application.
4040
-c, --config string Provide path to a webpack configuration file
41+
--config-name string[] Name of the configuration to use
4142
-m, --merge string Merge a configuration file using webpack-merge
4243
--progress Print compilation progress during build
4344
--color Enables colors on console

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { extensions, jsVariants } = require('interpret');
55
const GroupHelper = require('../utils/GroupHelper');
66
const rechoir = require('rechoir');
77
const MergeError = require('../utils/errors/MergeError');
8+
const logger = require('../utils/logger');
89

910
// Order defines the priority, in increasing order
1011
// example - config file lookup will be in order of .webpack/webpack.config.development.js -> webpack.config.development.js -> webpack.config.js
@@ -117,6 +118,16 @@ class ConfigGroup extends GroupHelper {
117118
const newOptions = configOptions(formattedEnv, argv);
118119
// When config function returns a promise, resolve it, if not it's resolved by default
119120
newOptionsObject['options'] = await Promise.resolve(newOptions);
121+
} else if (Array.isArray(configOptions) && this.args.configName) {
122+
// In case of exporting multiple configurations, If you pass a name to --config-name flag,
123+
// webpack will only build that specific configuration.
124+
const namedOptions = configOptions.filter((opt) => this.args.configName.includes(opt.name));
125+
if (namedOptions.length === 0) {
126+
logger.error(`Configuration with name "${this.args.configName}" was not found.`);
127+
process.exit(2);
128+
} else {
129+
newOptionsObject['options'] = namedOptions;
130+
}
120131
} else {
121132
if (Array.isArray(configOptions) && !configOptions.length) {
122133
newOptionsObject['options'] = {};

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ module.exports = {
124124
description: 'Provide path to a webpack configuration file e.g. ./webpack.config.js',
125125
link: 'https://webpack.js.org/configuration/',
126126
},
127+
{
128+
name: 'config-name',
129+
usage: '--config-name <name of config>',
130+
type: String,
131+
multiple: true,
132+
group: CONFIG_GROUP,
133+
description: 'Name of the configuration to use',
134+
},
127135
{
128136
name: 'color',
129137
usage: '--color',
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
const { run } = require('../utils/test-utils');
4+
const { stat } = require('fs');
5+
const { resolve } = require('path');
6+
7+
describe('--config-name flag', () => {
8+
it('should select only the config whose name is passed with --config-name', (done) => {
9+
const { stderr, stdout } = run(__dirname, ['--config-name', 'first'], false);
10+
expect(stderr).toBeFalsy();
11+
expect(stdout).toContain('Child first');
12+
expect(stdout).not.toContain('Child second');
13+
expect(stdout).not.toContain('Child third');
14+
15+
stat(resolve(__dirname, './dist/dist-first.js'), (err, stats) => {
16+
expect(err).toBe(null);
17+
expect(stats.isFile()).toBe(true);
18+
done();
19+
});
20+
});
21+
22+
it('should work with multiple values for --config-name', (done) => {
23+
const { stderr, stdout } = run(__dirname, ['--config-name', 'first', '--config-name', 'third'], false);
24+
expect(stderr).toBeFalsy();
25+
expect(stdout).toContain('Child first');
26+
expect(stdout).not.toContain('Child second');
27+
expect(stdout).toContain('Child third');
28+
29+
stat(resolve(__dirname, './dist/dist-first.js'), (err, stats) => {
30+
expect(err).toBe(null);
31+
expect(stats.isFile()).toBe(true);
32+
done();
33+
});
34+
stat(resolve(__dirname, './dist/dist-third.js'), (err, stats) => {
35+
expect(err).toBe(null);
36+
expect(stats.isFile()).toBe(true);
37+
done();
38+
});
39+
});
40+
41+
it('should log error if invalid config name is provided', () => {
42+
const { stderr, stdout } = run(__dirname, ['--config-name', 'test'], false);
43+
expect(stderr).toContain('Configuration with name "test" was not found.');
44+
expect(stdout).toBeFalsy();
45+
});
46+
});

test/config-name/src/first.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('first config');

test/config-name/src/second.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('second config');

test/config-name/src/third.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('third config');

test/config-name/webpack.config.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module.exports = [
2+
{
3+
output: {
4+
filename: './dist-first.js',
5+
},
6+
name: 'first',
7+
entry: './src/first.js',
8+
mode: 'development',
9+
},
10+
{
11+
output: {
12+
filename: './dist-second.js',
13+
},
14+
name: 'second',
15+
entry: './src/second.js',
16+
mode: 'production',
17+
},
18+
{
19+
output: {
20+
filename: './dist-third.js',
21+
},
22+
name: 'third',
23+
entry: './src/third.js',
24+
mode: 'none',
25+
},
26+
];

0 commit comments

Comments
 (0)