DefaultStatsPresetPlugin.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const RequestShortener = require("../RequestShortener");
  7. /** @typedef {import("../../declarations/WebpackOptions").StatsOptions} StatsOptions */
  8. /** @typedef {import("../Compilation")} Compilation */
  9. /** @typedef {import("../Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */
  10. /** @typedef {import("../Compiler")} Compiler */
  11. const applyDefaults = (options, defaults) => {
  12. for (const key of Object.keys(defaults)) {
  13. if (typeof options[key] === "undefined") {
  14. options[key] = defaults[key];
  15. }
  16. }
  17. };
  18. const NAMED_PRESETS = {
  19. verbose: {
  20. hash: true,
  21. builtAt: true,
  22. relatedAssets: true,
  23. entrypoints: true,
  24. chunkGroups: true,
  25. ids: true,
  26. modules: false,
  27. chunks: true,
  28. chunkRelations: true,
  29. chunkModules: true,
  30. dependentModules: true,
  31. chunkOrigins: true,
  32. depth: true,
  33. env: true,
  34. reasons: true,
  35. usedExports: true,
  36. providedExports: true,
  37. optimizationBailout: true,
  38. errorDetails: true,
  39. errorStack: true,
  40. publicPath: true,
  41. logging: "verbose",
  42. orphanModules: true,
  43. runtimeModules: true,
  44. exclude: false,
  45. errorsSpace: Infinity,
  46. warningsSpace: Infinity,
  47. modulesSpace: Infinity,
  48. chunkModulesSpace: Infinity,
  49. assetsSpace: Infinity,
  50. reasonsSpace: Infinity,
  51. children: true
  52. },
  53. detailed: {
  54. hash: true,
  55. builtAt: true,
  56. relatedAssets: true,
  57. entrypoints: true,
  58. chunkGroups: true,
  59. ids: true,
  60. chunks: true,
  61. chunkRelations: true,
  62. chunkModules: false,
  63. chunkOrigins: true,
  64. depth: true,
  65. usedExports: true,
  66. providedExports: true,
  67. optimizationBailout: true,
  68. errorDetails: true,
  69. publicPath: true,
  70. logging: true,
  71. runtimeModules: true,
  72. exclude: false,
  73. errorsSpace: 1000,
  74. warningsSpace: 1000,
  75. modulesSpace: 1000,
  76. assetsSpace: 1000,
  77. reasonsSpace: 1000
  78. },
  79. minimal: {
  80. all: false,
  81. version: true,
  82. timings: true,
  83. modules: true,
  84. errorsSpace: 0,
  85. warningsSpace: 0,
  86. modulesSpace: 0,
  87. assets: true,
  88. assetsSpace: 0,
  89. errors: true,
  90. errorsCount: true,
  91. warnings: true,
  92. warningsCount: true,
  93. logging: "warn"
  94. },
  95. "errors-only": {
  96. all: false,
  97. errors: true,
  98. errorsCount: true,
  99. errorsSpace: Infinity,
  100. moduleTrace: true,
  101. logging: "error"
  102. },
  103. "errors-warnings": {
  104. all: false,
  105. errors: true,
  106. errorsCount: true,
  107. errorsSpace: Infinity,
  108. warnings: true,
  109. warningsCount: true,
  110. warningsSpace: Infinity,
  111. logging: "warn"
  112. },
  113. summary: {
  114. all: false,
  115. version: true,
  116. errorsCount: true,
  117. warningsCount: true
  118. },
  119. none: {
  120. all: false
  121. }
  122. };
  123. const NORMAL_ON = ({ all }) => all !== false;
  124. const NORMAL_OFF = ({ all }) => all === true;
  125. const ON_FOR_TO_STRING = ({ all }, { forToString }) =>
  126. forToString ? all !== false : all === true;
  127. const OFF_FOR_TO_STRING = ({ all }, { forToString }) =>
  128. forToString ? all === true : all !== false;
  129. const AUTO_FOR_TO_STRING = ({ all }, { forToString }) => {
  130. if (all === false) return false;
  131. if (all === true) return true;
  132. if (forToString) return "auto";
  133. return true;
  134. };
  135. /** @type {Record<string, (options: StatsOptions, context: CreateStatsOptionsContext, compilation: Compilation) => any>} */
  136. const DEFAULTS = {
  137. context: (options, context, compilation) => compilation.compiler.context,
  138. requestShortener: (options, context, compilation) =>
  139. compilation.compiler.context === options.context
  140. ? compilation.requestShortener
  141. : new RequestShortener(options.context, compilation.compiler.root),
  142. performance: NORMAL_ON,
  143. hash: OFF_FOR_TO_STRING,
  144. env: NORMAL_OFF,
  145. version: NORMAL_ON,
  146. timings: NORMAL_ON,
  147. builtAt: OFF_FOR_TO_STRING,
  148. assets: NORMAL_ON,
  149. entrypoints: AUTO_FOR_TO_STRING,
  150. chunkGroups: OFF_FOR_TO_STRING,
  151. chunkGroupAuxiliary: OFF_FOR_TO_STRING,
  152. chunkGroupChildren: OFF_FOR_TO_STRING,
  153. chunkGroupMaxAssets: (o, { forToString }) => (forToString ? 5 : Infinity),
  154. chunks: OFF_FOR_TO_STRING,
  155. chunkRelations: OFF_FOR_TO_STRING,
  156. chunkModules: ({ all, modules }) => {
  157. if (all === false) return false;
  158. if (all === true) return true;
  159. if (modules) return false;
  160. return true;
  161. },
  162. dependentModules: OFF_FOR_TO_STRING,
  163. chunkOrigins: OFF_FOR_TO_STRING,
  164. ids: OFF_FOR_TO_STRING,
  165. modules: ({ all, chunks, chunkModules }, { forToString }) => {
  166. if (all === false) return false;
  167. if (all === true) return true;
  168. if (forToString && chunks && chunkModules) return false;
  169. return true;
  170. },
  171. nestedModules: OFF_FOR_TO_STRING,
  172. groupModulesByType: ON_FOR_TO_STRING,
  173. groupModulesByCacheStatus: ON_FOR_TO_STRING,
  174. groupModulesByLayer: ON_FOR_TO_STRING,
  175. groupModulesByAttributes: ON_FOR_TO_STRING,
  176. groupModulesByPath: ON_FOR_TO_STRING,
  177. groupModulesByExtension: ON_FOR_TO_STRING,
  178. modulesSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
  179. chunkModulesSpace: (o, { forToString }) => (forToString ? 10 : Infinity),
  180. nestedModulesSpace: (o, { forToString }) => (forToString ? 10 : Infinity),
  181. relatedAssets: OFF_FOR_TO_STRING,
  182. groupAssetsByEmitStatus: ON_FOR_TO_STRING,
  183. groupAssetsByInfo: ON_FOR_TO_STRING,
  184. groupAssetsByPath: ON_FOR_TO_STRING,
  185. groupAssetsByExtension: ON_FOR_TO_STRING,
  186. groupAssetsByChunk: ON_FOR_TO_STRING,
  187. assetsSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
  188. orphanModules: OFF_FOR_TO_STRING,
  189. runtimeModules: ({ all, runtime }, { forToString }) =>
  190. runtime !== undefined
  191. ? runtime
  192. : forToString
  193. ? all === true
  194. : all !== false,
  195. cachedModules: ({ all, cached }, { forToString }) =>
  196. cached !== undefined ? cached : forToString ? all === true : all !== false,
  197. moduleAssets: OFF_FOR_TO_STRING,
  198. depth: OFF_FOR_TO_STRING,
  199. cachedAssets: OFF_FOR_TO_STRING,
  200. reasons: OFF_FOR_TO_STRING,
  201. reasonsSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
  202. groupReasonsByOrigin: ON_FOR_TO_STRING,
  203. usedExports: OFF_FOR_TO_STRING,
  204. providedExports: OFF_FOR_TO_STRING,
  205. optimizationBailout: OFF_FOR_TO_STRING,
  206. children: OFF_FOR_TO_STRING,
  207. source: NORMAL_OFF,
  208. moduleTrace: NORMAL_ON,
  209. errors: NORMAL_ON,
  210. errorsCount: NORMAL_ON,
  211. errorDetails: AUTO_FOR_TO_STRING,
  212. errorStack: OFF_FOR_TO_STRING,
  213. warnings: NORMAL_ON,
  214. warningsCount: NORMAL_ON,
  215. publicPath: OFF_FOR_TO_STRING,
  216. logging: ({ all }, { forToString }) =>
  217. forToString && all !== false ? "info" : false,
  218. loggingDebug: () => [],
  219. loggingTrace: OFF_FOR_TO_STRING,
  220. excludeModules: () => [],
  221. excludeAssets: () => [],
  222. modulesSort: () => "depth",
  223. chunkModulesSort: () => "name",
  224. nestedModulesSort: () => false,
  225. chunksSort: () => false,
  226. assetsSort: () => "!size",
  227. outputPath: OFF_FOR_TO_STRING,
  228. colors: () => false
  229. };
  230. const normalizeFilter = item => {
  231. if (typeof item === "string") {
  232. const regExp = new RegExp(
  233. `[\\\\/]${item.replace(/[-[\]{}()*+?.\\^$|]/g, "\\$&")}([\\\\/]|$|!|\\?)`
  234. );
  235. return ident => regExp.test(ident);
  236. }
  237. if (item && typeof item === "object" && typeof item.test === "function") {
  238. return ident => item.test(ident);
  239. }
  240. if (typeof item === "function") {
  241. return item;
  242. }
  243. if (typeof item === "boolean") {
  244. return () => item;
  245. }
  246. };
  247. const NORMALIZER = {
  248. excludeModules: value => {
  249. if (!Array.isArray(value)) {
  250. value = value ? [value] : [];
  251. }
  252. return value.map(normalizeFilter);
  253. },
  254. excludeAssets: value => {
  255. if (!Array.isArray(value)) {
  256. value = value ? [value] : [];
  257. }
  258. return value.map(normalizeFilter);
  259. },
  260. warningsFilter: value => {
  261. if (!Array.isArray(value)) {
  262. value = value ? [value] : [];
  263. }
  264. return value.map(filter => {
  265. if (typeof filter === "string") {
  266. return (warning, warningString) => warningString.includes(filter);
  267. }
  268. if (filter instanceof RegExp) {
  269. return (warning, warningString) => filter.test(warningString);
  270. }
  271. if (typeof filter === "function") {
  272. return filter;
  273. }
  274. throw new Error(
  275. `Can only filter warnings with Strings or RegExps. (Given: ${filter})`
  276. );
  277. });
  278. },
  279. logging: value => {
  280. if (value === true) value = "log";
  281. return value;
  282. },
  283. loggingDebug: value => {
  284. if (!Array.isArray(value)) {
  285. value = value ? [value] : [];
  286. }
  287. return value.map(normalizeFilter);
  288. }
  289. };
  290. class DefaultStatsPresetPlugin {
  291. /**
  292. * Apply the plugin
  293. * @param {Compiler} compiler the compiler instance
  294. * @returns {void}
  295. */
  296. apply(compiler) {
  297. compiler.hooks.compilation.tap("DefaultStatsPresetPlugin", compilation => {
  298. for (const key of Object.keys(NAMED_PRESETS)) {
  299. const defaults = NAMED_PRESETS[key];
  300. compilation.hooks.statsPreset
  301. .for(key)
  302. .tap("DefaultStatsPresetPlugin", (options, context) => {
  303. applyDefaults(options, defaults);
  304. });
  305. }
  306. compilation.hooks.statsNormalize.tap(
  307. "DefaultStatsPresetPlugin",
  308. (options, context) => {
  309. for (const key of Object.keys(DEFAULTS)) {
  310. if (options[key] === undefined)
  311. options[key] = DEFAULTS[key](options, context, compilation);
  312. }
  313. for (const key of Object.keys(NORMALIZER)) {
  314. options[key] = NORMALIZER[key](options[key]);
  315. }
  316. }
  317. );
  318. });
  319. }
  320. }
  321. module.exports = DefaultStatsPresetPlugin;