UNPKG

4.22 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const identifierUtils = require("./util/identifier");
9
10/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
11/** @typedef {import("./Stats")} Stats */
12/** @typedef {import("./stats/DefaultStatsFactoryPlugin").KnownStatsCompilation} KnownStatsCompilation */
13/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
14
15const indent = (str, prefix) => {
16 const rem = str.replace(/\n([^\n])/g, "\n" + prefix + "$1");
17 return prefix + rem;
18};
19
20class MultiStats {
21 /**
22 * @param {Stats[]} stats the child stats
23 */
24 constructor(stats) {
25 this.stats = stats;
26 }
27
28 get hash() {
29 return this.stats.map(stat => stat.hash).join("");
30 }
31
32 /**
33 * @returns {boolean} true if a child compilation encountered an error
34 */
35 hasErrors() {
36 return this.stats.some(stat => stat.hasErrors());
37 }
38
39 /**
40 * @returns {boolean} true if a child compilation had a warning
41 */
42 hasWarnings() {
43 return this.stats.some(stat => stat.hasWarnings());
44 }
45
46 _createChildOptions(options, context) {
47 if (!options) {
48 options = {};
49 }
50 const { children: childrenOptions = undefined, ...baseOptions } =
51 typeof options === "string" ? { preset: options } : options;
52 const children = this.stats.map((stat, idx) => {
53 const childOptions = Array.isArray(childrenOptions)
54 ? childrenOptions[idx]
55 : childrenOptions;
56 return stat.compilation.createStatsOptions(
57 {
58 ...baseOptions,
59 ...(typeof childOptions === "string"
60 ? { preset: childOptions }
61 : childOptions && typeof childOptions === "object"
62 ? childOptions
63 : undefined)
64 },
65 context
66 );
67 });
68 return {
69 version: children.every(o => o.version),
70 hash: children.every(o => o.hash),
71 errorsCount: children.every(o => o.errorsCount),
72 warningsCount: children.every(o => o.warningsCount),
73 errors: children.every(o => o.errors),
74 warnings: children.every(o => o.warnings),
75 children
76 };
77 }
78
79 /**
80 * @param {any} options stats options
81 * @returns {StatsCompilation} json output
82 */
83 toJson(options) {
84 options = this._createChildOptions(options, { forToString: false });
85 /** @type {KnownStatsCompilation} */
86 const obj = {};
87 obj.children = this.stats.map((stat, idx) => {
88 const obj = stat.toJson(options.children[idx]);
89 const compilationName = stat.compilation.name;
90 const name =
91 compilationName &&
92 identifierUtils.makePathsRelative(
93 options.context,
94 compilationName,
95 stat.compilation.compiler.root
96 );
97 obj.name = name;
98 return obj;
99 });
100 if (options.version) {
101 obj.version = obj.children[0].version;
102 }
103 if (options.hash) {
104 obj.hash = obj.children.map(j => j.hash).join("");
105 }
106 const mapError = (j, obj) => {
107 return {
108 ...obj,
109 compilerPath: obj.compilerPath
110 ? `${j.name}.${obj.compilerPath}`
111 : j.name
112 };
113 };
114 if (options.errors) {
115 obj.errors = [];
116 for (const j of obj.children) {
117 for (const i of j.errors) {
118 obj.errors.push(mapError(j, i));
119 }
120 }
121 }
122 if (options.warnings) {
123 obj.warnings = [];
124 for (const j of obj.children) {
125 for (const i of j.warnings) {
126 obj.warnings.push(mapError(j, i));
127 }
128 }
129 }
130 if (options.errorsCount) {
131 obj.errorsCount = 0;
132 for (const j of obj.children) {
133 obj.errorsCount += j.errorsCount;
134 }
135 }
136 if (options.warningsCount) {
137 obj.warningsCount = 0;
138 for (const j of obj.children) {
139 obj.warningsCount += j.warningsCount;
140 }
141 }
142 return obj;
143 }
144
145 toString(options) {
146 options = this._createChildOptions(options, { forToString: true });
147 const results = this.stats.map((stat, idx) => {
148 const str = stat.toString(options.children[idx]);
149 const compilationName = stat.compilation.name;
150 const name =
151 compilationName &&
152 identifierUtils
153 .makePathsRelative(
154 options.context,
155 compilationName,
156 stat.compilation.compiler.root
157 )
158 .replace(/\|/g, " ");
159 if (!str) return str;
160 return name ? `${name}:\n${indent(str, " ")}` : str;
161 });
162 return results.filter(Boolean).join("\n\n");
163 }
164}
165
166module.exports = MultiStats;