validateSchema.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { validate } = require("schema-utils");
  7. /* cSpell:disable */
  8. const DID_YOU_MEAN = {
  9. rules: "module.rules",
  10. loaders: "module.rules or module.rules.*.use",
  11. query: "module.rules.*.options (BREAKING CHANGE since webpack 5)",
  12. noParse: "module.noParse",
  13. filename: "output.filename or module.rules.*.generator.filename",
  14. file: "output.filename",
  15. chunkFilename: "output.chunkFilename",
  16. chunkfilename: "output.chunkFilename",
  17. ecmaVersion:
  18. "output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)",
  19. ecmaversion:
  20. "output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)",
  21. ecma: "output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)",
  22. path: "output.path",
  23. pathinfo: "output.pathinfo",
  24. pathInfo: "output.pathinfo",
  25. jsonpFunction: "output.chunkLoadingGlobal (BREAKING CHANGE since webpack 5)",
  26. chunkCallbackName:
  27. "output.chunkLoadingGlobal (BREAKING CHANGE since webpack 5)",
  28. jsonpScriptType: "output.scriptType (BREAKING CHANGE since webpack 5)",
  29. hotUpdateFunction: "output.hotUpdateGlobal (BREAKING CHANGE since webpack 5)",
  30. splitChunks: "optimization.splitChunks",
  31. immutablePaths: "snapshot.immutablePaths",
  32. managedPaths: "snapshot.managedPaths",
  33. maxModules: "stats.modulesSpace (BREAKING CHANGE since webpack 5)",
  34. hashedModuleIds:
  35. 'optimization.moduleIds: "hashed" (BREAKING CHANGE since webpack 5)',
  36. namedChunks:
  37. 'optimization.chunkIds: "named" (BREAKING CHANGE since webpack 5)',
  38. namedModules:
  39. 'optimization.moduleIds: "named" (BREAKING CHANGE since webpack 5)',
  40. occurrenceOrder:
  41. 'optimization.chunkIds: "size" and optimization.moduleIds: "size" (BREAKING CHANGE since webpack 5)',
  42. automaticNamePrefix:
  43. "optimization.splitChunks.[cacheGroups.*].idHint (BREAKING CHANGE since webpack 5)",
  44. noEmitOnErrors:
  45. "optimization.emitOnErrors (BREAKING CHANGE since webpack 5: logic is inverted to avoid negative flags)",
  46. Buffer:
  47. "to use the ProvidePlugin to process the Buffer variable to modules as polyfill\n" +
  48. "BREAKING CHANGE: webpack 5 no longer provided Node.js polyfills by default.\n" +
  49. "Note: if you are using 'node.Buffer: false', you can just remove that as this is the default behavior now.\n" +
  50. "To provide a polyfill to modules use:\n" +
  51. 'new ProvidePlugin({ Buffer: ["buffer", "Buffer"] }) and npm install buffer.',
  52. process:
  53. "to use the ProvidePlugin to process the process variable to modules as polyfill\n" +
  54. "BREAKING CHANGE: webpack 5 no longer provided Node.js polyfills by default.\n" +
  55. "Note: if you are using 'node.process: false', you can just remove that as this is the default behavior now.\n" +
  56. "To provide a polyfill to modules use:\n" +
  57. 'new ProvidePlugin({ process: "process" }) and npm install buffer.'
  58. };
  59. const REMOVED = {
  60. concord:
  61. "BREAKING CHANGE: resolve.concord has been removed and is no longer available.",
  62. devtoolLineToLine:
  63. "BREAKING CHANGE: output.devtoolLineToLine has been removed and is no longer available."
  64. };
  65. /* cSpell:enable */
  66. /**
  67. * @param {Parameters<typeof validate>[0]} schema a json schema
  68. * @param {Parameters<typeof validate>[1]} options the options that should be validated
  69. * @param {Parameters<typeof validate>[2]=} validationConfiguration configuration for generating errors
  70. * @returns {void}
  71. */
  72. const validateSchema = (schema, options, validationConfiguration) => {
  73. validate(
  74. schema,
  75. options,
  76. validationConfiguration || {
  77. name: "Webpack",
  78. postFormatter: (formattedError, error) => {
  79. const children = error.children;
  80. if (
  81. children &&
  82. children.some(
  83. child =>
  84. child.keyword === "absolutePath" &&
  85. child.instancePath === "/output/filename"
  86. )
  87. ) {
  88. return `${formattedError}\nPlease use output.path to specify absolute path and output.filename for the file name.`;
  89. }
  90. if (
  91. children &&
  92. children.some(
  93. child =>
  94. child.keyword === "pattern" && child.instancePath === "/devtool"
  95. )
  96. ) {
  97. return (
  98. `${formattedError}\n` +
  99. "BREAKING CHANGE since webpack 5: The devtool option is more strict.\n" +
  100. "Please strictly follow the order of the keywords in the pattern."
  101. );
  102. }
  103. if (error.keyword === "additionalProperties") {
  104. const params = error.params;
  105. if (
  106. Object.prototype.hasOwnProperty.call(
  107. DID_YOU_MEAN,
  108. params.additionalProperty
  109. )
  110. ) {
  111. return `${formattedError}\nDid you mean ${
  112. DID_YOU_MEAN[
  113. /** @type {keyof DID_YOU_MEAN} */ (params.additionalProperty)
  114. ]
  115. }?`;
  116. }
  117. if (
  118. Object.prototype.hasOwnProperty.call(
  119. REMOVED,
  120. params.additionalProperty
  121. )
  122. ) {
  123. return `${formattedError}\n${
  124. REMOVED[/** @type {keyof REMOVED} */ (params.additionalProperty)]
  125. }?`;
  126. }
  127. if (!error.instancePath) {
  128. if (params.additionalProperty === "debug") {
  129. return (
  130. `${formattedError}\n` +
  131. "The 'debug' property was removed in webpack 2.0.0.\n" +
  132. "Loaders should be updated to allow passing this option via loader options in module.rules.\n" +
  133. "Until loaders are updated one can use the LoaderOptionsPlugin to switch loaders into debug mode:\n" +
  134. "plugins: [\n" +
  135. " new webpack.LoaderOptionsPlugin({\n" +
  136. " debug: true\n" +
  137. " })\n" +
  138. "]"
  139. );
  140. }
  141. if (params.additionalProperty) {
  142. return (
  143. `${formattedError}\n` +
  144. "For typos: please correct them.\n" +
  145. "For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.\n" +
  146. " Loaders should be updated to allow passing options via loader options in module.rules.\n" +
  147. " Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:\n" +
  148. " plugins: [\n" +
  149. " new webpack.LoaderOptionsPlugin({\n" +
  150. " // test: /\\.xxx$/, // may apply this only for some modules\n" +
  151. " options: {\n" +
  152. ` ${params.additionalProperty}: …\n` +
  153. " }\n" +
  154. " })\n" +
  155. " ]"
  156. );
  157. }
  158. }
  159. }
  160. return formattedError;
  161. }
  162. }
  163. );
  164. };
  165. module.exports = validateSchema;