Skip to content

Commit 7314d6c

Browse files
feat: show multiple suggestions on unknown options (#2349)
1 parent 3eabbbc commit 7314d6c

File tree

3 files changed

+21
-27
lines changed

3 files changed

+21
-27
lines changed

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

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,26 @@ const builtInFlags = [
2323
// For configs
2424
{
2525
name: 'config',
26-
usage: '--config <path-to-config> | --config <path-to-config> --config <path-to-config>',
2726
alias: 'c',
2827
type: String,
2928
multiple: true,
3029
description: 'Provide path to a webpack configuration file e.g. ./webpack.config.js.',
3130
},
3231
{
3332
name: 'config-name',
34-
usage: '--config-name <name-of-config> | --config-name <name-of-config> --config-name <name-of-config>',
3533
type: String,
3634
multiple: true,
3735
description: 'Name of the configuration to use.',
3836
},
3937
{
4038
name: 'merge',
41-
usage: '--config <first-config> --config <second-config> --merge',
4239
alias: 'm',
4340
type: Boolean,
4441
description: "Merge two or more configurations using 'webpack-merge'.",
4542
},
4643
// Complex configs
4744
{
4845
name: 'env',
49-
usage: '--env <variable> | --env <variable> --env <variable=value>',
5046
type: (value, previous = {}) => {
5147
// This ensures we're only splitting by the first `=`
5248
const [allKeys, val] = value.split(/=(.+)/, 2);
@@ -79,7 +75,6 @@ const builtInFlags = [
7975
// Adding more plugins
8076
{
8177
name: 'hot',
82-
usage: '--hot',
8378
alias: 'h',
8479
type: Boolean,
8580
negative: true,
@@ -88,28 +83,24 @@ const builtInFlags = [
8883
},
8984
{
9085
name: 'analyze',
91-
usage: '--analyze',
9286
type: Boolean,
9387
multiple: false,
9488
description: 'It invokes webpack-bundle-analyzer plugin to get bundle information.',
9589
},
9690
{
9791
name: 'progress',
98-
usage: '--progress | --progress profile',
9992
type: [Boolean, String],
10093
description: 'Print compilation progress during build.',
10194
},
10295
{
10396
name: 'prefetch',
104-
usage: '--prefetch <request>',
10597
type: String,
10698
description: 'Prefetch this request.',
10799
},
108100

109101
// Output options
110102
{
111103
name: 'json',
112-
usage: '--json | --json <path-to-stats-file>',
113104
type: [String, Boolean],
114105
alias: 'j',
115106
description: 'Prints result as JSON or store it in a file.',
@@ -118,29 +109,25 @@ const builtInFlags = [
118109
// For webpack@4
119110
{
120111
name: 'entry',
121-
usage: '--entry <path-to-entry-file> | --entry <path> --entry <path>',
122112
type: String,
123113
multiple: true,
124114
description: 'The entry point(s) of your application e.g. ./src/main.js.',
125115
},
126116
{
127117
name: 'output-path',
128-
usage: '--output-path <path-to-output-directory>',
129118
alias: 'o',
130119
type: String,
131120
description: 'Output location of the file generated by webpack e.g. ./dist/.',
132121
},
133122
{
134123
name: 'target',
135-
usage: '--target <value> | --target <value> --target <value>',
136124
alias: 't',
137125
type: String,
138126
multiple: cli !== undefined,
139127
description: 'Sets the build target e.g. node.',
140128
},
141129
{
142130
name: 'devtool',
143-
usage: '--devtool <value>',
144131
type: String,
145132
negative: true,
146133
alias: 'd',
@@ -149,27 +136,23 @@ const builtInFlags = [
149136
},
150137
{
151138
name: 'mode',
152-
usage: '--mode <development | production | none>',
153139
type: String,
154140
description: 'Defines the mode to pass to webpack.',
155141
},
156142
{
157143
name: 'name',
158-
usage: '--name',
159144
type: String,
160145
description: 'Name of the configuration. Used when loading multiple configurations.',
161146
},
162147
{
163148
name: 'stats',
164-
usage: '--stats | --stats <value>',
165149
type: [String, Boolean],
166150
negative: true,
167151
description: 'It instructs webpack on how to treat the stats e.g. verbose.',
168152
negatedDescription: 'Disable stats output.',
169153
},
170154
{
171155
name: 'watch',
172-
usage: '--watch',
173156
type: Boolean,
174157
negative: true,
175158
alias: 'w',
@@ -178,7 +161,6 @@ const builtInFlags = [
178161
},
179162
{
180163
name: 'watch-options-stdin',
181-
usage: '--watch-options-stdin',
182164
type: Boolean,
183165
negative: true,
184166
description: 'Stop watching when stdin stream has ended.',
@@ -192,14 +174,11 @@ const coreFlags = cli
192174
? Object.entries(cli.getArguments()).map(([flag, meta]) => {
193175
if (meta.simpleType === 'string') {
194176
meta.type = String;
195-
meta.usage = `--${flag} <value>`;
196177
} else if (meta.simpleType === 'number') {
197178
meta.type = Number;
198-
meta.usage = `--${flag} <value>`;
199179
} else {
200180
meta.type = Boolean;
201181
meta.negative = !flag.endsWith('-reset');
202-
meta.usage = `--${flag}`;
203182
}
204183

205184
const inBuiltIn = builtInFlags.find((builtInFlag) => builtInFlag.name === flag);

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ class WebpackCLI {
316316
const loadCommandByName = async (commandName, allowToInstall = false) => {
317317
if (commandName === bundleCommandOptions.name || commandName === bundleCommandOptions.alias) {
318318
// Make `bundle|b [options]` command
319-
this.makeCommand(bundleCommandOptions, this.getBuiltInOptions(), async (program) => {
319+
await this.makeCommand(bundleCommandOptions, this.getBuiltInOptions(), async (program) => {
320320
const options = program.opts();
321321

322322
if (program.args.length > 0) {
@@ -430,11 +430,11 @@ class WebpackCLI {
430430
process.exit(2);
431431
}
432432

433-
const found = command.options.find((option) => distance(name, option.long.slice(2)) < 3);
434-
435-
if (found) {
436-
logger.error(`Did you mean '--${found.name()}'?`);
437-
}
433+
command.options.forEach((option) => {
434+
if (distance(name, option.long.slice(2)) < 3) {
435+
logger.error(`Did you mean '--${option.name()}'?`);
436+
}
437+
});
438438
}
439439
}
440440
}

test/unknown/unknown.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,21 @@ describe('unknown behaviour', () => {
144144
expect(stdout).toBeFalsy();
145145
});
146146

147+
it('should log an error if an unknown flag is passed and suggests the closest match to an unknown flag #3', () => {
148+
const { exitCode, stderr, stdout } = run(__dirname, ['--output-library-auxiliary-comment-commnjs']);
149+
150+
expect(exitCode).toBe(2);
151+
expect(stderr).toContain("unknown option '--output-library-auxiliary-comment-commnjs'");
152+
153+
if (isWebpack5) {
154+
expect(stderr).toContain("Did you mean '--output-library-auxiliary-comment-commonjs'?");
155+
expect(stderr).toContain("Did you mean '--output-library-auxiliary-comment-commonjs2'?");
156+
}
157+
158+
expect(stderr).toContain("Run 'webpack --help' to see available commands and options");
159+
expect(stdout).toBeFalsy();
160+
});
161+
147162
it('should log an error if an unknown flag is passed and suggests the closest match to an unknown flag using "bundle" command', () => {
148163
const { exitCode, stderr, stdout } = run(__dirname, ['bundle', '--entyr', './a.js']);
149164

0 commit comments

Comments
 (0)