UNPKG

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