source: trip-planner-front/node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js@ fa375fe

Last change on this file since fa375fe was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 38.8 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8/** @typedef {import("../Compiler")} Compiler */
9/** @typedef {import("./StatsPrinter")} StatsPrinter */
10/** @typedef {import("./StatsPrinter").StatsPrinterContext} StatsPrinterContext */
11
12const plural = (n, singular, plural) => (n === 1 ? singular : plural);
13
14/**
15 * @param {Record<string, number>} sizes sizes by source type
16 * @param {Object} options options
17 * @param {(number) => string=} options.formatSize size formatter
18 * @returns {string} text
19 */
20const printSizes = (sizes, { formatSize = n => `${n}` }) => {
21 const keys = Object.keys(sizes);
22 if (keys.length > 1) {
23 return keys.map(key => `${formatSize(sizes[key])} (${key})`).join(" ");
24 } else if (keys.length === 1) {
25 return formatSize(sizes[keys[0]]);
26 }
27};
28
29const mapLines = (str, fn) => str.split("\n").map(fn).join("\n");
30
31/**
32 * @param {number} n a number
33 * @returns {string} number as two digit string, leading 0
34 */
35const twoDigit = n => (n >= 10 ? `${n}` : `0${n}`);
36
37const isValidId = id => {
38 return typeof id === "number" || id;
39};
40
41/** @type {Record<string, (thing: any, context: StatsPrinterContext, printer: StatsPrinter) => string | void>} */
42const SIMPLE_PRINTERS = {
43 "compilation.summary!": (
44 _,
45 {
46 type,
47 bold,
48 green,
49 red,
50 yellow,
51 formatDateTime,
52 formatTime,
53 compilation: {
54 name,
55 hash,
56 version,
57 time,
58 builtAt,
59 errorsCount,
60 warningsCount
61 }
62 }
63 ) => {
64 const root = type === "compilation.summary!";
65 const warningsMessage =
66 warningsCount > 0
67 ? yellow(
68 `${warningsCount} ${plural(warningsCount, "warning", "warnings")}`
69 )
70 : "";
71 const errorsMessage =
72 errorsCount > 0
73 ? red(`${errorsCount} ${plural(errorsCount, "error", "errors")}`)
74 : "";
75 const timeMessage = root && time ? ` in ${formatTime(time)}` : "";
76 const hashMessage = hash ? ` (${hash})` : "";
77 const builtAtMessage =
78 root && builtAt ? `${formatDateTime(builtAt)}: ` : "";
79 const versionMessage = root && version ? `webpack ${version}` : "";
80 const nameMessage =
81 root && name
82 ? bold(name)
83 : name
84 ? `Child ${bold(name)}`
85 : root
86 ? ""
87 : "Child";
88 const subjectMessage =
89 nameMessage && versionMessage
90 ? `${nameMessage} (${versionMessage})`
91 : versionMessage || nameMessage || "webpack";
92 let statusMessage;
93 if (errorsMessage && warningsMessage) {
94 statusMessage = `compiled with ${errorsMessage} and ${warningsMessage}`;
95 } else if (errorsMessage) {
96 statusMessage = `compiled with ${errorsMessage}`;
97 } else if (warningsMessage) {
98 statusMessage = `compiled with ${warningsMessage}`;
99 } else if (errorsCount === 0 && warningsCount === 0) {
100 statusMessage = `compiled ${green("successfully")}`;
101 } else {
102 statusMessage = `compiled`;
103 }
104 if (
105 builtAtMessage ||
106 versionMessage ||
107 errorsMessage ||
108 warningsMessage ||
109 (errorsCount === 0 && warningsCount === 0) ||
110 timeMessage ||
111 hashMessage
112 )
113 return `${builtAtMessage}${subjectMessage} ${statusMessage}${timeMessage}${hashMessage}`;
114 },
115 "compilation.filteredWarningDetailsCount": count =>
116 count
117 ? `${count} ${plural(
118 count,
119 "warning has",
120 "warnings have"
121 )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.`
122 : undefined,
123 "compilation.filteredErrorDetailsCount": (count, { yellow }) =>
124 count
125 ? yellow(
126 `${count} ${plural(
127 count,
128 "error has",
129 "errors have"
130 )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.`
131 )
132 : undefined,
133 "compilation.env": (env, { bold }) =>
134 env
135 ? `Environment (--env): ${bold(JSON.stringify(env, null, 2))}`
136 : undefined,
137 "compilation.publicPath": (publicPath, { bold }) =>
138 `PublicPath: ${bold(publicPath || "(none)")}`,
139 "compilation.entrypoints": (entrypoints, context, printer) =>
140 Array.isArray(entrypoints)
141 ? undefined
142 : printer.print(context.type, Object.values(entrypoints), {
143 ...context,
144 chunkGroupKind: "Entrypoint"
145 }),
146 "compilation.namedChunkGroups": (namedChunkGroups, context, printer) => {
147 if (!Array.isArray(namedChunkGroups)) {
148 const {
149 compilation: { entrypoints }
150 } = context;
151 let chunkGroups = Object.values(namedChunkGroups);
152 if (entrypoints) {
153 chunkGroups = chunkGroups.filter(
154 group =>
155 !Object.prototype.hasOwnProperty.call(entrypoints, group.name)
156 );
157 }
158 return printer.print(context.type, chunkGroups, {
159 ...context,
160 chunkGroupKind: "Chunk Group"
161 });
162 }
163 },
164 "compilation.assetsByChunkName": () => "",
165
166 "compilation.filteredModules": filteredModules =>
167 filteredModules > 0
168 ? `${filteredModules} ${plural(filteredModules, "module", "modules")}`
169 : undefined,
170 "compilation.filteredAssets": (filteredAssets, { compilation: { assets } }) =>
171 filteredAssets > 0
172 ? `${filteredAssets} ${plural(filteredAssets, "asset", "assets")}`
173 : undefined,
174 "compilation.logging": (logging, context, printer) =>
175 Array.isArray(logging)
176 ? undefined
177 : printer.print(
178 context.type,
179 Object.entries(logging).map(([name, value]) => ({ ...value, name })),
180 context
181 ),
182 "compilation.warningsInChildren!": (_, { yellow, compilation }) => {
183 if (
184 !compilation.children &&
185 compilation.warningsCount > 0 &&
186 compilation.warnings
187 ) {
188 const childWarnings =
189 compilation.warningsCount - compilation.warnings.length;
190 if (childWarnings > 0) {
191 return yellow(
192 `${childWarnings} ${plural(
193 childWarnings,
194 "WARNING",
195 "WARNINGS"
196 )} in child compilations${
197 compilation.children
198 ? ""
199 : " (Use 'stats.children: true' resp. '--stats-children' for more details)"
200 }`
201 );
202 }
203 }
204 },
205 "compilation.errorsInChildren!": (_, { red, compilation }) => {
206 if (
207 !compilation.children &&
208 compilation.errorsCount > 0 &&
209 compilation.errors
210 ) {
211 const childErrors = compilation.errorsCount - compilation.errors.length;
212 if (childErrors > 0) {
213 return red(
214 `${childErrors} ${plural(
215 childErrors,
216 "ERROR",
217 "ERRORS"
218 )} in child compilations${
219 compilation.children
220 ? ""
221 : " (Use 'stats.children: true' resp. '--stats-children' for more details)"
222 }`
223 );
224 }
225 }
226 },
227
228 "asset.type": type => type,
229 "asset.name": (name, { formatFilename, asset: { isOverSizeLimit } }) =>
230 formatFilename(name, isOverSizeLimit),
231 "asset.size": (
232 size,
233 { asset: { isOverSizeLimit }, yellow, green, formatSize }
234 ) => (isOverSizeLimit ? yellow(formatSize(size)) : formatSize(size)),
235 "asset.emitted": (emitted, { green, formatFlag }) =>
236 emitted ? green(formatFlag("emitted")) : undefined,
237 "asset.comparedForEmit": (comparedForEmit, { yellow, formatFlag }) =>
238 comparedForEmit ? yellow(formatFlag("compared for emit")) : undefined,
239 "asset.cached": (cached, { green, formatFlag }) =>
240 cached ? green(formatFlag("cached")) : undefined,
241 "asset.isOverSizeLimit": (isOverSizeLimit, { yellow, formatFlag }) =>
242 isOverSizeLimit ? yellow(formatFlag("big")) : undefined,
243
244 "asset.info.immutable": (immutable, { green, formatFlag }) =>
245 immutable ? green(formatFlag("immutable")) : undefined,
246 "asset.info.javascriptModule": (javascriptModule, { formatFlag }) =>
247 javascriptModule ? formatFlag("javascript module") : undefined,
248 "asset.info.sourceFilename": (sourceFilename, { formatFlag }) =>
249 sourceFilename
250 ? formatFlag(
251 sourceFilename === true
252 ? "from source file"
253 : `from: ${sourceFilename}`
254 )
255 : undefined,
256 "asset.info.development": (development, { green, formatFlag }) =>
257 development ? green(formatFlag("dev")) : undefined,
258 "asset.info.hotModuleReplacement": (
259 hotModuleReplacement,
260 { green, formatFlag }
261 ) => (hotModuleReplacement ? green(formatFlag("hmr")) : undefined),
262 "asset.separator!": () => "\n",
263 "asset.filteredRelated": (filteredRelated, { asset: { related } }) =>
264 filteredRelated > 0
265 ? `${filteredRelated} related ${plural(
266 filteredRelated,
267 "asset",
268 "assets"
269 )}`
270 : undefined,
271 "asset.filteredChildren": filteredChildren =>
272 filteredChildren > 0
273 ? `${filteredChildren} ${plural(filteredChildren, "asset", "assets")}`
274 : undefined,
275
276 assetChunk: (id, { formatChunkId }) => formatChunkId(id),
277
278 assetChunkName: name => name,
279 assetChunkIdHint: name => name,
280
281 "module.type": type => (type !== "module" ? type : undefined),
282 "module.id": (id, { formatModuleId }) =>
283 isValidId(id) ? formatModuleId(id) : undefined,
284 "module.name": (name, { bold }) => {
285 const [, prefix, resource] = /^(.*!)?([^!]*)$/.exec(name);
286 return (prefix || "") + bold(resource);
287 },
288 "module.identifier": identifier => undefined,
289 "module.layer": (layer, { formatLayer }) =>
290 layer ? formatLayer(layer) : undefined,
291 "module.sizes": printSizes,
292 "module.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
293 "module.depth": (depth, { formatFlag }) =>
294 depth !== null ? formatFlag(`depth ${depth}`) : undefined,
295 "module.cacheable": (cacheable, { formatFlag, red }) =>
296 cacheable === false ? red(formatFlag("not cacheable")) : undefined,
297 "module.orphan": (orphan, { formatFlag, yellow }) =>
298 orphan ? yellow(formatFlag("orphan")) : undefined,
299 "module.runtime": (runtime, { formatFlag, yellow }) =>
300 runtime ? yellow(formatFlag("runtime")) : undefined,
301 "module.optional": (optional, { formatFlag, yellow }) =>
302 optional ? yellow(formatFlag("optional")) : undefined,
303 "module.dependent": (dependent, { formatFlag, cyan }) =>
304 dependent ? cyan(formatFlag("dependent")) : undefined,
305 "module.built": (built, { formatFlag, yellow }) =>
306 built ? yellow(formatFlag("built")) : undefined,
307 "module.codeGenerated": (codeGenerated, { formatFlag, yellow }) =>
308 codeGenerated ? yellow(formatFlag("code generated")) : undefined,
309 "module.buildTimeExecuted": (buildTimeExecuted, { formatFlag, green }) =>
310 buildTimeExecuted ? green(formatFlag("build time executed")) : undefined,
311 "module.cached": (cached, { formatFlag, green }) =>
312 cached ? green(formatFlag("cached")) : undefined,
313 "module.assets": (assets, { formatFlag, magenta }) =>
314 assets && assets.length
315 ? magenta(
316 formatFlag(
317 `${assets.length} ${plural(assets.length, "asset", "assets")}`
318 )
319 )
320 : undefined,
321 "module.warnings": (warnings, { formatFlag, yellow }) =>
322 warnings === true
323 ? yellow(formatFlag("warnings"))
324 : warnings
325 ? yellow(
326 formatFlag(`${warnings} ${plural(warnings, "warning", "warnings")}`)
327 )
328 : undefined,
329 "module.errors": (errors, { formatFlag, red }) =>
330 errors === true
331 ? red(formatFlag("errors"))
332 : errors
333 ? red(formatFlag(`${errors} ${plural(errors, "error", "errors")}`))
334 : undefined,
335 "module.providedExports": (providedExports, { formatFlag, cyan }) => {
336 if (Array.isArray(providedExports)) {
337 if (providedExports.length === 0) return cyan(formatFlag("no exports"));
338 return cyan(formatFlag(`exports: ${providedExports.join(", ")}`));
339 }
340 },
341 "module.usedExports": (usedExports, { formatFlag, cyan, module }) => {
342 if (usedExports !== true) {
343 if (usedExports === null) return cyan(formatFlag("used exports unknown"));
344 if (usedExports === false) return cyan(formatFlag("module unused"));
345 if (Array.isArray(usedExports)) {
346 if (usedExports.length === 0)
347 return cyan(formatFlag("no exports used"));
348 const providedExportsCount = Array.isArray(module.providedExports)
349 ? module.providedExports.length
350 : null;
351 if (
352 providedExportsCount !== null &&
353 providedExportsCount === usedExports.length
354 ) {
355 return cyan(formatFlag("all exports used"));
356 } else {
357 return cyan(
358 formatFlag(`only some exports used: ${usedExports.join(", ")}`)
359 );
360 }
361 }
362 }
363 },
364 "module.optimizationBailout[]": (optimizationBailout, { yellow }) =>
365 yellow(optimizationBailout),
366 "module.issuerPath": (issuerPath, { module }) =>
367 module.profile ? undefined : "",
368 "module.profile": profile => undefined,
369 "module.filteredModules": filteredModules =>
370 filteredModules > 0
371 ? `${filteredModules} nested ${plural(
372 filteredModules,
373 "module",
374 "modules"
375 )}`
376 : undefined,
377 "module.filteredReasons": filteredReasons =>
378 filteredReasons > 0
379 ? `${filteredReasons} ${plural(filteredReasons, "reason", "reasons")}`
380 : undefined,
381 "module.filteredChildren": filteredChildren =>
382 filteredChildren > 0
383 ? `${filteredChildren} ${plural(filteredChildren, "module", "modules")}`
384 : undefined,
385 "module.separator!": () => "\n",
386
387 "moduleIssuer.id": (id, { formatModuleId }) => formatModuleId(id),
388 "moduleIssuer.profile.total": (value, { formatTime }) => formatTime(value),
389
390 "moduleReason.type": type => type,
391 "moduleReason.userRequest": (userRequest, { cyan }) => cyan(userRequest),
392 "moduleReason.moduleId": (moduleId, { formatModuleId }) =>
393 isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
394 "moduleReason.module": (module, { magenta }) => magenta(module),
395 "moduleReason.loc": loc => loc,
396 "moduleReason.explanation": (explanation, { cyan }) => cyan(explanation),
397 "moduleReason.active": (active, { formatFlag }) =>
398 active ? undefined : formatFlag("inactive"),
399 "moduleReason.resolvedModule": (module, { magenta }) => magenta(module),
400 "moduleReason.filteredChildren": filteredChildren =>
401 filteredChildren > 0
402 ? `${filteredChildren} ${plural(filteredChildren, "reason", "reasons")}`
403 : undefined,
404
405 "module.profile.total": (value, { formatTime }) => formatTime(value),
406 "module.profile.resolving": (value, { formatTime }) =>
407 `resolving: ${formatTime(value)}`,
408 "module.profile.restoring": (value, { formatTime }) =>
409 `restoring: ${formatTime(value)}`,
410 "module.profile.integration": (value, { formatTime }) =>
411 `integration: ${formatTime(value)}`,
412 "module.profile.building": (value, { formatTime }) =>
413 `building: ${formatTime(value)}`,
414 "module.profile.storing": (value, { formatTime }) =>
415 `storing: ${formatTime(value)}`,
416 "module.profile.additionalResolving": (value, { formatTime }) =>
417 value ? `additional resolving: ${formatTime(value)}` : undefined,
418 "module.profile.additionalIntegration": (value, { formatTime }) =>
419 value ? `additional integration: ${formatTime(value)}` : undefined,
420
421 "chunkGroup.kind!": (_, { chunkGroupKind }) => chunkGroupKind,
422 "chunkGroup.separator!": () => "\n",
423 "chunkGroup.name": (name, { bold }) => bold(name),
424 "chunkGroup.isOverSizeLimit": (isOverSizeLimit, { formatFlag, yellow }) =>
425 isOverSizeLimit ? yellow(formatFlag("big")) : undefined,
426 "chunkGroup.assetsSize": (size, { formatSize }) =>
427 size ? formatSize(size) : undefined,
428 "chunkGroup.auxiliaryAssetsSize": (size, { formatSize }) =>
429 size ? `(${formatSize(size)})` : undefined,
430 "chunkGroup.filteredAssets": n =>
431 n > 0 ? `${n} ${plural(n, "asset", "assets")}` : undefined,
432 "chunkGroup.filteredAuxiliaryAssets": n =>
433 n > 0 ? `${n} auxiliary ${plural(n, "asset", "assets")}` : undefined,
434 "chunkGroup.is!": () => "=",
435 "chunkGroupAsset.name": (asset, { green }) => green(asset),
436 "chunkGroupAsset.size": (size, { formatSize, chunkGroup }) =>
437 chunkGroup.assets.length > 1 ||
438 (chunkGroup.auxiliaryAssets && chunkGroup.auxiliaryAssets.length > 0)
439 ? formatSize(size)
440 : undefined,
441 "chunkGroup.children": (children, context, printer) =>
442 Array.isArray(children)
443 ? undefined
444 : printer.print(
445 context.type,
446 Object.keys(children).map(key => ({
447 type: key,
448 children: children[key]
449 })),
450 context
451 ),
452 "chunkGroupChildGroup.type": type => `${type}:`,
453 "chunkGroupChild.assets[]": (file, { formatFilename }) =>
454 formatFilename(file),
455 "chunkGroupChild.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
456 "chunkGroupChild.name": name => (name ? `(name: ${name})` : undefined),
457
458 "chunk.id": (id, { formatChunkId }) => formatChunkId(id),
459 "chunk.files[]": (file, { formatFilename }) => formatFilename(file),
460 "chunk.names[]": name => name,
461 "chunk.idHints[]": name => name,
462 "chunk.runtime[]": name => name,
463 "chunk.sizes": (sizes, context) => printSizes(sizes, context),
464 "chunk.parents[]": (parents, context) =>
465 context.formatChunkId(parents, "parent"),
466 "chunk.siblings[]": (siblings, context) =>
467 context.formatChunkId(siblings, "sibling"),
468 "chunk.children[]": (children, context) =>
469 context.formatChunkId(children, "child"),
470 "chunk.childrenByOrder": (childrenByOrder, context, printer) =>
471 Array.isArray(childrenByOrder)
472 ? undefined
473 : printer.print(
474 context.type,
475 Object.keys(childrenByOrder).map(key => ({
476 type: key,
477 children: childrenByOrder[key]
478 })),
479 context
480 ),
481 "chunk.childrenByOrder[].type": type => `${type}:`,
482 "chunk.childrenByOrder[].children[]": (id, { formatChunkId }) =>
483 isValidId(id) ? formatChunkId(id) : undefined,
484 "chunk.entry": (entry, { formatFlag, yellow }) =>
485 entry ? yellow(formatFlag("entry")) : undefined,
486 "chunk.initial": (initial, { formatFlag, yellow }) =>
487 initial ? yellow(formatFlag("initial")) : undefined,
488 "chunk.rendered": (rendered, { formatFlag, green }) =>
489 rendered ? green(formatFlag("rendered")) : undefined,
490 "chunk.recorded": (recorded, { formatFlag, green }) =>
491 recorded ? green(formatFlag("recorded")) : undefined,
492 "chunk.reason": (reason, { yellow }) => (reason ? yellow(reason) : undefined),
493 "chunk.filteredModules": filteredModules =>
494 filteredModules > 0
495 ? `${filteredModules} chunk ${plural(
496 filteredModules,
497 "module",
498 "modules"
499 )}`
500 : undefined,
501 "chunk.separator!": () => "\n",
502
503 "chunkOrigin.request": request => request,
504 "chunkOrigin.moduleId": (moduleId, { formatModuleId }) =>
505 isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
506 "chunkOrigin.moduleName": (moduleName, { bold }) => bold(moduleName),
507 "chunkOrigin.loc": loc => loc,
508
509 "error.compilerPath": (compilerPath, { bold }) =>
510 compilerPath ? bold(`(${compilerPath})`) : undefined,
511 "error.chunkId": (chunkId, { formatChunkId }) =>
512 isValidId(chunkId) ? formatChunkId(chunkId) : undefined,
513 "error.chunkEntry": (chunkEntry, { formatFlag }) =>
514 chunkEntry ? formatFlag("entry") : undefined,
515 "error.chunkInitial": (chunkInitial, { formatFlag }) =>
516 chunkInitial ? formatFlag("initial") : undefined,
517 "error.file": (file, { bold }) => bold(file),
518 "error.moduleName": (moduleName, { bold }) => {
519 return moduleName.includes("!")
520 ? `${bold(moduleName.replace(/^(\s|\S)*!/, ""))} (${moduleName})`
521 : `${bold(moduleName)}`;
522 },
523 "error.loc": (loc, { green }) => green(loc),
524 "error.message": (message, { bold, formatError }) =>
525 message.includes("\u001b[") ? message : bold(formatError(message)),
526 "error.details": (details, { formatError }) => formatError(details),
527 "error.stack": stack => stack,
528 "error.moduleTrace": moduleTrace => undefined,
529 "error.separator!": () => "\n",
530
531 "loggingEntry(error).loggingEntry.message": (message, { red }) =>
532 mapLines(message, x => `<e> ${red(x)}`),
533 "loggingEntry(warn).loggingEntry.message": (message, { yellow }) =>
534 mapLines(message, x => `<w> ${yellow(x)}`),
535 "loggingEntry(info).loggingEntry.message": (message, { green }) =>
536 mapLines(message, x => `<i> ${green(x)}`),
537 "loggingEntry(log).loggingEntry.message": (message, { bold }) =>
538 mapLines(message, x => ` ${bold(x)}`),
539 "loggingEntry(debug).loggingEntry.message": message =>
540 mapLines(message, x => ` ${x}`),
541 "loggingEntry(trace).loggingEntry.message": message =>
542 mapLines(message, x => ` ${x}`),
543 "loggingEntry(status).loggingEntry.message": (message, { magenta }) =>
544 mapLines(message, x => `<s> ${magenta(x)}`),
545 "loggingEntry(profile).loggingEntry.message": (message, { magenta }) =>
546 mapLines(message, x => `<p> ${magenta(x)}`),
547 "loggingEntry(profileEnd).loggingEntry.message": (message, { magenta }) =>
548 mapLines(message, x => `</p> ${magenta(x)}`),
549 "loggingEntry(time).loggingEntry.message": (message, { magenta }) =>
550 mapLines(message, x => `<t> ${magenta(x)}`),
551 "loggingEntry(group).loggingEntry.message": (message, { cyan }) =>
552 mapLines(message, x => `<-> ${cyan(x)}`),
553 "loggingEntry(groupCollapsed).loggingEntry.message": (message, { cyan }) =>
554 mapLines(message, x => `<+> ${cyan(x)}`),
555 "loggingEntry(clear).loggingEntry": () => " -------",
556 "loggingEntry(groupCollapsed).loggingEntry.children": () => "",
557 "loggingEntry.trace[]": trace =>
558 trace ? mapLines(trace, x => `| ${x}`) : undefined,
559
560 "moduleTraceItem.originName": originName => originName,
561
562 loggingGroup: loggingGroup =>
563 loggingGroup.entries.length === 0 ? "" : undefined,
564 "loggingGroup.debug": (flag, { red }) => (flag ? red("DEBUG") : undefined),
565 "loggingGroup.name": (name, { bold }) => bold(`LOG from ${name}`),
566 "loggingGroup.separator!": () => "\n",
567 "loggingGroup.filteredEntries": filteredEntries =>
568 filteredEntries > 0 ? `+ ${filteredEntries} hidden lines` : undefined,
569
570 "moduleTraceDependency.loc": loc => loc
571};
572
573/** @type {Record<string, string | Function>} */
574const ITEM_NAMES = {
575 "compilation.assets[]": "asset",
576 "compilation.modules[]": "module",
577 "compilation.chunks[]": "chunk",
578 "compilation.entrypoints[]": "chunkGroup",
579 "compilation.namedChunkGroups[]": "chunkGroup",
580 "compilation.errors[]": "error",
581 "compilation.warnings[]": "error",
582 "compilation.logging[]": "loggingGroup",
583 "compilation.children[]": "compilation",
584 "asset.related[]": "asset",
585 "asset.children[]": "asset",
586 "asset.chunks[]": "assetChunk",
587 "asset.auxiliaryChunks[]": "assetChunk",
588 "asset.chunkNames[]": "assetChunkName",
589 "asset.chunkIdHints[]": "assetChunkIdHint",
590 "asset.auxiliaryChunkNames[]": "assetChunkName",
591 "asset.auxiliaryChunkIdHints[]": "assetChunkIdHint",
592 "chunkGroup.assets[]": "chunkGroupAsset",
593 "chunkGroup.auxiliaryAssets[]": "chunkGroupAsset",
594 "chunkGroupChild.assets[]": "chunkGroupAsset",
595 "chunkGroupChild.auxiliaryAssets[]": "chunkGroupAsset",
596 "chunkGroup.children[]": "chunkGroupChildGroup",
597 "chunkGroupChildGroup.children[]": "chunkGroupChild",
598 "module.modules[]": "module",
599 "module.children[]": "module",
600 "module.reasons[]": "moduleReason",
601 "moduleReason.children[]": "moduleReason",
602 "module.issuerPath[]": "moduleIssuer",
603 "chunk.origins[]": "chunkOrigin",
604 "chunk.modules[]": "module",
605 "loggingGroup.entries[]": logEntry =>
606 `loggingEntry(${logEntry.type}).loggingEntry`,
607 "loggingEntry.children[]": logEntry =>
608 `loggingEntry(${logEntry.type}).loggingEntry`,
609 "error.moduleTrace[]": "moduleTraceItem",
610 "moduleTraceItem.dependencies[]": "moduleTraceDependency"
611};
612
613const ERROR_PREFERRED_ORDER = [
614 "compilerPath",
615 "chunkId",
616 "chunkEntry",
617 "chunkInitial",
618 "file",
619 "separator!",
620 "moduleName",
621 "loc",
622 "separator!",
623 "message",
624 "separator!",
625 "details",
626 "separator!",
627 "stack",
628 "separator!",
629 "missing",
630 "separator!",
631 "moduleTrace"
632];
633
634/** @type {Record<string, string[]>} */
635const PREFERRED_ORDERS = {
636 compilation: [
637 "name",
638 "hash",
639 "version",
640 "time",
641 "builtAt",
642 "env",
643 "publicPath",
644 "assets",
645 "filteredAssets",
646 "entrypoints",
647 "namedChunkGroups",
648 "chunks",
649 "modules",
650 "filteredModules",
651 "children",
652 "logging",
653 "warnings",
654 "warningsInChildren!",
655 "filteredWarningDetailsCount",
656 "errors",
657 "errorsInChildren!",
658 "filteredErrorDetailsCount",
659 "summary!",
660 "needAdditionalPass"
661 ],
662 asset: [
663 "type",
664 "name",
665 "size",
666 "chunks",
667 "auxiliaryChunks",
668 "emitted",
669 "comparedForEmit",
670 "cached",
671 "info",
672 "isOverSizeLimit",
673 "chunkNames",
674 "auxiliaryChunkNames",
675 "chunkIdHints",
676 "auxiliaryChunkIdHints",
677 "related",
678 "filteredRelated",
679 "children",
680 "filteredChildren"
681 ],
682 "asset.info": [
683 "immutable",
684 "sourceFilename",
685 "javascriptModule",
686 "development",
687 "hotModuleReplacement"
688 ],
689 chunkGroup: [
690 "kind!",
691 "name",
692 "isOverSizeLimit",
693 "assetsSize",
694 "auxiliaryAssetsSize",
695 "is!",
696 "assets",
697 "filteredAssets",
698 "auxiliaryAssets",
699 "filteredAuxiliaryAssets",
700 "separator!",
701 "children"
702 ],
703 chunkGroupAsset: ["name", "size"],
704 chunkGroupChildGroup: ["type", "children"],
705 chunkGroupChild: ["assets", "chunks", "name"],
706 module: [
707 "type",
708 "name",
709 "identifier",
710 "id",
711 "layer",
712 "sizes",
713 "chunks",
714 "depth",
715 "cacheable",
716 "orphan",
717 "runtime",
718 "optional",
719 "dependent",
720 "built",
721 "codeGenerated",
722 "cached",
723 "assets",
724 "failed",
725 "warnings",
726 "errors",
727 "children",
728 "filteredChildren",
729 "providedExports",
730 "usedExports",
731 "optimizationBailout",
732 "reasons",
733 "filteredReasons",
734 "issuerPath",
735 "profile",
736 "modules",
737 "filteredModules"
738 ],
739 moduleReason: [
740 "active",
741 "type",
742 "userRequest",
743 "moduleId",
744 "module",
745 "resolvedModule",
746 "loc",
747 "explanation",
748 "children",
749 "filteredChildren"
750 ],
751 "module.profile": [
752 "total",
753 "separator!",
754 "resolving",
755 "restoring",
756 "integration",
757 "building",
758 "storing",
759 "additionalResolving",
760 "additionalIntegration"
761 ],
762 chunk: [
763 "id",
764 "runtime",
765 "files",
766 "names",
767 "idHints",
768 "sizes",
769 "parents",
770 "siblings",
771 "children",
772 "childrenByOrder",
773 "entry",
774 "initial",
775 "rendered",
776 "recorded",
777 "reason",
778 "separator!",
779 "origins",
780 "separator!",
781 "modules",
782 "separator!",
783 "filteredModules"
784 ],
785 chunkOrigin: ["request", "moduleId", "moduleName", "loc"],
786 error: ERROR_PREFERRED_ORDER,
787 warning: ERROR_PREFERRED_ORDER,
788 "chunk.childrenByOrder[]": ["type", "children"],
789 loggingGroup: [
790 "debug",
791 "name",
792 "separator!",
793 "entries",
794 "separator!",
795 "filteredEntries"
796 ],
797 loggingEntry: ["message", "trace", "children"]
798};
799
800const itemsJoinOneLine = items => items.filter(Boolean).join(" ");
801const itemsJoinOneLineBrackets = items =>
802 items.length > 0 ? `(${items.filter(Boolean).join(" ")})` : undefined;
803const itemsJoinMoreSpacing = items => items.filter(Boolean).join("\n\n");
804const itemsJoinComma = items => items.filter(Boolean).join(", ");
805const itemsJoinCommaBrackets = items =>
806 items.length > 0 ? `(${items.filter(Boolean).join(", ")})` : undefined;
807const itemsJoinCommaBracketsWithName = name => items =>
808 items.length > 0
809 ? `(${name}: ${items.filter(Boolean).join(", ")})`
810 : undefined;
811
812/** @type {Record<string, (items: string[]) => string>} */
813const SIMPLE_ITEMS_JOINER = {
814 "chunk.parents": itemsJoinOneLine,
815 "chunk.siblings": itemsJoinOneLine,
816 "chunk.children": itemsJoinOneLine,
817 "chunk.names": itemsJoinCommaBrackets,
818 "chunk.idHints": itemsJoinCommaBracketsWithName("id hint"),
819 "chunk.runtime": itemsJoinCommaBracketsWithName("runtime"),
820 "chunk.files": itemsJoinComma,
821 "chunk.childrenByOrder": itemsJoinOneLine,
822 "chunk.childrenByOrder[].children": itemsJoinOneLine,
823 "chunkGroup.assets": itemsJoinOneLine,
824 "chunkGroup.auxiliaryAssets": itemsJoinOneLineBrackets,
825 "chunkGroupChildGroup.children": itemsJoinComma,
826 "chunkGroupChild.assets": itemsJoinOneLine,
827 "chunkGroupChild.auxiliaryAssets": itemsJoinOneLineBrackets,
828 "asset.chunks": itemsJoinComma,
829 "asset.auxiliaryChunks": itemsJoinCommaBrackets,
830 "asset.chunkNames": itemsJoinCommaBracketsWithName("name"),
831 "asset.auxiliaryChunkNames": itemsJoinCommaBracketsWithName("auxiliary name"),
832 "asset.chunkIdHints": itemsJoinCommaBracketsWithName("id hint"),
833 "asset.auxiliaryChunkIdHints":
834 itemsJoinCommaBracketsWithName("auxiliary id hint"),
835 "module.chunks": itemsJoinOneLine,
836 "module.issuerPath": items =>
837 items
838 .filter(Boolean)
839 .map(item => `${item} ->`)
840 .join(" "),
841 "compilation.errors": itemsJoinMoreSpacing,
842 "compilation.warnings": itemsJoinMoreSpacing,
843 "compilation.logging": itemsJoinMoreSpacing,
844 "compilation.children": items => indent(itemsJoinMoreSpacing(items), " "),
845 "moduleTraceItem.dependencies": itemsJoinOneLine,
846 "loggingEntry.children": items =>
847 indent(items.filter(Boolean).join("\n"), " ", false)
848};
849
850const joinOneLine = items =>
851 items
852 .map(item => item.content)
853 .filter(Boolean)
854 .join(" ");
855
856const joinInBrackets = items => {
857 const res = [];
858 let mode = 0;
859 for (const item of items) {
860 if (item.element === "separator!") {
861 switch (mode) {
862 case 0:
863 case 1:
864 mode += 2;
865 break;
866 case 4:
867 res.push(")");
868 mode = 3;
869 break;
870 }
871 }
872 if (!item.content) continue;
873 switch (mode) {
874 case 0:
875 mode = 1;
876 break;
877 case 1:
878 res.push(" ");
879 break;
880 case 2:
881 res.push("(");
882 mode = 4;
883 break;
884 case 3:
885 res.push(" (");
886 mode = 4;
887 break;
888 case 4:
889 res.push(", ");
890 break;
891 }
892 res.push(item.content);
893 }
894 if (mode === 4) res.push(")");
895 return res.join("");
896};
897
898const indent = (str, prefix, noPrefixInFirstLine) => {
899 const rem = str.replace(/\n([^\n])/g, "\n" + prefix + "$1");
900 if (noPrefixInFirstLine) return rem;
901 const ind = str[0] === "\n" ? "" : prefix;
902 return ind + rem;
903};
904
905const joinExplicitNewLine = (items, indenter) => {
906 let firstInLine = true;
907 let first = true;
908 return items
909 .map(item => {
910 if (!item || !item.content) return;
911 let content = indent(item.content, first ? "" : indenter, !firstInLine);
912 if (firstInLine) {
913 content = content.replace(/^\n+/, "");
914 }
915 if (!content) return;
916 first = false;
917 const noJoiner = firstInLine || content.startsWith("\n");
918 firstInLine = content.endsWith("\n");
919 return noJoiner ? content : " " + content;
920 })
921 .filter(Boolean)
922 .join("")
923 .trim();
924};
925
926const joinError =
927 error =>
928 (items, { red, yellow }) =>
929 `${error ? red("ERROR") : yellow("WARNING")} in ${joinExplicitNewLine(
930 items,
931 ""
932 )}`;
933
934/** @type {Record<string, (items: ({ element: string, content: string })[], context: StatsPrinterContext) => string>} */
935const SIMPLE_ELEMENT_JOINERS = {
936 compilation: items => {
937 const result = [];
938 let lastNeedMore = false;
939 for (const item of items) {
940 if (!item.content) continue;
941 const needMoreSpace =
942 item.element === "warnings" ||
943 item.element === "filteredWarningDetailsCount" ||
944 item.element === "errors" ||
945 item.element === "filteredErrorDetailsCount" ||
946 item.element === "logging";
947 if (result.length !== 0) {
948 result.push(needMoreSpace || lastNeedMore ? "\n\n" : "\n");
949 }
950 result.push(item.content);
951 lastNeedMore = needMoreSpace;
952 }
953 if (lastNeedMore) result.push("\n");
954 return result.join("");
955 },
956 asset: items =>
957 joinExplicitNewLine(
958 items.map(item => {
959 if (
960 (item.element === "related" || item.element === "children") &&
961 item.content
962 ) {
963 return {
964 ...item,
965 content: `\n${item.content}\n`
966 };
967 }
968 return item;
969 }),
970 " "
971 ),
972 "asset.info": joinOneLine,
973 module: (items, { module }) => {
974 let hasName = false;
975 return joinExplicitNewLine(
976 items.map(item => {
977 switch (item.element) {
978 case "id":
979 if (module.id === module.name) {
980 if (hasName) return false;
981 if (item.content) hasName = true;
982 }
983 break;
984 case "name":
985 if (hasName) return false;
986 if (item.content) hasName = true;
987 break;
988 case "providedExports":
989 case "usedExports":
990 case "optimizationBailout":
991 case "reasons":
992 case "issuerPath":
993 case "profile":
994 case "children":
995 case "modules":
996 if (item.content) {
997 return {
998 ...item,
999 content: `\n${item.content}\n`
1000 };
1001 }
1002 break;
1003 }
1004 return item;
1005 }),
1006 " "
1007 );
1008 },
1009 chunk: items => {
1010 let hasEntry = false;
1011 return (
1012 "chunk " +
1013 joinExplicitNewLine(
1014 items.filter(item => {
1015 switch (item.element) {
1016 case "entry":
1017 if (item.content) hasEntry = true;
1018 break;
1019 case "initial":
1020 if (hasEntry) return false;
1021 break;
1022 }
1023 return true;
1024 }),
1025 " "
1026 )
1027 );
1028 },
1029 "chunk.childrenByOrder[]": items => `(${joinOneLine(items)})`,
1030 chunkGroup: items => joinExplicitNewLine(items, " "),
1031 chunkGroupAsset: joinOneLine,
1032 chunkGroupChildGroup: joinOneLine,
1033 chunkGroupChild: joinOneLine,
1034 // moduleReason: (items, { moduleReason }) => {
1035 // let hasName = false;
1036 // return joinOneLine(
1037 // items.filter(item => {
1038 // switch (item.element) {
1039 // case "moduleId":
1040 // if (moduleReason.moduleId === moduleReason.module && item.content)
1041 // hasName = true;
1042 // break;
1043 // case "module":
1044 // if (hasName) return false;
1045 // break;
1046 // case "resolvedModule":
1047 // return (
1048 // moduleReason.module !== moduleReason.resolvedModule &&
1049 // item.content
1050 // );
1051 // }
1052 // return true;
1053 // })
1054 // );
1055 // },
1056 moduleReason: (items, { moduleReason }) => {
1057 let hasName = false;
1058 return joinExplicitNewLine(
1059 items.map(item => {
1060 switch (item.element) {
1061 case "moduleId":
1062 if (moduleReason.moduleId === moduleReason.module && item.content)
1063 hasName = true;
1064 break;
1065 case "module":
1066 if (hasName) return false;
1067 break;
1068 case "resolvedModule":
1069 if (moduleReason.module === moduleReason.resolvedModule)
1070 return false;
1071 break;
1072 case "children":
1073 if (item.content) {
1074 return {
1075 ...item,
1076 content: `\n${item.content}\n`
1077 };
1078 }
1079 break;
1080 }
1081 return item;
1082 }),
1083 " "
1084 );
1085 },
1086 "module.profile": joinInBrackets,
1087 moduleIssuer: joinOneLine,
1088 chunkOrigin: items => "> " + joinOneLine(items),
1089 "errors[].error": joinError(true),
1090 "warnings[].error": joinError(false),
1091 loggingGroup: items => joinExplicitNewLine(items, "").trimRight(),
1092 moduleTraceItem: items => " @ " + joinOneLine(items),
1093 moduleTraceDependency: joinOneLine
1094};
1095
1096const AVAILABLE_COLORS = {
1097 bold: "\u001b[1m",
1098 yellow: "\u001b[1m\u001b[33m",
1099 red: "\u001b[1m\u001b[31m",
1100 green: "\u001b[1m\u001b[32m",
1101 cyan: "\u001b[1m\u001b[36m",
1102 magenta: "\u001b[1m\u001b[35m"
1103};
1104
1105const AVAILABLE_FORMATS = {
1106 formatChunkId: (id, { yellow }, direction) => {
1107 switch (direction) {
1108 case "parent":
1109 return `<{${yellow(id)}}>`;
1110 case "sibling":
1111 return `={${yellow(id)}}=`;
1112 case "child":
1113 return `>{${yellow(id)}}<`;
1114 default:
1115 return `{${yellow(id)}}`;
1116 }
1117 },
1118 formatModuleId: id => `[${id}]`,
1119 formatFilename: (filename, { green, yellow }, oversize) =>
1120 (oversize ? yellow : green)(filename),
1121 formatFlag: flag => `[${flag}]`,
1122 formatLayer: layer => `(in ${layer})`,
1123 formatSize: require("../SizeFormatHelpers").formatSize,
1124 formatDateTime: (dateTime, { bold }) => {
1125 const d = new Date(dateTime);
1126 const x = twoDigit;
1127 const date = `${d.getFullYear()}-${x(d.getMonth() + 1)}-${x(d.getDate())}`;
1128 const time = `${x(d.getHours())}:${x(d.getMinutes())}:${x(d.getSeconds())}`;
1129 return `${date} ${bold(time)}`;
1130 },
1131 formatTime: (
1132 time,
1133 { timeReference, bold, green, yellow, red },
1134 boldQuantity
1135 ) => {
1136 const unit = " ms";
1137 if (timeReference && time !== timeReference) {
1138 const times = [
1139 timeReference / 2,
1140 timeReference / 4,
1141 timeReference / 8,
1142 timeReference / 16
1143 ];
1144 if (time < times[3]) return `${time}${unit}`;
1145 else if (time < times[2]) return bold(`${time}${unit}`);
1146 else if (time < times[1]) return green(`${time}${unit}`);
1147 else if (time < times[0]) return yellow(`${time}${unit}`);
1148 else return red(`${time}${unit}`);
1149 } else {
1150 return `${boldQuantity ? bold(time) : time}${unit}`;
1151 }
1152 },
1153 formatError: (message, { green, yellow, red }) => {
1154 if (message.includes("\u001b[")) return message;
1155 const highlights = [
1156 { regExp: /(Did you mean .+)/g, format: green },
1157 {
1158 regExp: /(Set 'mode' option to 'development' or 'production')/g,
1159 format: green
1160 },
1161 { regExp: /(\(module has no exports\))/g, format: red },
1162 { regExp: /\(possible exports: (.+)\)/g, format: green },
1163 { regExp: /\s*(.+ doesn't exist)/g, format: red },
1164 { regExp: /('\w+' option has not been set)/g, format: red },
1165 {
1166 regExp: /(Emitted value instead of an instance of Error)/g,
1167 format: yellow
1168 },
1169 { regExp: /(Used? .+ instead)/gi, format: yellow },
1170 { regExp: /\b(deprecated|must|required)\b/g, format: yellow },
1171 {
1172 regExp: /\b(BREAKING CHANGE)\b/gi,
1173 format: red
1174 },
1175 {
1176 regExp:
1177 /\b(error|failed|unexpected|invalid|not found|not supported|not available|not possible|not implemented|doesn't support|conflict|conflicting|not existing|duplicate)\b/gi,
1178 format: red
1179 }
1180 ];
1181 for (const { regExp, format } of highlights) {
1182 message = message.replace(regExp, (match, content) => {
1183 return match.replace(content, format(content));
1184 });
1185 }
1186 return message;
1187 }
1188};
1189
1190const RESULT_MODIFIER = {
1191 "module.modules": result => {
1192 return indent(result, "| ");
1193 }
1194};
1195
1196const createOrder = (array, preferredOrder) => {
1197 const originalArray = array.slice();
1198 const set = new Set(array);
1199 const usedSet = new Set();
1200 array.length = 0;
1201 for (const element of preferredOrder) {
1202 if (element.endsWith("!") || set.has(element)) {
1203 array.push(element);
1204 usedSet.add(element);
1205 }
1206 }
1207 for (const element of originalArray) {
1208 if (!usedSet.has(element)) {
1209 array.push(element);
1210 }
1211 }
1212 return array;
1213};
1214
1215class DefaultStatsPrinterPlugin {
1216 /**
1217 * Apply the plugin
1218 * @param {Compiler} compiler the compiler instance
1219 * @returns {void}
1220 */
1221 apply(compiler) {
1222 compiler.hooks.compilation.tap("DefaultStatsPrinterPlugin", compilation => {
1223 compilation.hooks.statsPrinter.tap(
1224 "DefaultStatsPrinterPlugin",
1225 (stats, options, context) => {
1226 // Put colors into context
1227 stats.hooks.print
1228 .for("compilation")
1229 .tap("DefaultStatsPrinterPlugin", (compilation, context) => {
1230 for (const color of Object.keys(AVAILABLE_COLORS)) {
1231 let start;
1232 if (options.colors) {
1233 if (
1234 typeof options.colors === "object" &&
1235 typeof options.colors[color] === "string"
1236 ) {
1237 start = options.colors[color];
1238 } else {
1239 start = AVAILABLE_COLORS[color];
1240 }
1241 }
1242 if (start) {
1243 context[color] = str =>
1244 `${start}${
1245 typeof str === "string"
1246 ? str.replace(
1247 /((\u001b\[39m|\u001b\[22m|\u001b\[0m)+)/g,
1248 `$1${start}`
1249 )
1250 : str
1251 }\u001b[39m\u001b[22m`;
1252 } else {
1253 context[color] = str => str;
1254 }
1255 }
1256 for (const format of Object.keys(AVAILABLE_FORMATS)) {
1257 context[format] = (content, ...args) =>
1258 AVAILABLE_FORMATS[format](content, context, ...args);
1259 }
1260 context.timeReference = compilation.time;
1261 });
1262
1263 for (const key of Object.keys(SIMPLE_PRINTERS)) {
1264 stats.hooks.print
1265 .for(key)
1266 .tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
1267 SIMPLE_PRINTERS[key](obj, ctx, stats)
1268 );
1269 }
1270
1271 for (const key of Object.keys(PREFERRED_ORDERS)) {
1272 const preferredOrder = PREFERRED_ORDERS[key];
1273 stats.hooks.sortElements
1274 .for(key)
1275 .tap("DefaultStatsPrinterPlugin", (elements, context) => {
1276 createOrder(elements, preferredOrder);
1277 });
1278 }
1279
1280 for (const key of Object.keys(ITEM_NAMES)) {
1281 const itemName = ITEM_NAMES[key];
1282 stats.hooks.getItemName
1283 .for(key)
1284 .tap(
1285 "DefaultStatsPrinterPlugin",
1286 typeof itemName === "string" ? () => itemName : itemName
1287 );
1288 }
1289
1290 for (const key of Object.keys(SIMPLE_ITEMS_JOINER)) {
1291 const joiner = SIMPLE_ITEMS_JOINER[key];
1292 stats.hooks.printItems
1293 .for(key)
1294 .tap("DefaultStatsPrinterPlugin", joiner);
1295 }
1296
1297 for (const key of Object.keys(SIMPLE_ELEMENT_JOINERS)) {
1298 const joiner = SIMPLE_ELEMENT_JOINERS[key];
1299 stats.hooks.printElements
1300 .for(key)
1301 .tap("DefaultStatsPrinterPlugin", joiner);
1302 }
1303
1304 for (const key of Object.keys(RESULT_MODIFIER)) {
1305 const modifier = RESULT_MODIFIER[key];
1306 stats.hooks.result
1307 .for(key)
1308 .tap("DefaultStatsPrinterPlugin", modifier);
1309 }
1310 }
1311 );
1312 });
1313 }
1314}
1315module.exports = DefaultStatsPrinterPlugin;
Note: See TracBrowser for help on using the repository browser.