disallow shorthand cache groups syntax with cache group named test

This is a potential config error

fixes #9722
This commit is contained in:
Tobias Koppers 2019-09-24 17:17:26 +02:00
parent adfa484921
commit 03b32d3765
4 changed files with 201 additions and 145 deletions

View File

@ -362,6 +362,10 @@ class WebpackOptionsValidationError extends WebpackError {
err.parentSchema
)}`;
}
} else if (err.keyword === "not") {
return `${dataPath} should not be ${getSchemaPartText(
err.schema
)}\n${getSchemaPartText(err.parentSchema)}`;
} else if (err.keyword === "absolutePath") {
const baseMessage = `${dataPath}: ${
err.message

View File

@ -684,6 +684,30 @@
}
}
]
},
"not": {
"description": "Using the cacheGroup shorthand syntax with a cache group named 'test' is a potential config error\nDid you intent to define a cache group with a test instead?\ncacheGroups: {\n <name>: {\n test: ...\n }\n}",
"type": "object",
"additionalProperties": true,
"properties": {
"test": {
"description": "The test property is a cache group name, but using the test option of the cache group could be intended instead",
"anyOf": [
{
"instanceof": "Function",
"tsType": "Function"
},
{
"type": "string"
},
{
"instanceof": "RegExp",
"tsType": "RegExp"
}
]
}
},
"required": ["test"]
}
},
"chunks": {

View File

@ -50,7 +50,8 @@ describe("Schemas", () => {
"minItems",
"minProperties",
"instanceof",
"tsType"
"tsType",
"not"
];
const validateProperty = property => {

View File

@ -23,16 +23,16 @@ describe("Validation", () => {
createTestCase("undefined configuration", undefined, msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration should be an object."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration should be an object."
`)
);
createTestCase("null configuration", null, msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration should be an object."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration should be an object."
`)
);
createTestCase(
@ -42,10 +42,10 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry should be an non-empty string.
-> An entry point without name. The string is resolved to a module which is loaded upon startup."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry should be an non-empty string.
-> An entry point without name. The string is resolved to a module which is loaded upon startup."
`)
);
createTestCase(
@ -57,10 +57,10 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry['bundle'] should be an non-empty array.
-> A non-empty array of non-empty strings"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry['bundle'] should be an non-empty array.
-> A non-empty array of non-empty strings"
`)
);
createTestCase(
@ -73,10 +73,10 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.module.wrappedContextRegExp should be an instance of RegExp
-> Set the inner regular expression for partial dynamic dependencies"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.module.wrappedContextRegExp should be an instance of RegExp
-> Set the inner regular expression for partial dynamic dependencies"
`)
);
createTestCase(
@ -87,10 +87,10 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.parallelism should be >= 1.
-> The number of parallel processed modules in the compilation."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.parallelism should be >= 1.
-> The number of parallel processed modules in the compilation."
`)
);
createTestCase(
@ -100,10 +100,10 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry should not contain the item 'abc' twice.
-> A non-empty array of non-empty strings"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry should not contain the item 'abc' twice.
-> A non-empty array of non-empty strings"
`)
);
createTestCase(
@ -116,16 +116,16 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry[0] should be a string.
-> A non-empty string
- configuration.output.filename should be one of these:
string | function
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
Details:
* configuration.output.filename should be a string.
* configuration.output.filename should be an instance of function"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry[0] should be a string.
-> A non-empty string
- configuration.output.filename should be one of these:
string | function
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
Details:
* configuration.output.filename should be a string.
* configuration.output.filename should be an instance of function"
`)
);
createTestCase(
@ -143,16 +143,16 @@ describe("Validation", () => {
],
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration[0].entry[0] should be a string.
-> A non-empty string
- configuration[1].output.filename should be one of these:
string | function
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
Details:
* configuration[1].output.filename should be a string.
* configuration[1].output.filename should be an instance of function"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration[0].entry[0] should be a string.
-> A non-empty string
- configuration[1].output.filename should be one of these:
string | function
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
Details:
* configuration[1].output.filename should be a string.
* configuration[1].output.filename should be an instance of function"
`)
);
createTestCase(
@ -176,11 +176,11 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.module.rules[0].oneOf[0] has an unknown property 'passer'. These properties are valid:
object { compiler?, enforce?, exclude?, include?, issuer?, loader?, loaders?, oneOf?, options?, parser?, query?, realResource?, resolve?, resource?, resourceQuery?, rules?, sideEffects?, test?, type?, use? }
-> A rule"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.module.rules[0].oneOf[0] has an unknown property 'passer'. These properties are valid:
object { compiler?, enforce?, exclude?, include?, issuer?, loader?, loaders?, oneOf?, options?, parser?, query?, realResource?, resolve?, resource?, resourceQuery?, rules?, sideEffects?, test?, type?, use? }
-> A rule"
`)
);
createTestCase(
@ -191,22 +191,22 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration has an unknown property 'postcss'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, externals?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, serve?, stats?, target?, watch?, watchOptions? }
For typos: please correct them.
For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
Loaders should be updated to allow passing options via loader options in module.rules.
Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
plugins: [
new webpack.LoaderOptionsPlugin({
// test: /\\\\.xxx$/, // may apply this only for some modules
options: {
postcss:
}
})
]"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration has an unknown property 'postcss'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, externals?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, serve?, stats?, target?, watch?, watchOptions? }
For typos: please correct them.
For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
Loaders should be updated to allow passing options via loader options in module.rules.
Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
plugins: [
new webpack.LoaderOptionsPlugin({
// test: /\\\\.xxx$/, // may apply this only for some modules
options: {
postcss:
}
})
]"
`)
);
createTestCase(
@ -217,14 +217,14 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.devtool should be one of these:
string | false
-> A developer tool to enhance debugging.
Details:
* configuration.devtool should be a string.
* configuration.devtool should be false"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.devtool should be one of these:
string | false
-> A developer tool to enhance debugging.
Details:
* configuration.devtool should be a string.
* configuration.devtool should be false"
`)
);
createTestCase(
@ -238,10 +238,10 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.output.path: The provided value \\"/somepath/!test\\" contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.
-> The output directory as **absolute path** (required)."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.output.path: The provided value \\"/somepath/!test\\" contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.
-> The output directory as **absolute path** (required)."
`)
);
createTestCase(
@ -254,10 +254,10 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.output.filename: A relative path is expected. However, the provided value \\"/bar\\" is an absolute path!
Please use output.path to specify absolute path and output.filename for the file name."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.output.filename: A relative path is expected. However, the provided value \\"/bar\\" is an absolute path!
Please use output.path to specify absolute path and output.filename for the file name."
`)
);
createTestCase(
@ -271,10 +271,10 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.context: The provided value \\"baz\\" is not an absolute path!
-> The base directory (absolute path!) for resolving the \`entry\` option. If \`output.pathinfo\` is set, the included pathinfo is shortened to this directory."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.context: The provided value \\"baz\\" is not an absolute path!
-> The base directory (absolute path!) for resolving the \`entry\` option. If \`output.pathinfo\` is set, the included pathinfo is shortened to this directory."
`)
);
createTestCase(
@ -291,10 +291,10 @@ describe("Validation", () => {
.replace(/object \{ .* \}/g, "object {...}")
.replace(/"none" \| .+/g, '"none" | ...')
).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.stats has an unknown property 'foobar'. These properties are valid:
object {...}"
`);
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.stats has an unknown property 'foobar'. These properties are valid:
object {...}"
`);
}
);
@ -306,16 +306,16 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] should be one of these:
object { apply, } | function
-> Plugin of type object or instanceof Function
Details:
* configuration.plugins[0] should be an object.
-> Plugin instance
* configuration.plugins[0] should be an instance of function
-> Function acting as plugin"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] should be one of these:
object { apply, } | function
-> Plugin of type object or instanceof Function
Details:
* configuration.plugins[0] should be an object.
-> Plugin instance
* configuration.plugins[0] should be an instance of function
-> Function acting as plugin"
`)
);
createTestCase(
@ -326,16 +326,16 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] should be one of these:
object { apply, } | function
-> Plugin of type object or instanceof Function
Details:
* configuration.plugins[0] should be an object.
-> Plugin instance
* configuration.plugins[0] should be an instance of function
-> Function acting as plugin"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] should be one of these:
object { apply, } | function
-> Plugin of type object or instanceof Function
Details:
* configuration.plugins[0] should be an object.
-> Plugin instance
* configuration.plugins[0] should be an instance of function
-> Function acting as plugin"
`)
);
createTestCase(
@ -346,16 +346,16 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] should be one of these:
object { apply, } | function
-> Plugin of type object or instanceof Function
Details:
* configuration.plugins[0] should be an object.
-> Plugin instance
* configuration.plugins[0] should be an instance of function
-> Function acting as plugin"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] should be one of these:
object { apply, } | function
-> Plugin of type object or instanceof Function
Details:
* configuration.plugins[0] should be an object.
-> Plugin instance
* configuration.plugins[0] should be an instance of function
-> Function acting as plugin"
`)
);
createTestCase(
@ -366,16 +366,16 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] should be one of these:
object { apply, } | function
-> Plugin of type object or instanceof Function
Details:
* configuration.plugins[0] should be an object.
-> Plugin instance
* configuration.plugins[0] should be an instance of function
-> Function acting as plugin"
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] should be one of these:
object { apply, } | function
-> Plugin of type object or instanceof Function
Details:
* configuration.plugins[0] should be an object.
-> Plugin instance
* configuration.plugins[0] should be an instance of function
-> Function acting as plugin"
`)
);
createTestCase(
@ -386,11 +386,11 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] misses the property 'apply'.
function
-> The run point of the plugin, required method."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.plugins[0] misses the property 'apply'.
function
-> The run point of the plugin, required method."
`)
);
createTestCase(
@ -400,11 +400,38 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.mode should be one of these:
\\"development\\" | \\"production\\" | \\"none\\"
-> Enable production optimizations or development hints."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.mode should be one of these:
\\"development\\" | \\"production\\" | \\"none\\"
-> Enable production optimizations or development hints."
`)
);
createTestCase(
"missing cache group name",
{
optimization: {
splitChunks: {
cacheGroups: {
test: /abc/
}
}
}
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.optimization.splitChunks.cacheGroups should not be object { test, }
-> Using the cacheGroup shorthand syntax with a cache group named 'test' is a potential config error
Did you intent to define a cache group with a test instead?
cacheGroups: {
<name>: {
test: ...
}
}
object { <key>: false | function | string | RegExp | object { automaticNameDelimiter?, automaticNameMaxLength?, automaticNamePrefix?, chunks?, enforce?, filename?, maxAsyncRequests?, maxInitialRequests?, maxSize?, minChunks?, minSize?, name?, priority?, reuseExistingChunk?, test? } }
-> Assign modules to a cache group (modules from different cache groups are tried to keep in separate chunks)"
`)
);
createTestCase(
@ -421,8 +448,8 @@ describe("Validation", () => {
],
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration should be an object."
`)
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration should be an object."
`)
);
});