DefaultStatsPresetPlugin.js 8.6 KB

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