12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- "use strict";
- /** @typedef {import("../Compiler")} Compiler */
- /** @typedef {import("../logging/Logger").LogTypeEnum} LogTypeEnum */
- /** @typedef {import("./DefaultStatsFactoryPlugin").ChunkId} ChunkId */
- /** @typedef {import("./DefaultStatsFactoryPlugin").ChunkName} ChunkName */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsAsset} KnownStatsAsset */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsAssetChunk} KnownStatsAssetChunk */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsAssetChunkIdHint} KnownStatsAssetChunkIdHint */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsAssetChunkName} KnownStatsAssetChunkName */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsChunk} KnownStatsChunk */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsChunkGroup} KnownStatsChunkGroup */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsChunkOrigin} KnownStatsChunkOrigin */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsCompilation} KnownStatsCompilation */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsError} KnownStatsError */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsLogging} KnownStatsLogging */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsLoggingEntry} KnownStatsLoggingEntry */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModule} KnownStatsModule */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModuleIssuer} KnownStatsModuleIssuer */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModuleReason} KnownStatsModuleReason */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModuleTraceDependency} KnownStatsModuleTraceDependency */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModuleTraceItem} KnownStatsModuleTraceItem */
- /** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsProfile} KnownStatsProfile */
- /** @typedef {import("./DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
- /** @typedef {import("./StatsPrinter")} StatsPrinter */
- /** @typedef {import("./StatsPrinter").ColorFunction} ColorFunction */
- /** @typedef {import("./StatsPrinter").KnownStatsPrinterColorFunctions} KnownStatsPrinterColorFunctions */
- /** @typedef {import("./StatsPrinter").KnownStatsPrinterContext} KnownStatsPrinterContext */
- /** @typedef {import("./StatsPrinter").KnownStatsPrinterFormatters} KnownStatsPrinterFormatters */
- /** @typedef {import("./StatsPrinter").StatsPrinterContext} StatsPrinterContext */
- /** @typedef {import("./StatsPrinter").StatsPrinterContextWithExtra} StatsPrinterContextWithExtra */
- const DATA_URI_CONTENT_LENGTH = 16;
- const MAX_MODULE_IDENTIFIER_LENGTH = 80;
- /**
- * @param {number} n a number
- * @param {string} singular singular
- * @param {string} plural plural
- * @returns {string} if n is 1, singular, else plural
- */
- const plural = (n, singular, plural) => (n === 1 ? singular : plural);
- /**
- * @param {Record<string, number>} sizes sizes by source type
- * @param {StatsPrinterContext} options options
- * @returns {string | undefined} text
- */
- const printSizes = (sizes, { formatSize = n => `${n}` }) => {
- const keys = Object.keys(sizes);
- if (keys.length > 1) {
- return keys.map(key => `${formatSize(sizes[key])} (${key})`).join(" ");
- } else if (keys.length === 1) {
- return formatSize(sizes[keys[0]]);
- }
- };
- /**
- * @param {string | null} resource resource
- * @returns {string} resource name for display
- */
- const getResourceName = resource => {
- if (!resource) return "";
- const dataUrl = /^data:[^,]+,/.exec(resource);
- if (!dataUrl) return resource;
- const len = dataUrl[0].length + DATA_URI_CONTENT_LENGTH;
- if (resource.length < len) return resource;
- return `${resource.slice(
- 0,
- Math.min(resource.length - /* '..'.length */ 2, len)
- )}..`;
- };
- /**
- * @param {string} name module name
- * @returns {[string,string]} prefix and module name
- */
- const getModuleName = name => {
- const [, prefix, resource] =
- /** @type {[string, string, string]} */
- (/** @type {unknown} */ (/^(.*!)?([^!]*)$/.exec(name)));
- if (resource.length > MAX_MODULE_IDENTIFIER_LENGTH) {
- const truncatedResource = `${resource.slice(
- 0,
- Math.min(
- resource.length - /* '...(truncated)'.length */ 14,
- MAX_MODULE_IDENTIFIER_LENGTH
- )
- )}...(truncated)`;
- return [prefix, getResourceName(truncatedResource)];
- }
- return [prefix, getResourceName(resource)];
- };
- /**
- * @param {string} str string
- * @param {(item: string) => string} fn function to apply to each line
- * @returns {string} joined string
- */
- const mapLines = (str, fn) => str.split("\n").map(fn).join("\n");
- /**
- * @param {number} n a number
- * @returns {string} number as two digit string, leading 0
- */
- const twoDigit = n => (n >= 10 ? `${n}` : `0${n}`);
- /**
- * @param {string | number | null} id an id
- * @returns {id is string | number} is i
- */
- const isValidId = id => {
- if (typeof id === "number" || id) {
- return true;
- }
- return false;
- };
- /**
- * @template T
- * @param {Array<T> | undefined} list of items
- * @param {number} count number of items to show
- * @returns {string} string representation of list
- */
- const moreCount = (list, count) =>
- list && list.length > 0 ? `+ ${count}` : `${count}`;
- /**
- * @template T
- * @template {keyof T} K
- * @typedef {{ [P in K]-?: T[P] }} WithRequired
- */
- /**
- * @template {keyof StatsPrinterContext} RequiredStatsPrinterContextKeys
- * @typedef {StatsPrinterContextWithExtra & WithRequired<StatsPrinterContext, "compilation" | RequiredStatsPrinterContextKeys>} DefineStatsPrinterContext
- */
- /**
- * @template T
- * @template {keyof StatsPrinterContext} RequiredStatsPrinterContextKeys
- * @typedef {(thing: Exclude<T, undefined>, context: DefineStatsPrinterContext<RequiredStatsPrinterContextKeys>, printer: StatsPrinter) => string | undefined} SimplePrinter
- */
- /**
- * @template T
- * @typedef {T extends (infer U)[] ? U : T} Unpacked
- */
- /**
- * @template {object} O
- * @template {keyof O} K
- * @template {string} B
- * @typedef {K extends string ? Exclude<O[K], undefined> extends EXPECTED_ANY[] ? never : `${B}.${K}` : never} PropertyName
- */
- /**
- * @template {object} O
- * @template {keyof O} K
- * @template {string} B
- * @typedef {K extends string ? NonNullable<O[K]> extends EXPECTED_ANY[] ? `${B}.${K}[]` : never : never} ArrayPropertyName
- */
- /**
- * @template {object} O
- * @template {keyof O} K
- * @template {string} B
- * @typedef {K extends string ? Exclude<O[K], undefined> extends EXPECTED_ANY[] ? `${B}.${K}` : never : never} MultiplePropertyName
- */
- /**
- * @template {object} O
- * @template {string} K
- * @template {string} E
- * @typedef {{ [property in `${K}!`]?: SimplePrinter<O, "compilation" | E> }} Exclamation
- */
- /**
- * @template {object} O
- * @template {string} B
- * @template {string} [R=B]
- * @typedef {{ [K in keyof O as PropertyName<O, K, B>]?: SimplePrinter<O[K], R> } &
- * { [K in keyof O as ArrayPropertyName<O, K, B>]?: Exclude<O[K], undefined> extends (infer I)[] ? SimplePrinter<I, R> : never } &
- * { [K in keyof O as MultiplePropertyName<O, K, B>]?: SimplePrinter<O[K], R> }
- * } Printers
- */
- /**
- * @typedef {Printers<KnownStatsCompilation, "compilation"> &
- * { ["compilation.summary!"]?: SimplePrinter<KnownStatsCompilation, "compilation"> } &
- * { ["compilation.errorsInChildren!"]?: SimplePrinter<KnownStatsCompilation, "compilation"> } &
- * { ["compilation.warningsInChildren!"]?: SimplePrinter<KnownStatsCompilation, "compilation"> }} CompilationSimplePrinters
- */
- /**
- * @type {CompilationSimplePrinters}
- */
- const COMPILATION_SIMPLE_PRINTERS = {
- "compilation.summary!": (
- _,
- {
- type,
- bold,
- green,
- red,
- yellow,
- formatDateTime,
- formatTime,
- compilation: {
- name,
- hash,
- version,
- time,
- builtAt,
- errorsCount,
- warningsCount
- }
- }
- ) => {
- const root = type === "compilation.summary!";
- const warningsMessage =
- /** @type {number} */ (warningsCount) > 0
- ? yellow(
- `${warningsCount} ${plural(/** @type {number} */ (warningsCount), "warning", "warnings")}`
- )
- : "";
- const errorsMessage =
- /** @type {number} */ (errorsCount) > 0
- ? red(
- `${errorsCount} ${plural(/** @type {number} */ (errorsCount), "error", "errors")}`
- )
- : "";
- const timeMessage = root && time ? ` in ${formatTime(time)}` : "";
- const hashMessage = hash ? ` (${hash})` : "";
- const builtAtMessage =
- root && builtAt ? `${formatDateTime(builtAt)}: ` : "";
- const versionMessage = root && version ? `webpack ${version}` : "";
- const nameMessage =
- root && name
- ? bold(name)
- : name
- ? `Child ${bold(name)}`
- : root
- ? ""
- : "Child";
- const subjectMessage =
- nameMessage && versionMessage
- ? `${nameMessage} (${versionMessage})`
- : versionMessage || nameMessage || "webpack";
- let statusMessage;
- if (errorsMessage && warningsMessage) {
- statusMessage = `compiled with ${errorsMessage} and ${warningsMessage}`;
- } else if (errorsMessage) {
- statusMessage = `compiled with ${errorsMessage}`;
- } else if (warningsMessage) {
- statusMessage = `compiled with ${warningsMessage}`;
- } else if (errorsCount === 0 && warningsCount === 0) {
- statusMessage = `compiled ${green("successfully")}`;
- } else {
- statusMessage = "compiled";
- }
- if (
- builtAtMessage ||
- versionMessage ||
- errorsMessage ||
- warningsMessage ||
- (errorsCount === 0 && warningsCount === 0) ||
- timeMessage ||
- hashMessage
- )
- return `${builtAtMessage}${subjectMessage} ${statusMessage}${timeMessage}${hashMessage}`;
- },
- "compilation.filteredWarningDetailsCount": count =>
- count
- ? `${count} ${plural(
- count,
- "warning has",
- "warnings have"
- )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.`
- : undefined,
- "compilation.filteredErrorDetailsCount": (count, { yellow }) =>
- count
- ? yellow(
- `${count} ${plural(
- count,
- "error has",
- "errors have"
- )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.`
- )
- : undefined,
- "compilation.env": (env, { bold }) =>
- env
- ? `Environment (--env): ${bold(JSON.stringify(env, null, 2))}`
- : undefined,
- "compilation.publicPath": (publicPath, { bold }) =>
- `PublicPath: ${bold(publicPath || "(none)")}`,
- "compilation.entrypoints": (entrypoints, context, printer) =>
- Array.isArray(entrypoints)
- ? undefined
- : printer.print(context.type, Object.values(entrypoints), {
- ...context,
- chunkGroupKind: "Entrypoint"
- }),
- "compilation.namedChunkGroups": (namedChunkGroups, context, printer) => {
- if (!Array.isArray(namedChunkGroups)) {
- const {
- compilation: { entrypoints }
- } = context;
- let chunkGroups = Object.values(namedChunkGroups);
- if (entrypoints) {
- chunkGroups = chunkGroups.filter(
- group =>
- !Object.prototype.hasOwnProperty.call(
- entrypoints,
- /** @type {string} */
- (group.name)
- )
- );
- }
- return printer.print(context.type, chunkGroups, {
- ...context,
- chunkGroupKind: "Chunk Group"
- });
- }
- },
- "compilation.assetsByChunkName": () => "",
- "compilation.filteredModules": (
- filteredModules,
- { compilation: { modules } }
- ) =>
- filteredModules > 0
- ? `${moreCount(modules, filteredModules)} ${plural(
- filteredModules,
- "module",
- "modules"
- )}`
- : undefined,
- "compilation.filteredAssets": (
- filteredAssets,
- { compilation: { assets } }
- ) =>
- filteredAssets > 0
- ? `${moreCount(assets, filteredAssets)} ${plural(
- filteredAssets,
- "asset",
- "assets"
- )}`
- : undefined,
- "compilation.logging": (logging, context, printer) =>
- Array.isArray(logging)
- ? undefined
- : printer.print(
- context.type,
- Object.entries(logging).map(([name, value]) => ({ ...value, name })),
- context
- ),
- "compilation.warningsInChildren!": (_, { yellow, compilation }) => {
- if (
- !compilation.children &&
- /** @type {number} */ (compilation.warningsCount) > 0 &&
- compilation.warnings
- ) {
- const childWarnings =
- /** @type {number} */ (compilation.warningsCount) -
- compilation.warnings.length;
- if (childWarnings > 0) {
- return yellow(
- `${childWarnings} ${plural(
- childWarnings,
- "WARNING",
- "WARNINGS"
- )} in child compilations${
- compilation.children
- ? ""
- : " (Use 'stats.children: true' resp. '--stats-children' for more details)"
- }`
- );
- }
- }
- },
- "compilation.errorsInChildren!": (_, { red, compilation }) => {
- if (
- !compilation.children &&
- /** @type {number} */ (compilation.errorsCount) > 0 &&
- compilation.errors
- ) {
- const childErrors =
- /** @type {number} */ (compilation.errorsCount) -
- compilation.errors.length;
- if (childErrors > 0) {
- return red(
- `${childErrors} ${plural(
- childErrors,
- "ERROR",
- "ERRORS"
- )} in child compilations${
- compilation.children
- ? ""
- : " (Use 'stats.children: true' resp. '--stats-children' for more details)"
- }`
- );
- }
- }
- }
- };
- /**
- * @typedef {Printers<KnownStatsAsset, "asset"> &
- * Printers<KnownStatsAsset["info"], "asset.info"> &
- * Exclamation<KnownStatsAsset, "asset.separator", "asset"> &
- * { ["asset.filteredChildren"]?: SimplePrinter<number, "asset"> } &
- * { assetChunk?: SimplePrinter<KnownStatsAssetChunk, "asset"> } &
- * { assetChunkName?: SimplePrinter<KnownStatsAssetChunkName, "asset"> } &
- * { assetChunkIdHint?: SimplePrinter<KnownStatsAssetChunkIdHint, "asset"> }} AssetSimplePrinters
- */
- /** @type {AssetSimplePrinters} */
- const ASSET_SIMPLE_PRINTERS = {
- "asset.type": type => type,
- "asset.name": (name, { formatFilename, asset: { isOverSizeLimit } }) =>
- formatFilename(name, isOverSizeLimit),
- "asset.size": (size, { asset: { isOverSizeLimit }, yellow, formatSize }) =>
- isOverSizeLimit ? yellow(formatSize(size)) : formatSize(size),
- "asset.emitted": (emitted, { green, formatFlag }) =>
- emitted ? green(formatFlag("emitted")) : undefined,
- "asset.comparedForEmit": (comparedForEmit, { yellow, formatFlag }) =>
- comparedForEmit ? yellow(formatFlag("compared for emit")) : undefined,
- "asset.cached": (cached, { green, formatFlag }) =>
- cached ? green(formatFlag("cached")) : undefined,
- "asset.isOverSizeLimit": (isOverSizeLimit, { yellow, formatFlag }) =>
- isOverSizeLimit ? yellow(formatFlag("big")) : undefined,
- "asset.info.immutable": (immutable, { green, formatFlag }) =>
- immutable ? green(formatFlag("immutable")) : undefined,
- "asset.info.javascriptModule": (javascriptModule, { formatFlag }) =>
- javascriptModule ? formatFlag("javascript module") : undefined,
- "asset.info.sourceFilename": (sourceFilename, { formatFlag }) =>
- sourceFilename ? formatFlag(`from: ${sourceFilename}`) : undefined,
- "asset.info.development": (development, { green, formatFlag }) =>
- development ? green(formatFlag("dev")) : undefined,
- "asset.info.hotModuleReplacement": (
- hotModuleReplacement,
- { green, formatFlag }
- ) => (hotModuleReplacement ? green(formatFlag("hmr")) : undefined),
- "asset.separator!": () => "\n",
- "asset.filteredRelated": (filteredRelated, { asset: { related } }) =>
- filteredRelated > 0
- ? `${moreCount(related, filteredRelated)} related ${plural(
- filteredRelated,
- "asset",
- "assets"
- )}`
- : undefined,
- "asset.filteredChildren": (filteredChildren, { asset: { children } }) =>
- filteredChildren > 0
- ? `${moreCount(children, filteredChildren)} ${plural(
- filteredChildren,
- "asset",
- "assets"
- )}`
- : undefined,
- assetChunk: (id, { formatChunkId }) => formatChunkId(id),
- assetChunkName: name => name || undefined,
- assetChunkIdHint: name => name || undefined
- };
- /**
- * @typedef {Printers<KnownStatsModule, "module"> &
- * Exclamation<KnownStatsModule, "module.separator", "module"> &
- * { ["module.filteredChildren"]?: SimplePrinter<number, "module"> } &
- * { ["module.filteredReasons"]?: SimplePrinter<number, "module"> }} ModuleSimplePrinters
- */
- /** @type {ModuleSimplePrinters} */
- const MODULE_SIMPLE_PRINTERS = {
- "module.type": type => (type !== "module" ? type : undefined),
- "module.id": (id, { formatModuleId }) =>
- isValidId(id) ? formatModuleId(id) : undefined,
- "module.name": (name, { bold }) => {
- const [prefix, resource] = getModuleName(name);
- return `${prefix || ""}${bold(resource || "")}`;
- },
- "module.identifier": identifier => undefined,
- "module.layer": (layer, { formatLayer }) =>
- layer ? formatLayer(layer) : undefined,
- "module.sizes": printSizes,
- "module.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
- "module.depth": (depth, { formatFlag }) =>
- depth !== null ? formatFlag(`depth ${depth}`) : undefined,
- "module.cacheable": (cacheable, { formatFlag, red }) =>
- cacheable === false ? red(formatFlag("not cacheable")) : undefined,
- "module.orphan": (orphan, { formatFlag, yellow }) =>
- orphan ? yellow(formatFlag("orphan")) : undefined,
- // "module.runtime": (runtime, { formatFlag, yellow }) =>
- // runtime ? yellow(formatFlag("runtime")) : undefined,
- "module.optional": (optional, { formatFlag, yellow }) =>
- optional ? yellow(formatFlag("optional")) : undefined,
- "module.dependent": (dependent, { formatFlag, cyan }) =>
- dependent ? cyan(formatFlag("dependent")) : undefined,
- "module.built": (built, { formatFlag, yellow }) =>
- built ? yellow(formatFlag("built")) : undefined,
- "module.codeGenerated": (codeGenerated, { formatFlag, yellow }) =>
- codeGenerated ? yellow(formatFlag("code generated")) : undefined,
- "module.buildTimeExecuted": (buildTimeExecuted, { formatFlag, green }) =>
- buildTimeExecuted ? green(formatFlag("build time executed")) : undefined,
- "module.cached": (cached, { formatFlag, green }) =>
- cached ? green(formatFlag("cached")) : undefined,
- "module.assets": (assets, { formatFlag, magenta }) =>
- assets && assets.length
- ? magenta(
- formatFlag(
- `${assets.length} ${plural(assets.length, "asset", "assets")}`
- )
- )
- : undefined,
- "module.warnings": (warnings, { formatFlag, yellow }) =>
- warnings
- ? yellow(
- formatFlag(`${warnings} ${plural(warnings, "warning", "warnings")}`)
- )
- : undefined,
- "module.errors": (errors, { formatFlag, red }) =>
- errors
- ? red(formatFlag(`${errors} ${plural(errors, "error", "errors")}`))
- : undefined,
- "module.providedExports": (providedExports, { formatFlag, cyan }) => {
- if (Array.isArray(providedExports)) {
- if (providedExports.length === 0) return cyan(formatFlag("no exports"));
- return cyan(formatFlag(`exports: ${providedExports.join(", ")}`));
- }
- },
- "module.usedExports": (usedExports, { formatFlag, cyan, module }) => {
- if (usedExports !== true) {
- if (usedExports === null) return cyan(formatFlag("used exports unknown"));
- if (usedExports === false) return cyan(formatFlag("module unused"));
- if (Array.isArray(usedExports)) {
- if (usedExports.length === 0)
- return cyan(formatFlag("no exports used"));
- const providedExportsCount = Array.isArray(module.providedExports)
- ? module.providedExports.length
- : null;
- if (
- providedExportsCount !== null &&
- providedExportsCount === usedExports.length
- ) {
- return cyan(formatFlag("all exports used"));
- }
- return cyan(
- formatFlag(`only some exports used: ${usedExports.join(", ")}`)
- );
- }
- }
- },
- "module.optimizationBailout[]": (optimizationBailout, { yellow }) =>
- yellow(optimizationBailout),
- "module.issuerPath": (issuerPath, { module }) =>
- module.profile ? undefined : "",
- "module.profile": profile => undefined,
- "module.filteredModules": (filteredModules, { module: { modules } }) =>
- filteredModules > 0
- ? `${moreCount(modules, filteredModules)} nested ${plural(
- filteredModules,
- "module",
- "modules"
- )}`
- : undefined,
- "module.filteredReasons": (filteredReasons, { module: { reasons } }) =>
- filteredReasons > 0
- ? `${moreCount(reasons, filteredReasons)} ${plural(
- filteredReasons,
- "reason",
- "reasons"
- )}`
- : undefined,
- "module.filteredChildren": (filteredChildren, { module: { children } }) =>
- filteredChildren > 0
- ? `${moreCount(children, filteredChildren)} ${plural(
- filteredChildren,
- "module",
- "modules"
- )}`
- : undefined,
- "module.separator!": () => "\n"
- };
- /**
- * @typedef {Printers<KnownStatsModuleIssuer, "moduleIssuer"> &
- * Printers<KnownStatsModuleIssuer["profile"], "moduleIssuer.profile", "moduleIssuer">} ModuleIssuerPrinters
- */
- /** @type {ModuleIssuerPrinters} */
- const MODULE_ISSUER_PRINTERS = {
- "moduleIssuer.id": (id, { formatModuleId }) => formatModuleId(id),
- "moduleIssuer.profile.total": (value, { formatTime }) => formatTime(value)
- };
- /**
- * @typedef {Printers<KnownStatsModuleReason, "moduleReason"> &
- * { ["moduleReason.filteredChildren"]?: SimplePrinter<number, "moduleReason"> }} ModuleReasonsPrinters
- */
- /** @type {ModuleReasonsPrinters} */
- const MODULE_REASON_PRINTERS = {
- "moduleReason.type": type => type || undefined,
- "moduleReason.userRequest": (userRequest, { cyan }) =>
- cyan(getResourceName(userRequest)),
- "moduleReason.moduleId": (moduleId, { formatModuleId }) =>
- isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
- "moduleReason.module": (module, { magenta }) =>
- module ? magenta(module) : undefined,
- "moduleReason.loc": loc => loc || undefined,
- "moduleReason.explanation": (explanation, { cyan }) =>
- explanation ? cyan(explanation) : undefined,
- "moduleReason.active": (active, { formatFlag }) =>
- active ? undefined : formatFlag("inactive"),
- "moduleReason.resolvedModule": (module, { magenta }) =>
- module ? magenta(module) : undefined,
- "moduleReason.filteredChildren": (
- filteredChildren,
- { moduleReason: { children } }
- ) =>
- filteredChildren > 0
- ? `${moreCount(children, filteredChildren)} ${plural(
- filteredChildren,
- "reason",
- "reasons"
- )}`
- : undefined
- };
- /** @typedef {Printers<KnownStatsProfile, "module.profile", "profile">} ModuleProfilePrinters */
- /** @type {ModuleProfilePrinters} */
- const MODULE_PROFILE_PRINTERS = {
- "module.profile.total": (value, { formatTime }) => formatTime(value),
- "module.profile.resolving": (value, { formatTime }) =>
- `resolving: ${formatTime(value)}`,
- "module.profile.restoring": (value, { formatTime }) =>
- `restoring: ${formatTime(value)}`,
- "module.profile.integration": (value, { formatTime }) =>
- `integration: ${formatTime(value)}`,
- "module.profile.building": (value, { formatTime }) =>
- `building: ${formatTime(value)}`,
- "module.profile.storing": (value, { formatTime }) =>
- `storing: ${formatTime(value)}`,
- "module.profile.additionalResolving": (value, { formatTime }) =>
- value ? `additional resolving: ${formatTime(value)}` : undefined,
- "module.profile.additionalIntegration": (value, { formatTime }) =>
- value ? `additional integration: ${formatTime(value)}` : undefined
- };
- /**
- * @typedef {Exclamation<KnownStatsChunkGroup, "chunkGroup.kind", "chunkGroupKind"> &
- * Exclamation<KnownStatsChunkGroup, "chunkGroup.separator", "chunkGroup"> &
- * Printers<KnownStatsChunkGroup, "chunkGroup"> &
- * Exclamation<KnownStatsChunkGroup, "chunkGroup.is", "chunkGroup"> &
- * Printers<Exclude<KnownStatsChunkGroup["assets"], undefined>[number], "chunkGroupAsset" | "chunkGroup"> &
- * { ['chunkGroupChildGroup.type']?: SimplePrinter<string, "chunkGroupAsset"> } &
- * { ['chunkGroupChild.assets[]']?: SimplePrinter<string, "chunkGroupAsset"> } &
- * { ['chunkGroupChild.chunks[]']?: SimplePrinter<ChunkId, "chunkGroupAsset"> } &
- * { ['chunkGroupChild.name']?: SimplePrinter<ChunkName, "chunkGroupAsset"> }} ChunkGroupPrinters
- */
- /** @type {ChunkGroupPrinters} */
- const CHUNK_GROUP_PRINTERS = {
- "chunkGroup.kind!": (_, { chunkGroupKind }) => chunkGroupKind,
- "chunkGroup.separator!": () => "\n",
- "chunkGroup.name": (name, { bold }) => (name ? bold(name) : undefined),
- "chunkGroup.isOverSizeLimit": (isOverSizeLimit, { formatFlag, yellow }) =>
- isOverSizeLimit ? yellow(formatFlag("big")) : undefined,
- "chunkGroup.assetsSize": (size, { formatSize }) =>
- size ? formatSize(size) : undefined,
- "chunkGroup.auxiliaryAssetsSize": (size, { formatSize }) =>
- size ? `(${formatSize(size)})` : undefined,
- "chunkGroup.filteredAssets": (n, { chunkGroup: { assets } }) =>
- n > 0
- ? `${moreCount(assets, n)} ${plural(n, "asset", "assets")}`
- : undefined,
- "chunkGroup.filteredAuxiliaryAssets": (
- n,
- { chunkGroup: { auxiliaryAssets } }
- ) =>
- n > 0
- ? `${moreCount(auxiliaryAssets, n)} auxiliary ${plural(
- n,
- "asset",
- "assets"
- )}`
- : undefined,
- "chunkGroup.is!": () => "=",
- "chunkGroupAsset.name": (asset, { green }) => green(asset),
- "chunkGroupAsset.size": (size, { formatSize, chunkGroup }) =>
- chunkGroup.assets &&
- (chunkGroup.assets.length > 1 ||
- (chunkGroup.auxiliaryAssets && chunkGroup.auxiliaryAssets.length > 0)
- ? formatSize(size)
- : undefined),
- "chunkGroup.children": (children, context, printer) =>
- Array.isArray(children)
- ? undefined
- : printer.print(
- context.type,
- Object.keys(children).map(key => ({
- type: key,
- children: children[key]
- })),
- context
- ),
- "chunkGroupChildGroup.type": type => `${type}:`,
- "chunkGroupChild.assets[]": (file, { formatFilename }) =>
- formatFilename(file),
- "chunkGroupChild.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
- "chunkGroupChild.name": name => (name ? `(name: ${name})` : undefined)
- };
- /**
- * @typedef {Printers<KnownStatsChunk, "chunk"> &
- * { ["chunk.childrenByOrder[].type"]: SimplePrinter<string, "chunk"> } &
- * { ["chunk.childrenByOrder[].children[]"]: SimplePrinter<ChunkId, "chunk"> } &
- * Exclamation<KnownStatsChunk, "chunk.separator", "chunk"> &
- * Printers<KnownStatsChunkOrigin, "chunkOrigin">} ChunkPrinters
- */
- /** @type {ChunkPrinters} */
- const CHUNK_PRINTERS = {
- "chunk.id": (id, { formatChunkId }) => formatChunkId(id),
- "chunk.files[]": (file, { formatFilename }) => formatFilename(file),
- "chunk.names[]": name => name,
- "chunk.idHints[]": name => name,
- "chunk.runtime[]": name => name,
- "chunk.sizes": (sizes, context) => printSizes(sizes, context),
- "chunk.parents[]": (parents, context) =>
- context.formatChunkId(parents, "parent"),
- "chunk.siblings[]": (siblings, context) =>
- context.formatChunkId(siblings, "sibling"),
- "chunk.children[]": (children, context) =>
- context.formatChunkId(children, "child"),
- "chunk.childrenByOrder": (childrenByOrder, context, printer) =>
- Array.isArray(childrenByOrder)
- ? undefined
- : printer.print(
- context.type,
- Object.keys(childrenByOrder).map(key => ({
- type: key,
- children: childrenByOrder[key]
- })),
- context
- ),
- "chunk.childrenByOrder[].type": type => `${type}:`,
- "chunk.childrenByOrder[].children[]": (id, { formatChunkId }) =>
- isValidId(id) ? formatChunkId(id) : undefined,
- "chunk.entry": (entry, { formatFlag, yellow }) =>
- entry ? yellow(formatFlag("entry")) : undefined,
- "chunk.initial": (initial, { formatFlag, yellow }) =>
- initial ? yellow(formatFlag("initial")) : undefined,
- "chunk.rendered": (rendered, { formatFlag, green }) =>
- rendered ? green(formatFlag("rendered")) : undefined,
- "chunk.recorded": (recorded, { formatFlag, green }) =>
- recorded ? green(formatFlag("recorded")) : undefined,
- "chunk.reason": (reason, { yellow }) => (reason ? yellow(reason) : undefined),
- "chunk.filteredModules": (filteredModules, { chunk: { modules } }) =>
- filteredModules > 0
- ? `${moreCount(modules, filteredModules)} chunk ${plural(
- filteredModules,
- "module",
- "modules"
- )}`
- : undefined,
- "chunk.separator!": () => "\n",
- "chunkOrigin.request": request => request,
- "chunkOrigin.moduleId": (moduleId, { formatModuleId }) =>
- isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
- "chunkOrigin.moduleName": (moduleName, { bold }) => bold(moduleName),
- "chunkOrigin.loc": loc => loc
- };
- /**
- * @typedef {Printers<KnownStatsError, "error"> &
- * { ["error.filteredDetails"]?: SimplePrinter<number, "error"> } &
- * Exclamation<KnownStatsError, "error.separator", "error">} ErrorPrinters
- */
- /**
- * @type {ErrorPrinters}
- */
- const ERROR_PRINTERS = {
- "error.compilerPath": (compilerPath, { bold }) =>
- compilerPath ? bold(`(${compilerPath})`) : undefined,
- "error.chunkId": (chunkId, { formatChunkId }) =>
- isValidId(chunkId) ? formatChunkId(chunkId) : undefined,
- "error.chunkEntry": (chunkEntry, { formatFlag }) =>
- chunkEntry ? formatFlag("entry") : undefined,
- "error.chunkInitial": (chunkInitial, { formatFlag }) =>
- chunkInitial ? formatFlag("initial") : undefined,
- "error.file": (file, { bold }) => bold(file),
- "error.moduleName": (moduleName, { bold }) =>
- moduleName.includes("!")
- ? `${bold(moduleName.replace(/^(\s|\S)*!/, ""))} (${moduleName})`
- : `${bold(moduleName)}`,
- "error.loc": (loc, { green }) => green(loc),
- "error.message": (message, { bold, formatError }) =>
- message.includes("\u001B[") ? message : bold(formatError(message)),
- "error.details": (details, { formatError }) => formatError(details),
- "error.filteredDetails": filteredDetails =>
- filteredDetails ? `+ ${filteredDetails} hidden lines` : undefined,
- "error.stack": stack => stack,
- "error.cause": (cause, context, printer) =>
- cause
- ? indent(
- `[cause]: ${
- /** @type {string} */
- (printer.print(`${context.type}.error`, cause, context))
- }`,
- " "
- )
- : undefined,
- "error.moduleTrace": moduleTrace => undefined,
- "error.separator!": () => "\n"
- };
- /**
- * @typedef {Printers<KnownStatsLoggingEntry, `loggingEntry(${LogTypeEnum}).loggingEntry`> &
- * { ["loggingEntry(clear).loggingEntry"]?: SimplePrinter<KnownStatsLoggingEntry, "logging"> } &
- * { ["loggingEntry.trace[]"]?: SimplePrinter<Exclude<KnownStatsLoggingEntry["trace"], undefined>[number], "logging"> } &
- * { loggingGroup?: SimplePrinter<KnownStatsLogging[], "logging"> } &
- * Printers<KnownStatsLogging & { name: string }, `loggingGroup`> &
- * Exclamation<KnownStatsLogging, "loggingGroup.separator", "loggingGroup">} LogEntryPrinters
- */
- /** @type {LogEntryPrinters} */
- const LOG_ENTRY_PRINTERS = {
- "loggingEntry(error).loggingEntry.message": (message, { red }) =>
- mapLines(message, x => `<e> ${red(x)}`),
- "loggingEntry(warn).loggingEntry.message": (message, { yellow }) =>
- mapLines(message, x => `<w> ${yellow(x)}`),
- "loggingEntry(info).loggingEntry.message": (message, { green }) =>
- mapLines(message, x => `<i> ${green(x)}`),
- "loggingEntry(log).loggingEntry.message": (message, { bold }) =>
- mapLines(message, x => ` ${bold(x)}`),
- "loggingEntry(debug).loggingEntry.message": message =>
- mapLines(message, x => ` ${x}`),
- "loggingEntry(trace).loggingEntry.message": message =>
- mapLines(message, x => ` ${x}`),
- "loggingEntry(status).loggingEntry.message": (message, { magenta }) =>
- mapLines(message, x => `<s> ${magenta(x)}`),
- "loggingEntry(profile).loggingEntry.message": (message, { magenta }) =>
- mapLines(message, x => `<p> ${magenta(x)}`),
- "loggingEntry(profileEnd).loggingEntry.message": (message, { magenta }) =>
- mapLines(message, x => `</p> ${magenta(x)}`),
- "loggingEntry(time).loggingEntry.message": (message, { magenta }) =>
- mapLines(message, x => `<t> ${magenta(x)}`),
- "loggingEntry(group).loggingEntry.message": (message, { cyan }) =>
- mapLines(message, x => `<-> ${cyan(x)}`),
- "loggingEntry(groupCollapsed).loggingEntry.message": (message, { cyan }) =>
- mapLines(message, x => `<+> ${cyan(x)}`),
- "loggingEntry(clear).loggingEntry": () => " -------",
- "loggingEntry(groupCollapsed).loggingEntry.children": () => "",
- "loggingEntry.trace[]": trace =>
- trace ? mapLines(trace, x => `| ${x}`) : undefined,
- loggingGroup: loggingGroup =>
- loggingGroup.entries.length === 0 ? "" : undefined,
- "loggingGroup.debug": (flag, { red }) => (flag ? red("DEBUG") : undefined),
- "loggingGroup.name": (name, { bold }) => bold(`LOG from ${name}`),
- "loggingGroup.separator!": () => "\n",
- "loggingGroup.filteredEntries": filteredEntries =>
- filteredEntries > 0 ? `+ ${filteredEntries} hidden lines` : undefined
- };
- /** @typedef {Printers<KnownStatsModuleTraceItem, "moduleTraceItem">} ModuleTraceItemPrinters */
- /** @type {ModuleTraceItemPrinters} */
- const MODULE_TRACE_ITEM_PRINTERS = {
- "moduleTraceItem.originName": originName => originName
- };
- /** @typedef {Printers<KnownStatsModuleTraceDependency, "moduleTraceDependency">} ModuleTraceDependencyPrinters */
- /** @type {ModuleTraceDependencyPrinters} */
- const MODULE_TRACE_DEPENDENCY_PRINTERS = {
- "moduleTraceDependency.loc": loc => loc
- };
- /**
- * @type {Record<string, string | ((item: KnownStatsLoggingEntry) => string)>}
- */
- const ITEM_NAMES = {
- "compilation.assets[]": "asset",
- "compilation.modules[]": "module",
- "compilation.chunks[]": "chunk",
- "compilation.entrypoints[]": "chunkGroup",
- "compilation.namedChunkGroups[]": "chunkGroup",
- "compilation.errors[]": "error",
- "compilation.warnings[]": "error",
- "compilation.logging[]": "loggingGroup",
- "compilation.children[]": "compilation",
- "asset.related[]": "asset",
- "asset.children[]": "asset",
- "asset.chunks[]": "assetChunk",
- "asset.auxiliaryChunks[]": "assetChunk",
- "asset.chunkNames[]": "assetChunkName",
- "asset.chunkIdHints[]": "assetChunkIdHint",
- "asset.auxiliaryChunkNames[]": "assetChunkName",
- "asset.auxiliaryChunkIdHints[]": "assetChunkIdHint",
- "chunkGroup.assets[]": "chunkGroupAsset",
- "chunkGroup.auxiliaryAssets[]": "chunkGroupAsset",
- "chunkGroupChild.assets[]": "chunkGroupAsset",
- "chunkGroupChild.auxiliaryAssets[]": "chunkGroupAsset",
- "chunkGroup.children[]": "chunkGroupChildGroup",
- "chunkGroupChildGroup.children[]": "chunkGroupChild",
- "module.modules[]": "module",
- "module.children[]": "module",
- "module.reasons[]": "moduleReason",
- "moduleReason.children[]": "moduleReason",
- "module.issuerPath[]": "moduleIssuer",
- "chunk.origins[]": "chunkOrigin",
- "chunk.modules[]": "module",
- "loggingGroup.entries[]": logEntry =>
- `loggingEntry(${logEntry.type}).loggingEntry`,
- "loggingEntry.children[]": logEntry =>
- `loggingEntry(${logEntry.type}).loggingEntry`,
- "error.moduleTrace[]": "moduleTraceItem",
- "error.errors[]": "error",
- "moduleTraceItem.dependencies[]": "moduleTraceDependency"
- };
- const ERROR_PREFERRED_ORDER = [
- "compilerPath",
- "chunkId",
- "chunkEntry",
- "chunkInitial",
- "file",
- "separator!",
- "moduleName",
- "loc",
- "separator!",
- "message",
- "separator!",
- "details",
- "separator!",
- "filteredDetails",
- "separator!",
- "stack",
- "separator!",
- "cause",
- "separator!",
- "missing",
- "separator!",
- "moduleTrace"
- ];
- /** @type {Record<string, string[]>} */
- const PREFERRED_ORDERS = {
- compilation: [
- "name",
- "hash",
- "version",
- "time",
- "builtAt",
- "env",
- "publicPath",
- "assets",
- "filteredAssets",
- "entrypoints",
- "namedChunkGroups",
- "chunks",
- "modules",
- "filteredModules",
- "children",
- "logging",
- "warnings",
- "warningsInChildren!",
- "filteredWarningDetailsCount",
- "errors",
- "errorsInChildren!",
- "filteredErrorDetailsCount",
- "summary!",
- "needAdditionalPass"
- ],
- asset: [
- "type",
- "name",
- "size",
- "chunks",
- "auxiliaryChunks",
- "emitted",
- "comparedForEmit",
- "cached",
- "info",
- "isOverSizeLimit",
- "chunkNames",
- "auxiliaryChunkNames",
- "chunkIdHints",
- "auxiliaryChunkIdHints",
- "related",
- "filteredRelated",
- "children",
- "filteredChildren"
- ],
- "asset.info": [
- "immutable",
- "sourceFilename",
- "javascriptModule",
- "development",
- "hotModuleReplacement"
- ],
- chunkGroup: [
- "kind!",
- "name",
- "isOverSizeLimit",
- "assetsSize",
- "auxiliaryAssetsSize",
- "is!",
- "assets",
- "filteredAssets",
- "auxiliaryAssets",
- "filteredAuxiliaryAssets",
- "separator!",
- "children"
- ],
- chunkGroupAsset: ["name", "size"],
- chunkGroupChildGroup: ["type", "children"],
- chunkGroupChild: ["assets", "chunks", "name"],
- module: [
- "type",
- "name",
- "identifier",
- "id",
- "layer",
- "sizes",
- "chunks",
- "depth",
- "cacheable",
- "orphan",
- "runtime",
- "optional",
- "dependent",
- "built",
- "codeGenerated",
- "cached",
- "assets",
- "failed",
- "warnings",
- "errors",
- "children",
- "filteredChildren",
- "providedExports",
- "usedExports",
- "optimizationBailout",
- "reasons",
- "filteredReasons",
- "issuerPath",
- "profile",
- "modules",
- "filteredModules"
- ],
- moduleReason: [
- "active",
- "type",
- "userRequest",
- "moduleId",
- "module",
- "resolvedModule",
- "loc",
- "explanation",
- "children",
- "filteredChildren"
- ],
- "module.profile": [
- "total",
- "separator!",
- "resolving",
- "restoring",
- "integration",
- "building",
- "storing",
- "additionalResolving",
- "additionalIntegration"
- ],
- chunk: [
- "id",
- "runtime",
- "files",
- "names",
- "idHints",
- "sizes",
- "parents",
- "siblings",
- "children",
- "childrenByOrder",
- "entry",
- "initial",
- "rendered",
- "recorded",
- "reason",
- "separator!",
- "origins",
- "separator!",
- "modules",
- "separator!",
- "filteredModules"
- ],
- chunkOrigin: ["request", "moduleId", "moduleName", "loc"],
- error: ERROR_PREFERRED_ORDER,
- warning: ERROR_PREFERRED_ORDER,
- "chunk.childrenByOrder[]": ["type", "children"],
- loggingGroup: [
- "debug",
- "name",
- "separator!",
- "entries",
- "separator!",
- "filteredEntries"
- ],
- loggingEntry: ["message", "trace", "children"]
- };
- /** @typedef {(items: string[]) => string | undefined} SimpleItemsJoiner */
- /** @type {SimpleItemsJoiner} */
- const itemsJoinOneLine = items => items.filter(Boolean).join(" ");
- /** @type {SimpleItemsJoiner} */
- const itemsJoinOneLineBrackets = items =>
- items.length > 0 ? `(${items.filter(Boolean).join(" ")})` : undefined;
- /** @type {SimpleItemsJoiner} */
- const itemsJoinMoreSpacing = items => items.filter(Boolean).join("\n\n");
- /** @type {SimpleItemsJoiner} */
- const itemsJoinComma = items => items.filter(Boolean).join(", ");
- /** @type {SimpleItemsJoiner} */
- const itemsJoinCommaBrackets = items =>
- items.length > 0 ? `(${items.filter(Boolean).join(", ")})` : undefined;
- /** @type {(item: string) => SimpleItemsJoiner} */
- const itemsJoinCommaBracketsWithName = name => items =>
- items.length > 0
- ? `(${name}: ${items.filter(Boolean).join(", ")})`
- : undefined;
- /** @type {Record<string, SimpleItemsJoiner>} */
- const SIMPLE_ITEMS_JOINER = {
- "chunk.parents": itemsJoinOneLine,
- "chunk.siblings": itemsJoinOneLine,
- "chunk.children": itemsJoinOneLine,
- "chunk.names": itemsJoinCommaBrackets,
- "chunk.idHints": itemsJoinCommaBracketsWithName("id hint"),
- "chunk.runtime": itemsJoinCommaBracketsWithName("runtime"),
- "chunk.files": itemsJoinComma,
- "chunk.childrenByOrder": itemsJoinOneLine,
- "chunk.childrenByOrder[].children": itemsJoinOneLine,
- "chunkGroup.assets": itemsJoinOneLine,
- "chunkGroup.auxiliaryAssets": itemsJoinOneLineBrackets,
- "chunkGroupChildGroup.children": itemsJoinComma,
- "chunkGroupChild.assets": itemsJoinOneLine,
- "chunkGroupChild.auxiliaryAssets": itemsJoinOneLineBrackets,
- "asset.chunks": itemsJoinComma,
- "asset.auxiliaryChunks": itemsJoinCommaBrackets,
- "asset.chunkNames": itemsJoinCommaBracketsWithName("name"),
- "asset.auxiliaryChunkNames": itemsJoinCommaBracketsWithName("auxiliary name"),
- "asset.chunkIdHints": itemsJoinCommaBracketsWithName("id hint"),
- "asset.auxiliaryChunkIdHints":
- itemsJoinCommaBracketsWithName("auxiliary id hint"),
- "module.chunks": itemsJoinOneLine,
- "module.issuerPath": items =>
- items
- .filter(Boolean)
- .map(item => `${item} ->`)
- .join(" "),
- "compilation.errors": itemsJoinMoreSpacing,
- "compilation.warnings": itemsJoinMoreSpacing,
- "compilation.logging": itemsJoinMoreSpacing,
- "compilation.children": items =>
- indent(/** @type {string} */ (itemsJoinMoreSpacing(items)), " "),
- "moduleTraceItem.dependencies": itemsJoinOneLine,
- "loggingEntry.children": items =>
- indent(items.filter(Boolean).join("\n"), " ", false)
- };
- /**
- * @param {Item[]} items items
- * @returns {string} result
- */
- const joinOneLine = items =>
- items
- .map(item => item.content)
- .filter(Boolean)
- .join(" ");
- /**
- * @param {Item[]} items items
- * @returns {string} result
- */
- const joinInBrackets = items => {
- const res = [];
- let mode = 0;
- for (const item of items) {
- if (item.element === "separator!") {
- switch (mode) {
- case 0:
- case 1:
- mode += 2;
- break;
- case 4:
- res.push(")");
- mode = 3;
- break;
- }
- }
- if (!item.content) continue;
- switch (mode) {
- case 0:
- mode = 1;
- break;
- case 1:
- res.push(" ");
- break;
- case 2:
- res.push("(");
- mode = 4;
- break;
- case 3:
- res.push(" (");
- mode = 4;
- break;
- case 4:
- res.push(", ");
- break;
- }
- res.push(item.content);
- }
- if (mode === 4) res.push(")");
- return res.join("");
- };
- /**
- * @param {string} str a string
- * @param {string} prefix prefix
- * @param {boolean=} noPrefixInFirstLine need prefix in the first line?
- * @returns {string} result
- */
- const indent = (str, prefix, noPrefixInFirstLine) => {
- const rem = str.replace(/\n([^\n])/g, `\n${prefix}$1`);
- if (noPrefixInFirstLine) return rem;
- const ind = str[0] === "\n" ? "" : prefix;
- return ind + rem;
- };
- /**
- * @param {(false | Item)[]} items items
- * @param {string} indenter indenter
- * @returns {string} result
- */
- const joinExplicitNewLine = (items, indenter) => {
- let firstInLine = true;
- let first = true;
- return items
- .map(item => {
- if (!item || !item.content) return;
- let content = indent(item.content, first ? "" : indenter, !firstInLine);
- if (firstInLine) {
- content = content.replace(/^\n+/, "");
- }
- if (!content) return;
- first = false;
- const noJoiner = firstInLine || content.startsWith("\n");
- firstInLine = content.endsWith("\n");
- return noJoiner ? content : ` ${content}`;
- })
- .filter(Boolean)
- .join("")
- .trim();
- };
- /**
- * @param {boolean} error is an error
- * @returns {SimpleElementJoiner} joiner
- */
- const joinError =
- error =>
- /**
- * @param {Item[]} items items
- * @param {StatsPrinterContextWithExtra} ctx context
- * @returns {string} result
- */
- (items, { red, yellow }) =>
- `${error ? red("ERROR") : yellow("WARNING")} in ${joinExplicitNewLine(
- items,
- ""
- )}`;
- /** @typedef {{ element: string, content: string | undefined }} Item */
- /** @typedef {(items: Item[], context: StatsPrinterContextWithExtra & Required<KnownStatsPrinterContext>) => string} SimpleElementJoiner */
- /** @type {Record<string, SimpleElementJoiner>} */
- const SIMPLE_ELEMENT_JOINERS = {
- compilation: items => {
- const result = [];
- let lastNeedMore = false;
- for (const item of items) {
- if (!item.content) continue;
- const needMoreSpace =
- item.element === "warnings" ||
- item.element === "filteredWarningDetailsCount" ||
- item.element === "errors" ||
- item.element === "filteredErrorDetailsCount" ||
- item.element === "logging";
- if (result.length !== 0) {
- result.push(needMoreSpace || lastNeedMore ? "\n\n" : "\n");
- }
- result.push(item.content);
- lastNeedMore = needMoreSpace;
- }
- if (lastNeedMore) result.push("\n");
- return result.join("");
- },
- asset: items =>
- joinExplicitNewLine(
- items.map(item => {
- if (
- (item.element === "related" || item.element === "children") &&
- item.content
- ) {
- return {
- ...item,
- content: `\n${item.content}\n`
- };
- }
- return item;
- }),
- " "
- ),
- "asset.info": joinOneLine,
- module: (items, { module }) => {
- let hasName = false;
- return joinExplicitNewLine(
- items.map(item => {
- switch (item.element) {
- case "id":
- if (module.id === module.name) {
- if (hasName) return false;
- if (item.content) hasName = true;
- }
- break;
- case "name":
- if (hasName) return false;
- if (item.content) hasName = true;
- break;
- case "providedExports":
- case "usedExports":
- case "optimizationBailout":
- case "reasons":
- case "issuerPath":
- case "profile":
- case "children":
- case "modules":
- if (item.content) {
- return {
- ...item,
- content: `\n${item.content}\n`
- };
- }
- break;
- }
- return item;
- }),
- " "
- );
- },
- chunk: items => {
- let hasEntry = false;
- return `chunk ${joinExplicitNewLine(
- items.filter(item => {
- switch (item.element) {
- case "entry":
- if (item.content) hasEntry = true;
- break;
- case "initial":
- if (hasEntry) return false;
- break;
- }
- return true;
- }),
- " "
- )}`;
- },
- "chunk.childrenByOrder[]": items => `(${joinOneLine(items)})`,
- chunkGroup: items => joinExplicitNewLine(items, " "),
- chunkGroupAsset: joinOneLine,
- chunkGroupChildGroup: joinOneLine,
- chunkGroupChild: joinOneLine,
- moduleReason: (items, { moduleReason }) => {
- let hasName = false;
- return joinExplicitNewLine(
- items.map(item => {
- switch (item.element) {
- case "moduleId":
- if (moduleReason.moduleId === moduleReason.module && item.content)
- hasName = true;
- break;
- case "module":
- if (hasName) return false;
- break;
- case "resolvedModule":
- if (moduleReason.module === moduleReason.resolvedModule)
- return false;
- break;
- case "children":
- if (item.content) {
- return {
- ...item,
- content: `\n${item.content}\n`
- };
- }
- break;
- }
- return item;
- }),
- " "
- );
- },
- "module.profile": joinInBrackets,
- moduleIssuer: joinOneLine,
- chunkOrigin: items => `> ${joinOneLine(items)}`,
- "errors[].error": joinError(true),
- "warnings[].error": joinError(false),
- error: items => joinExplicitNewLine(items, ""),
- "error.errors[].error": items =>
- indent(`[errors]: ${joinExplicitNewLine(items, "")}`, " "),
- loggingGroup: items => joinExplicitNewLine(items, "").trimEnd(),
- moduleTraceItem: items => ` @ ${joinOneLine(items)}`,
- moduleTraceDependency: joinOneLine
- };
- /** @type {Record<keyof KnownStatsPrinterColorFunctions, string>} */
- const AVAILABLE_COLORS = {
- bold: "\u001B[1m",
- yellow: "\u001B[1m\u001B[33m",
- red: "\u001B[1m\u001B[31m",
- green: "\u001B[1m\u001B[32m",
- cyan: "\u001B[1m\u001B[36m",
- magenta: "\u001B[1m\u001B[35m"
- };
- /** @typedef {Required<{ [Key in keyof KnownStatsPrinterFormatters]: (value: Parameters<NonNullable<KnownStatsPrinterFormatters[Key]>>[0], options: Required<KnownStatsPrinterColorFunctions> & StatsPrinterContext, ...args: TODO[]) => string }>} AvailableFormats */
- /** @type {AvailableFormats} */
- const AVAILABLE_FORMATS = {
- formatChunkId: (id, { yellow }, direction) => {
- switch (direction) {
- case "parent":
- return `<{${yellow(id)}}>`;
- case "sibling":
- return `={${yellow(id)}}=`;
- case "child":
- return `>{${yellow(id)}}<`;
- default:
- return `{${yellow(id)}}`;
- }
- },
- formatModuleId: id => `[${id}]`,
- formatFilename: (filename, { green, yellow }, oversize) =>
- (oversize ? yellow : green)(filename),
- formatFlag: flag => `[${flag}]`,
- formatLayer: layer => `(in ${layer})`,
- formatSize: require("../SizeFormatHelpers").formatSize,
- formatDateTime: (dateTime, { bold }) => {
- const d = new Date(dateTime);
- const x = twoDigit;
- const date = `${d.getFullYear()}-${x(d.getMonth() + 1)}-${x(d.getDate())}`;
- const time = `${x(d.getHours())}:${x(d.getMinutes())}:${x(d.getSeconds())}`;
- return `${date} ${bold(time)}`;
- },
- formatTime: (
- time,
- { timeReference, bold, green, yellow, red },
- boldQuantity
- ) => {
- const unit = " ms";
- if (timeReference && time !== timeReference) {
- const times = [
- timeReference / 2,
- timeReference / 4,
- timeReference / 8,
- timeReference / 16
- ];
- if (time < times[3]) return `${time}${unit}`;
- else if (time < times[2]) return bold(`${time}${unit}`);
- else if (time < times[1]) return green(`${time}${unit}`);
- else if (time < times[0]) return yellow(`${time}${unit}`);
- return red(`${time}${unit}`);
- }
- return `${boldQuantity ? bold(time) : time}${unit}`;
- },
- formatError: (message, { green, yellow, red }) => {
- if (message.includes("\u001B[")) return message;
- const highlights = [
- { regExp: /(Did you mean .+)/g, format: green },
- {
- regExp: /(Set 'mode' option to 'development' or 'production')/g,
- format: green
- },
- { regExp: /(\(module has no exports\))/g, format: red },
- { regExp: /\(possible exports: (.+)\)/g, format: green },
- { regExp: /(?:^|\n)(.* doesn't exist)/g, format: red },
- { regExp: /('\w+' option has not been set)/g, format: red },
- {
- regExp: /(Emitted value instead of an instance of Error)/g,
- format: yellow
- },
- { regExp: /(Used? .+ instead)/gi, format: yellow },
- { regExp: /\b(deprecated|must|required)\b/g, format: yellow },
- {
- regExp: /\b(BREAKING CHANGE)\b/gi,
- format: red
- },
- {
- regExp:
- /\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,
- format: red
- }
- ];
- for (const { regExp, format } of highlights) {
- message = message.replace(
- regExp,
- /**
- * @param {string} match match
- * @param {string} content content
- * @returns {string} result
- */
- (match, content) => match.replace(content, format(content))
- );
- }
- return message;
- }
- };
- /** @typedef {(result: string) => string} ResultModifierFn */
- /** @type {Record<string, ResultModifierFn>} */
- const RESULT_MODIFIER = {
- "module.modules": result => indent(result, "| ")
- };
- /**
- * @param {string[]} array array
- * @param {string[]} preferredOrder preferred order
- * @returns {string[]} result
- */
- const createOrder = (array, preferredOrder) => {
- const originalArray = array.slice();
- /** @type {Set<string>} */
- const set = new Set(array);
- /** @type {Set<string>} */
- const usedSet = new Set();
- array.length = 0;
- for (const element of preferredOrder) {
- if (element.endsWith("!") || set.has(element)) {
- array.push(element);
- usedSet.add(element);
- }
- }
- for (const element of originalArray) {
- if (!usedSet.has(element)) {
- array.push(element);
- }
- }
- return array;
- };
- const PLUGIN_NAME = "DefaultStatsPrinterPlugin";
- class DefaultStatsPrinterPlugin {
- /**
- * Apply the plugin
- * @param {Compiler} compiler the compiler instance
- * @returns {void}
- */
- apply(compiler) {
- compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
- compilation.hooks.statsPrinter.tap(PLUGIN_NAME, (stats, options) => {
- // Put colors into context
- stats.hooks.print
- .for("compilation")
- .tap(PLUGIN_NAME, (compilation, context) => {
- for (const color of Object.keys(AVAILABLE_COLORS)) {
- const name =
- /** @type {keyof KnownStatsPrinterColorFunctions} */
- (color);
- /** @type {string | undefined} */
- let start;
- if (options.colors) {
- if (
- typeof options.colors === "object" &&
- typeof options.colors[name] === "string"
- ) {
- start = options.colors[name];
- } else {
- start = AVAILABLE_COLORS[name];
- }
- }
- if (start) {
- /** @type {ColorFunction} */
- context[color] = str =>
- `${start}${
- typeof str === "string"
- ? str.replace(
- /((\u001B\[39m|\u001B\[22m|\u001B\[0m)+)/g,
- `$1${start}`
- )
- : str
- }\u001B[39m\u001B[22m`;
- } else {
- /**
- * @param {string} str string
- * @returns {string} str string
- */
- context[color] = str => str;
- }
- }
- for (const format of Object.keys(AVAILABLE_FORMATS)) {
- context[format] =
- /**
- * @param {string | number} content content
- * @param {...TODO} args args
- * @returns {string} result
- */
- (content, ...args) =>
- /** @type {TODO} */
- (
- AVAILABLE_FORMATS[
- /** @type {keyof AvailableFormats} */
- (format)
- ]
- )(
- content,
- /** @type {StatsPrinterContext & Required<KnownStatsPrinterColorFunctions>} */
- (context),
- ...args
- );
- }
- context.timeReference = compilation.time;
- });
- for (const key of Object.keys(COMPILATION_SIMPLE_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {TODO} */
- (
- COMPILATION_SIMPLE_PRINTERS[
- /** @type {keyof CompilationSimplePrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"compilation">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(ASSET_SIMPLE_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {NonNullable<AssetSimplePrinters[keyof AssetSimplePrinters]>} */
- (
- ASSET_SIMPLE_PRINTERS[
- /** @type {keyof AssetSimplePrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"asset" | "asset.info">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(MODULE_SIMPLE_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {TODO} */
- (
- MODULE_SIMPLE_PRINTERS[
- /** @type {keyof ModuleSimplePrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"module">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(MODULE_ISSUER_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {NonNullable<ModuleIssuerPrinters[keyof ModuleIssuerPrinters]>} */
- (
- MODULE_ISSUER_PRINTERS[
- /** @type {keyof ModuleIssuerPrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"moduleIssuer">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(MODULE_REASON_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {TODO} */
- (
- MODULE_REASON_PRINTERS[
- /** @type {keyof ModuleReasonsPrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"moduleReason">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(MODULE_PROFILE_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {NonNullable<ModuleProfilePrinters[keyof ModuleProfilePrinters]>} */
- (
- MODULE_PROFILE_PRINTERS[
- /** @type {keyof ModuleProfilePrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"profile">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(CHUNK_GROUP_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {TODO} */
- (
- CHUNK_GROUP_PRINTERS[
- /** @type {keyof ChunkGroupPrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"chunkGroupKind" | "chunkGroup">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(CHUNK_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {TODO} */
- (CHUNK_PRINTERS[/** @type {keyof ChunkPrinters} */ (key)])(
- obj,
- /** @type {DefineStatsPrinterContext<"chunk">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(ERROR_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {TODO} */
- (ERROR_PRINTERS[/** @type {keyof ErrorPrinters} */ (key)])(
- obj,
- /** @type {DefineStatsPrinterContext<"error">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(LOG_ENTRY_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {TODO} */
- (
- LOG_ENTRY_PRINTERS[
- /** @type {keyof LogEntryPrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"logging">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(MODULE_TRACE_DEPENDENCY_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {NonNullable<ModuleTraceDependencyPrinters[keyof ModuleTraceDependencyPrinters]>} */
- (
- MODULE_TRACE_DEPENDENCY_PRINTERS[
- /** @type {keyof ModuleTraceDependencyPrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"moduleTraceDependency">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(MODULE_TRACE_ITEM_PRINTERS)) {
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
- /** @type {NonNullable<ModuleTraceItemPrinters[keyof ModuleTraceItemPrinters]>} */
- (
- MODULE_TRACE_ITEM_PRINTERS[
- /** @type {keyof ModuleTraceItemPrinters} */
- (key)
- ]
- )(
- obj,
- /** @type {DefineStatsPrinterContext<"moduleTraceItem">} */
- (ctx),
- stats
- )
- );
- }
- for (const key of Object.keys(PREFERRED_ORDERS)) {
- const preferredOrder = PREFERRED_ORDERS[key];
- stats.hooks.sortElements
- .for(key)
- .tap(PLUGIN_NAME, (elements, context) => {
- createOrder(elements, preferredOrder);
- });
- }
- for (const key of Object.keys(ITEM_NAMES)) {
- const itemName = ITEM_NAMES[key];
- stats.hooks.getItemName
- .for(key)
- .tap(
- PLUGIN_NAME,
- typeof itemName === "string" ? () => itemName : itemName
- );
- }
- for (const key of Object.keys(SIMPLE_ITEMS_JOINER)) {
- const joiner = SIMPLE_ITEMS_JOINER[key];
- stats.hooks.printItems.for(key).tap(PLUGIN_NAME, joiner);
- }
- for (const key of Object.keys(SIMPLE_ELEMENT_JOINERS)) {
- const joiner = SIMPLE_ELEMENT_JOINERS[key];
- stats.hooks.printElements
- .for(key)
- .tap(PLUGIN_NAME, /** @type {TODO} */ (joiner));
- }
- for (const key of Object.keys(RESULT_MODIFIER)) {
- const modifier = RESULT_MODIFIER[key];
- stats.hooks.result.for(key).tap(PLUGIN_NAME, modifier);
- }
- });
- });
- }
- }
- module.exports = DefaultStatsPrinterPlugin;
|