source: imaps-frontend/node_modules/webpack/lib/ModuleInfoHeaderPlugin.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 8.9 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
8const { ConcatSource, RawSource, CachedSource } = require("webpack-sources");
9const { UsageState } = require("./ExportsInfo");
10const Template = require("./Template");
11const CssModulesPlugin = require("./css/CssModulesPlugin");
12const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
13
14/** @typedef {import("webpack-sources").Source} Source */
15/** @typedef {import("./Compiler")} Compiler */
16/** @typedef {import("./ExportsInfo")} ExportsInfo */
17/** @typedef {import("./ExportsInfo").ExportInfo} ExportInfo */
18/** @typedef {import("./Module")} Module */
19/** @typedef {import("./Module").BuildMeta} BuildMeta */
20/** @typedef {import("./ModuleGraph")} ModuleGraph */
21/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
22/** @typedef {import("./RequestShortener")} RequestShortener */
23
24/**
25 * @template T
26 * @param {Iterable<T>} iterable iterable
27 * @returns {string} joined with comma
28 */
29const joinIterableWithComma = iterable => {
30 // This is more performant than Array.from().join(", ")
31 // as it doesn't create an array
32 let str = "";
33 let first = true;
34 for (const item of iterable) {
35 if (first) {
36 first = false;
37 } else {
38 str += ", ";
39 }
40 str += item;
41 }
42 return str;
43};
44
45/**
46 * @param {ConcatSource} source output
47 * @param {string} indent spacing
48 * @param {ExportsInfo} exportsInfo data
49 * @param {ModuleGraph} moduleGraph moduleGraph
50 * @param {RequestShortener} requestShortener requestShortener
51 * @param {Set<ExportInfo>} alreadyPrinted deduplication set
52 * @returns {void}
53 */
54const printExportsInfoToSource = (
55 source,
56 indent,
57 exportsInfo,
58 moduleGraph,
59 requestShortener,
60 alreadyPrinted = new Set()
61) => {
62 const otherExportsInfo = exportsInfo.otherExportsInfo;
63
64 let alreadyPrintedExports = 0;
65
66 // determine exports to print
67 const printedExports = [];
68 for (const exportInfo of exportsInfo.orderedExports) {
69 if (!alreadyPrinted.has(exportInfo)) {
70 alreadyPrinted.add(exportInfo);
71 printedExports.push(exportInfo);
72 } else {
73 alreadyPrintedExports++;
74 }
75 }
76 let showOtherExports = false;
77 if (!alreadyPrinted.has(otherExportsInfo)) {
78 alreadyPrinted.add(otherExportsInfo);
79 showOtherExports = true;
80 } else {
81 alreadyPrintedExports++;
82 }
83
84 // print the exports
85 for (const exportInfo of printedExports) {
86 const target = exportInfo.getTarget(moduleGraph);
87 source.add(
88 `${Template.toComment(
89 `${indent}export ${JSON.stringify(exportInfo.name).slice(
90 1,
91 -1
92 )} [${exportInfo.getProvidedInfo()}] [${exportInfo.getUsedInfo()}] [${exportInfo.getRenameInfo()}]${
93 target
94 ? ` -> ${target.module.readableIdentifier(requestShortener)}${
95 target.export
96 ? ` .${target.export
97 .map(e => JSON.stringify(e).slice(1, -1))
98 .join(".")}`
99 : ""
100 }`
101 : ""
102 }`
103 )}\n`
104 );
105 if (exportInfo.exportsInfo) {
106 printExportsInfoToSource(
107 source,
108 `${indent} `,
109 exportInfo.exportsInfo,
110 moduleGraph,
111 requestShortener,
112 alreadyPrinted
113 );
114 }
115 }
116
117 if (alreadyPrintedExports) {
118 source.add(
119 `${Template.toComment(
120 `${indent}... (${alreadyPrintedExports} already listed exports)`
121 )}\n`
122 );
123 }
124
125 if (showOtherExports) {
126 const target = otherExportsInfo.getTarget(moduleGraph);
127 if (
128 target ||
129 otherExportsInfo.provided !== false ||
130 otherExportsInfo.getUsed(undefined) !== UsageState.Unused
131 ) {
132 const title =
133 printedExports.length > 0 || alreadyPrintedExports > 0
134 ? "other exports"
135 : "exports";
136 source.add(
137 `${Template.toComment(
138 `${indent}${title} [${otherExportsInfo.getProvidedInfo()}] [${otherExportsInfo.getUsedInfo()}]${
139 target
140 ? ` -> ${target.module.readableIdentifier(requestShortener)}`
141 : ""
142 }`
143 )}\n`
144 );
145 }
146 }
147};
148
149/** @type {WeakMap<RequestShortener, WeakMap<Module, { header: RawSource | undefined, full: WeakMap<Source, CachedSource> }>>} */
150const caches = new WeakMap();
151
152class ModuleInfoHeaderPlugin {
153 /**
154 * @param {boolean=} verbose add more information like exports, runtime requirements and bailouts
155 */
156 constructor(verbose = true) {
157 this._verbose = verbose;
158 }
159
160 /**
161 * @param {Compiler} compiler the compiler
162 * @returns {void}
163 */
164 apply(compiler) {
165 const { _verbose: verbose } = this;
166 compiler.hooks.compilation.tap("ModuleInfoHeaderPlugin", compilation => {
167 const javascriptHooks =
168 JavascriptModulesPlugin.getCompilationHooks(compilation);
169 javascriptHooks.renderModulePackage.tap(
170 "ModuleInfoHeaderPlugin",
171 (
172 moduleSource,
173 module,
174 { chunk, chunkGraph, moduleGraph, runtimeTemplate }
175 ) => {
176 const { requestShortener } = runtimeTemplate;
177 let cacheEntry;
178 let cache = caches.get(requestShortener);
179 if (cache === undefined) {
180 caches.set(requestShortener, (cache = new WeakMap()));
181 cache.set(
182 module,
183 (cacheEntry = { header: undefined, full: new WeakMap() })
184 );
185 } else {
186 cacheEntry = cache.get(module);
187 if (cacheEntry === undefined) {
188 cache.set(
189 module,
190 (cacheEntry = { header: undefined, full: new WeakMap() })
191 );
192 } else if (!verbose) {
193 const cachedSource = cacheEntry.full.get(moduleSource);
194 if (cachedSource !== undefined) return cachedSource;
195 }
196 }
197 const source = new ConcatSource();
198 let header = cacheEntry.header;
199 if (header === undefined) {
200 header = this.generateHeader(module, requestShortener);
201 cacheEntry.header = header;
202 }
203 source.add(header);
204 if (verbose) {
205 const exportsType = /** @type {BuildMeta} */ (module.buildMeta)
206 .exportsType;
207 source.add(
208 `${Template.toComment(
209 exportsType
210 ? `${exportsType} exports`
211 : "unknown exports (runtime-defined)"
212 )}\n`
213 );
214 if (exportsType) {
215 const exportsInfo = moduleGraph.getExportsInfo(module);
216 printExportsInfoToSource(
217 source,
218 "",
219 exportsInfo,
220 moduleGraph,
221 requestShortener
222 );
223 }
224 source.add(
225 `${Template.toComment(
226 `runtime requirements: ${joinIterableWithComma(
227 chunkGraph.getModuleRuntimeRequirements(module, chunk.runtime)
228 )}`
229 )}\n`
230 );
231 const optimizationBailout =
232 moduleGraph.getOptimizationBailout(module);
233 if (optimizationBailout) {
234 for (const text of optimizationBailout) {
235 const code =
236 typeof text === "function" ? text(requestShortener) : text;
237 source.add(`${Template.toComment(`${code}`)}\n`);
238 }
239 }
240 source.add(moduleSource);
241 return source;
242 }
243 source.add(moduleSource);
244 const cachedSource = new CachedSource(source);
245 cacheEntry.full.set(moduleSource, cachedSource);
246 return cachedSource;
247 }
248 );
249 javascriptHooks.chunkHash.tap(
250 "ModuleInfoHeaderPlugin",
251 (_chunk, hash) => {
252 hash.update("ModuleInfoHeaderPlugin");
253 hash.update("1");
254 }
255 );
256 const cssHooks = CssModulesPlugin.getCompilationHooks(compilation);
257 cssHooks.renderModulePackage.tap(
258 "ModuleInfoHeaderPlugin",
259 (moduleSource, module, { runtimeTemplate }) => {
260 const { requestShortener } = runtimeTemplate;
261 let cacheEntry;
262 let cache = caches.get(requestShortener);
263 if (cache === undefined) {
264 caches.set(requestShortener, (cache = new WeakMap()));
265 cache.set(
266 module,
267 (cacheEntry = { header: undefined, full: new WeakMap() })
268 );
269 } else {
270 cacheEntry = cache.get(module);
271 if (cacheEntry === undefined) {
272 cache.set(
273 module,
274 (cacheEntry = { header: undefined, full: new WeakMap() })
275 );
276 } else if (!verbose) {
277 const cachedSource = cacheEntry.full.get(moduleSource);
278 if (cachedSource !== undefined) return cachedSource;
279 }
280 }
281 const source = new ConcatSource();
282 let header = cacheEntry.header;
283 if (header === undefined) {
284 header = this.generateHeader(module, requestShortener);
285 cacheEntry.header = header;
286 }
287 source.add(header);
288 source.add(moduleSource);
289 const cachedSource = new CachedSource(source);
290 cacheEntry.full.set(moduleSource, cachedSource);
291 return cachedSource;
292 }
293 );
294 cssHooks.chunkHash.tap("ModuleInfoHeaderPlugin", (_chunk, hash) => {
295 hash.update("ModuleInfoHeaderPlugin");
296 hash.update("1");
297 });
298 });
299 }
300
301 /**
302 * @param {Module} module the module
303 * @param {RequestShortener} requestShortener request shortener
304 * @returns {RawSource} the header
305 */
306 generateHeader(module, requestShortener) {
307 const req = module.readableIdentifier(requestShortener);
308 const reqStr = req.replace(/\*\//g, "*_/");
309 const reqStrStar = "*".repeat(reqStr.length);
310 const headerStr = `/*!****${reqStrStar}****!*\\\n !*** ${reqStr} ***!\n \\****${reqStrStar}****/\n`;
311 return new RawSource(headerStr);
312 }
313}
314module.exports = ModuleInfoHeaderPlugin;
Note: See TracBrowser for help on using the repository browser.