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

fix: fix error message on invalid plugin options #2380

Merged
merged 2 commits into from Jan 28, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -91,7 +91,7 @@
"strip-ansi": "^6.0.0",
"ts-jest": "^26.4.3",
"typescript": "^4.1.3",
"webpack": "^5.17.0",
"webpack": "^5.18.0",
"webpack-bundle-analyzer": "^4.3.0",
"webpack-dev-server": "^3.11.1",
"yeoman-test": "^2.7.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/serve/src/index.ts
Expand Up @@ -113,7 +113,7 @@ class ServeCommand {
try {
servers = await startDevServer(compiler, devServerOptions, options, logger);
} catch (error) {
if (error.name === 'ValidationError') {
if (cli.isValidationError(error)) {
logger.error(error.message);
} else {
logger.error(error);
Expand Down
26 changes: 16 additions & 10 deletions packages/webpack-cli/lib/webpack-cli.js
Expand Up @@ -1172,7 +1172,13 @@ class WebpackCLI {
}
} catch (error) {
logger.error(`Failed to load '${configPath}' config`);
logger.error(error);

if (this.isValidationError(error)) {
logger.error(error.message);
} else {
logger.error(error);
}

process.exit(2);
}

Expand Down Expand Up @@ -1602,15 +1608,15 @@ class WebpackCLI {
return compiler.options.watchOptions && compiler.options.watchOptions.stdin;
}

async createCompiler(options, callback) {
const isValidationError = (error) => {
// https://github.com/webpack/webpack/blob/master/lib/index.js#L267
// https://github.com/webpack/webpack/blob/v4.44.2/lib/webpack.js#L90
const ValidationError = this.webpack.ValidationError || this.webpack.WebpackOptionsValidationError;
isValidationError(error) {
// https://github.com/webpack/webpack/blob/master/lib/index.js#L267
// https://github.com/webpack/webpack/blob/v4.44.2/lib/webpack.js#L90
const ValidationError = this.webpack.ValidationError || this.webpack.WebpackOptionsValidationError;

return error instanceof ValidationError;
};
return error instanceof ValidationError || error.name === 'ValidationError';
}

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

config = await this.applyOptions(config, options);
Expand All @@ -1623,7 +1629,7 @@ class WebpackCLI {
config.options,
callback
? (error, stats) => {
if (isValidationError(error)) {
if (error && this.isValidationError(error)) {
logger.error(error.message);
process.exit(2);
}
Expand All @@ -1633,7 +1639,7 @@ class WebpackCLI {
: callback,
);
} catch (error) {
if (isValidationError(error)) {
if (this.isValidationError(error)) {
logger.error(error.message);
} else {
logger.error(error);
Expand Down
89 changes: 86 additions & 3 deletions test/error/invalid-schema/invalid-schema.test.js
Expand Up @@ -3,23 +3,31 @@ const { run, isWebpack5 } = require('../../utils/test-utils');

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

expect(exitCode).toEqual(2);
expect(stderr).toContain('Invalid configuration object');
expect(stdout).toBeFalsy();
});

it('should log error on invalid plugin options', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['--config', './webpack.plugin-mock.config.js']);

expect(exitCode).toEqual(2);
expect(stderr).toContain(isWebpack5 ? 'Invalid options object' : 'Invalid Options');
expect(stdout).toBeFalsy();
});

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

expect(exitCode).toEqual(2);
expect(stderr).toContain('Invalid configuration object');
expect(stdout).toBeFalsy();
});

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

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

it('should log error on invalid option using "build" command', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['build', '--mode', 'Yukihira']);

expect(exitCode).toEqual(2);

if (isWebpack5) {
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
expect(stderr).toContain("Expected: 'development | production | none'");
} else {
expect(stderr).toContain('Invalid configuration object');
}

expect(stdout).toBeFalsy();
});

it('should log error on invalid option using "bundle" command', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['bundle', '--mode', 'Yukihira']);

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

it('should log error on invalid option using "b" command', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['b', '--mode', 'Yukihira']);

expect(exitCode).toEqual(2);

if (isWebpack5) {
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
expect(stderr).toContain("Expected: 'development | production | none'");
} else {
expect(stderr).toContain('Invalid configuration object');
}

expect(stdout).toBeFalsy();
});

it('should log error on invalid option using "watch" command', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['watch', '--mode', 'Yukihira']);

expect(exitCode).toEqual(2);

if (isWebpack5) {
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
expect(stderr).toContain("Expected: 'development | production | none'");
} else {
expect(stderr).toContain('Invalid configuration object');
}

expect(stdout).toBeFalsy();
});

it('should log error on invalid option using "w" command', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['w', '--mode', 'Yukihira']);

expect(exitCode).toEqual(2);

if (isWebpack5) {
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
expect(stderr).toContain("Expected: 'development | production | none'");
} else {
expect(stderr).toContain('Invalid configuration object');
}

expect(stdout).toBeFalsy();
});

it('should log error on invalid option using "server" command', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['serve', '--mode', 'Yukihira']);

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

expect(stdout).toBeFalsy();
});

it('should log error on invalid option using "s" command', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['s', '--mode', 'Yukihira']);

expect(exitCode).toEqual(2);

if (isWebpack5) {
expect(stderr).toContain("Invalid value 'Yukihira' for the '--mode' option");
expect(stderr).toContain("Expected: 'development | production | none'");
} else {
expect(stderr).toContain('Invalid configuration object');
}

expect(stdout).toBeFalsy();
});
});
10 changes: 10 additions & 0 deletions test/error/invalid-schema/webpack.plugin-mock.config.js
@@ -0,0 +1,10 @@
const webpack = require('webpack');

module.exports = {
mode: 'development',
plugins: [
new webpack.BannerPlugin({
unknown: 'unknown',
}),
],
};
45 changes: 25 additions & 20 deletions yarn.lock
Expand Up @@ -1895,11 +1895,16 @@
jest-diff "^26.0.0"
pretty-format "^26.0.0"

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

"@types/json-schema@^7.0.6":
version "7.0.7"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==

"@types/keyv@*":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
Expand Down Expand Up @@ -2863,15 +2868,15 @@ browser-process-hrtime@^1.0.0:
integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==

browserslist@^4.14.5:
version "4.15.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.15.0.tgz#3d48bbca6a3f378e86102ffd017d9a03f122bdb0"
integrity sha512-IJ1iysdMkGmjjYeRlDU8PQejVwxvVO5QOfXH7ylW31GO6LwNRSmm/SgRXtNsEXqMLl2e+2H5eEJ7sfynF8TCaQ==
version "4.16.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766"
integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==
dependencies:
caniuse-lite "^1.0.30001164"
caniuse-lite "^1.0.30001173"
colorette "^1.2.1"
electron-to-chromium "^1.3.612"
electron-to-chromium "^1.3.634"
escalade "^3.1.1"
node-releases "^1.1.67"
node-releases "^1.1.69"

bs-logger@0.x:
version "0.2.6"
Expand Down Expand Up @@ -3066,10 +3071,10 @@ camelcase@^6.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==

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

capture-exit@^2.0.0:
version "2.0.0"
Expand Down Expand Up @@ -4147,10 +4152,10 @@ ejs@^3.0.1:
dependencies:
jake "^10.6.1"

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

elegant-spinner@^1.0.1:
version "1.0.1"
Expand Down Expand Up @@ -8019,10 +8024,10 @@ node-preload@^0.2.1:
dependencies:
process-on-spawn "^1.0.0"

node-releases@^1.1.67:
version "1.1.67"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12"
integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==
node-releases@^1.1.69:
version "1.1.70"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08"
integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==

nopt@^4.0.1:
version "4.0.3"
Expand Down Expand Up @@ -11072,7 +11077,7 @@ webpack-sources@^2.1.1:
source-list-map "^2.0.1"
source-map "^0.6.1"

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