Skip to content

Commit f9ce1d3

Browse files
fix: error message on invalid plugin options (#2380)
1 parent 311bae3 commit f9ce1d3

File tree

7 files changed

+139
-35
lines changed

7 files changed

+139
-35
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
"strip-ansi": "^6.0.0",
9292
"ts-jest": "^26.4.3",
9393
"typescript": "^4.1.3",
94-
"webpack": "^5.17.0",
94+
"webpack": "^5.18.0",
9595
"webpack-bundle-analyzer": "^4.3.0",
9696
"webpack-dev-server": "^3.11.1",
9797
"yeoman-test": "^2.7.0"

packages/serve/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class ServeCommand {
113113
try {
114114
servers = await startDevServer(compiler, devServerOptions, options, logger);
115115
} catch (error) {
116-
if (error.name === 'ValidationError') {
116+
if (cli.isValidationError(error)) {
117117
logger.error(error.message);
118118
} else {
119119
logger.error(error);

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

+16-10
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,13 @@ class WebpackCLI {
11721172
}
11731173
} catch (error) {
11741174
logger.error(`Failed to load '${configPath}' config`);
1175-
logger.error(error);
1175+
1176+
if (this.isValidationError(error)) {
1177+
logger.error(error.message);
1178+
} else {
1179+
logger.error(error);
1180+
}
1181+
11761182
process.exit(2);
11771183
}
11781184

@@ -1602,15 +1608,15 @@ class WebpackCLI {
16021608
return compiler.options.watchOptions && compiler.options.watchOptions.stdin;
16031609
}
16041610

1605-
async createCompiler(options, callback) {
1606-
const isValidationError = (error) => {
1607-
// https://github.com/webpack/webpack/blob/master/lib/index.js#L267
1608-
// https://github.com/webpack/webpack/blob/v4.44.2/lib/webpack.js#L90
1609-
const ValidationError = this.webpack.ValidationError || this.webpack.WebpackOptionsValidationError;
1611+
isValidationError(error) {
1612+
// https://github.com/webpack/webpack/blob/master/lib/index.js#L267
1613+
// https://github.com/webpack/webpack/blob/v4.44.2/lib/webpack.js#L90
1614+
const ValidationError = this.webpack.ValidationError || this.webpack.WebpackOptionsValidationError;
16101615

1611-
return error instanceof ValidationError;
1612-
};
1616+
return error instanceof ValidationError || error.name === 'ValidationError';
1617+
}
16131618

1619+
async createCompiler(options, callback) {
16141620
let config = await this.resolveConfig(options);
16151621

16161622
config = await this.applyOptions(config, options);
@@ -1623,7 +1629,7 @@ class WebpackCLI {
16231629
config.options,
16241630
callback
16251631
? (error, stats) => {
1626-
if (isValidationError(error)) {
1632+
if (error && this.isValidationError(error)) {
16271633
logger.error(error.message);
16281634
process.exit(2);
16291635
}
@@ -1633,7 +1639,7 @@ class WebpackCLI {
16331639
: callback,
16341640
);
16351641
} catch (error) {
1636-
if (isValidationError(error)) {
1642+
if (this.isValidationError(error)) {
16371643
logger.error(error.message);
16381644
} else {
16391645
logger.error(error);

test/error/invalid-schema/invalid-schema.test.js

+86-3
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,31 @@ const { run, isWebpack5 } = require('../../utils/test-utils');
33

44
describe('invalid schema', () => {
55
it('should log error on invalid config', () => {
6-
const { exitCode, stderr, stdout } = run(__dirname, ['--config', './webpack.config.mock.js']);
6+
const { exitCode, stderr, stdout } = run(__dirname, ['--config', './webpack.mock.config.js']);
77

88
expect(exitCode).toEqual(2);
99
expect(stderr).toContain('Invalid configuration object');
1010
expect(stdout).toBeFalsy();
1111
});
1212

13+
it('should log error on invalid plugin options', () => {
14+
const { exitCode, stderr, stdout } = run(__dirname, ['--config', './webpack.plugin-mock.config.js']);
15+
16+
expect(exitCode).toEqual(2);
17+
expect(stderr).toContain(isWebpack5 ? 'Invalid options object' : 'Invalid Options');
18+
expect(stdout).toBeFalsy();
19+
});
20+
1321
it('should log error on invalid config using the "bundle" command', () => {
14-
const { exitCode, stderr, stdout } = run(__dirname, ['bundle', '--config', './webpack.config.mock.js']);
22+
const { exitCode, stderr, stdout } = run(__dirname, ['bundle', '--config', './webpack.mock.config.js']);
1523

1624
expect(exitCode).toEqual(2);
1725
expect(stderr).toContain('Invalid configuration object');
1826
expect(stdout).toBeFalsy();
1927
});
2028

2129
it('should log error on invalid config using the "serve" command', () => {
22-
const { exitCode, stderr, stdout } = run(__dirname, ['serve', '--config', './webpack.config.mock.js']);
30+
const { exitCode, stderr, stdout } = run(__dirname, ['serve', '--config', './webpack.mock.config.js']);
2331

2432
expect(exitCode).toEqual(2);
2533
expect(stderr).toContain('Invalid configuration object');
@@ -41,6 +49,21 @@ describe('invalid schema', () => {
4149
expect(stdout).toBeFalsy();
4250
});
4351

52+
it('should log error on invalid option using "build" command', () => {
53+
const { exitCode, stderr, stdout } = run(__dirname, ['build', '--mode', 'Yukihira']);
54+
55+
expect(exitCode).toEqual(2);
56+
57+
if (isWebpack5) {
58+
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
59+
expect(stderr).toContain("Expected: 'development | production | none'");
60+
} else {
61+
expect(stderr).toContain('Invalid configuration object');
62+
}
63+
64+
expect(stdout).toBeFalsy();
65+
});
66+
4467
it('should log error on invalid option using "bundle" command', () => {
4568
const { exitCode, stderr, stdout } = run(__dirname, ['bundle', '--mode', 'Yukihira']);
4669

@@ -56,6 +79,51 @@ describe('invalid schema', () => {
5679
expect(stdout).toBeFalsy();
5780
});
5881

82+
it('should log error on invalid option using "b" command', () => {
83+
const { exitCode, stderr, stdout } = run(__dirname, ['b', '--mode', 'Yukihira']);
84+
85+
expect(exitCode).toEqual(2);
86+
87+
if (isWebpack5) {
88+
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
89+
expect(stderr).toContain("Expected: 'development | production | none'");
90+
} else {
91+
expect(stderr).toContain('Invalid configuration object');
92+
}
93+
94+
expect(stdout).toBeFalsy();
95+
});
96+
97+
it('should log error on invalid option using "watch" command', () => {
98+
const { exitCode, stderr, stdout } = run(__dirname, ['watch', '--mode', 'Yukihira']);
99+
100+
expect(exitCode).toEqual(2);
101+
102+
if (isWebpack5) {
103+
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
104+
expect(stderr).toContain("Expected: 'development | production | none'");
105+
} else {
106+
expect(stderr).toContain('Invalid configuration object');
107+
}
108+
109+
expect(stdout).toBeFalsy();
110+
});
111+
112+
it('should log error on invalid option using "w" command', () => {
113+
const { exitCode, stderr, stdout } = run(__dirname, ['w', '--mode', 'Yukihira']);
114+
115+
expect(exitCode).toEqual(2);
116+
117+
if (isWebpack5) {
118+
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
119+
expect(stderr).toContain("Expected: 'development | production | none'");
120+
} else {
121+
expect(stderr).toContain('Invalid configuration object');
122+
}
123+
124+
expect(stdout).toBeFalsy();
125+
});
126+
59127
it('should log error on invalid option using "server" command', () => {
60128
const { exitCode, stderr, stdout } = run(__dirname, ['serve', '--mode', 'Yukihira']);
61129

@@ -70,4 +138,19 @@ describe('invalid schema', () => {
70138

71139
expect(stdout).toBeFalsy();
72140
});
141+
142+
it('should log error on invalid option using "s" command', () => {
143+
const { exitCode, stderr, stdout } = run(__dirname, ['s', '--mode', 'Yukihira']);
144+
145+
expect(exitCode).toEqual(2);
146+
147+
if (isWebpack5) {
148+
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
149+
expect(stderr).toContain("Expected: 'development | production | none'");
150+
} else {
151+
expect(stderr).toContain('Invalid configuration object');
152+
}
153+
154+
expect(stdout).toBeFalsy();
155+
});
73156
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const webpack = require('webpack');
2+
3+
module.exports = {
4+
mode: 'development',
5+
plugins: [
6+
new webpack.BannerPlugin({
7+
unknown: 'unknown',
8+
}),
9+
],
10+
};

yarn.lock

+25-20
Original file line numberDiff line numberDiff line change
@@ -1895,11 +1895,16 @@
18951895
jest-diff "^26.0.0"
18961896
pretty-format "^26.0.0"
18971897

1898-
"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.6":
1898+
"@types/json-schema@*", "@types/json-schema@^7.0.3":
18991899
version "7.0.6"
19001900
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
19011901
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
19021902

1903+
"@types/json-schema@^7.0.6":
1904+
version "7.0.7"
1905+
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
1906+
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
1907+
19031908
"@types/keyv@*":
19041909
version "3.1.1"
19051910
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
@@ -2863,15 +2868,15 @@ browser-process-hrtime@^1.0.0:
28632868
integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
28642869

28652870
browserslist@^4.14.5:
2866-
version "4.15.0"
2867-
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.15.0.tgz#3d48bbca6a3f378e86102ffd017d9a03f122bdb0"
2868-
integrity sha512-IJ1iysdMkGmjjYeRlDU8PQejVwxvVO5QOfXH7ylW31GO6LwNRSmm/SgRXtNsEXqMLl2e+2H5eEJ7sfynF8TCaQ==
2871+
version "4.16.1"
2872+
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766"
2873+
integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==
28692874
dependencies:
2870-
caniuse-lite "^1.0.30001164"
2875+
caniuse-lite "^1.0.30001173"
28712876
colorette "^1.2.1"
2872-
electron-to-chromium "^1.3.612"
2877+
electron-to-chromium "^1.3.634"
28732878
escalade "^3.1.1"
2874-
node-releases "^1.1.67"
2879+
node-releases "^1.1.69"
28752880

28762881
28772882
version "0.2.6"
@@ -3066,10 +3071,10 @@ camelcase@^6.0.0:
30663071
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
30673072
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
30683073

3069-
caniuse-lite@^1.0.30001164:
3070-
version "1.0.30001165"
3071-
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz#32955490d2f60290bb186bb754f2981917fa744f"
3072-
integrity sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA==
3074+
caniuse-lite@^1.0.30001173:
3075+
version "1.0.30001180"
3076+
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001180.tgz#67abcd6d1edf48fa5e7d1e84091d1d65ab76e33b"
3077+
integrity sha512-n8JVqXuZMVSPKiPiypjFtDTXc4jWIdjxull0f92WLo7e1MSi3uJ3NvveakSh/aCl1QKFAvIz3vIj0v+0K+FrXw==
30733078

30743079
capture-exit@^2.0.0:
30753080
version "2.0.0"
@@ -4147,10 +4152,10 @@ ejs@^3.0.1:
41474152
dependencies:
41484153
jake "^10.6.1"
41494154

4150-
electron-to-chromium@^1.3.612:
4151-
version "1.3.621"
4152-
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.621.tgz#0bbe2100ef0b28f88d0b1101fbdf433312f69be0"
4153-
integrity sha512-FeIuBzArONbAmKmZIsZIFGu/Gc9AVGlVeVbhCq+G2YIl6QkT0TDn2HKN/FMf1btXEB9kEmIuQf3/lBTVAbmFOg==
4155+
electron-to-chromium@^1.3.634:
4156+
version "1.3.647"
4157+
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.647.tgz#8f1750ab7a5137f1a9a27f8f4ebdf550e08ae10b"
4158+
integrity sha512-Or2Nu8TjkmSywY9hk85K/Y6il28hchlonITz30fkC87qvSNupQl29O12BzDDDTnUFlo6kEIFL2QGSpkZDMxH8g==
41544159

41554160
elegant-spinner@^1.0.1:
41564161
version "1.0.1"
@@ -8019,10 +8024,10 @@ node-preload@^0.2.1:
80198024
dependencies:
80208025
process-on-spawn "^1.0.0"
80218026

8022-
node-releases@^1.1.67:
8023-
version "1.1.67"
8024-
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12"
8025-
integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==
8027+
node-releases@^1.1.69:
8028+
version "1.1.70"
8029+
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08"
8030+
integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==
80268031

80278032
nopt@^4.0.1:
80288033
version "4.0.3"
@@ -11072,7 +11077,7 @@ webpack-sources@^2.1.1:
1107211077
source-list-map "^2.0.1"
1107311078
source-map "^0.6.1"
1107411079

11075-
webpack@^5.17.0:
11080+
webpack@^5.18.0:
1107611081
version "5.18.0"
1107711082
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.18.0.tgz#bbcf13094aa0da0534d513f27d7ee72d74e499c6"
1107811083
integrity sha512-RmiP/iy6ROvVe/S+u0TrvL/oOmvP+2+Bs8MWjvBwwY/j82Q51XJyDJ75m0QAGntL1Wx6B//Xc0+4VPP/hlNHmw==

0 commit comments

Comments
 (0)