1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const createHash = require("../util/createHash");
|
9 | const { makePathsRelative } = require("../util/identifier");
|
10 | const numberHash = require("../util/numberHash");
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | const getHash = (str, len, hashFunction) => {
|
25 | const hash = createHash(hashFunction);
|
26 | hash.update(str);
|
27 | const digest = (hash.digest("hex"));
|
28 | return digest.substr(0, len);
|
29 | };
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | const avoidNumber = str => {
|
36 |
|
37 | if (str.length > 21) return str;
|
38 | const firstChar = str.charCodeAt(0);
|
39 |
|
40 |
|
41 | if (firstChar < 49) {
|
42 | if (firstChar !== 45) return str;
|
43 | } else if (firstChar > 57) {
|
44 | return str;
|
45 | }
|
46 | if (str === +str + "") {
|
47 | return `_${str}`;
|
48 | }
|
49 | return str;
|
50 | };
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 | const requestToId = request => {
|
57 | return request
|
58 | .replace(/^(\.\.?\/)+/, "")
|
59 | .replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_");
|
60 | };
|
61 | exports.requestToId = requestToId;
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | const shortenLongString = (string, delimiter, hashFunction) => {
|
70 | if (string.length < 100) return string;
|
71 | return (
|
72 | string.slice(0, 100 - 6 - delimiter.length) +
|
73 | delimiter +
|
74 | getHash(string, 6, hashFunction)
|
75 | );
|
76 | };
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 | const getShortModuleName = (module, context, associatedObjectForCache) => {
|
85 | const libIdent = module.libIdent({ context, associatedObjectForCache });
|
86 | if (libIdent) return avoidNumber(libIdent);
|
87 | const nameForCondition = module.nameForCondition();
|
88 | if (nameForCondition)
|
89 | return avoidNumber(
|
90 | makePathsRelative(context, nameForCondition, associatedObjectForCache)
|
91 | );
|
92 | return "";
|
93 | };
|
94 | exports.getShortModuleName = getShortModuleName;
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 | const getLongModuleName = (
|
105 | shortName,
|
106 | module,
|
107 | context,
|
108 | hashFunction,
|
109 | associatedObjectForCache
|
110 | ) => {
|
111 | const fullName = getFullModuleName(module, context, associatedObjectForCache);
|
112 | return `${shortName}?${getHash(fullName, 4, hashFunction)}`;
|
113 | };
|
114 | exports.getLongModuleName = getLongModuleName;
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 | const getFullModuleName = (module, context, associatedObjectForCache) => {
|
123 | return makePathsRelative(
|
124 | context,
|
125 | module.identifier(),
|
126 | associatedObjectForCache
|
127 | );
|
128 | };
|
129 | exports.getFullModuleName = getFullModuleName;
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 | const getShortChunkName = (
|
141 | chunk,
|
142 | chunkGraph,
|
143 | context,
|
144 | delimiter,
|
145 | hashFunction,
|
146 | associatedObjectForCache
|
147 | ) => {
|
148 | const modules = chunkGraph.getChunkRootModules(chunk);
|
149 | const shortModuleNames = modules.map(m =>
|
150 | requestToId(getShortModuleName(m, context, associatedObjectForCache))
|
151 | );
|
152 | chunk.idNameHints.sort();
|
153 | const chunkName = Array.from(chunk.idNameHints)
|
154 | .concat(shortModuleNames)
|
155 | .filter(Boolean)
|
156 | .join(delimiter);
|
157 | return shortenLongString(chunkName, delimiter, hashFunction);
|
158 | };
|
159 | exports.getShortChunkName = getShortChunkName;
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 | const getLongChunkName = (
|
171 | chunk,
|
172 | chunkGraph,
|
173 | context,
|
174 | delimiter,
|
175 | hashFunction,
|
176 | associatedObjectForCache
|
177 | ) => {
|
178 | const modules = chunkGraph.getChunkRootModules(chunk);
|
179 | const shortModuleNames = modules.map(m =>
|
180 | requestToId(getShortModuleName(m, context, associatedObjectForCache))
|
181 | );
|
182 | const longModuleNames = modules.map(m =>
|
183 | requestToId(
|
184 | getLongModuleName("", m, context, hashFunction, associatedObjectForCache)
|
185 | )
|
186 | );
|
187 | chunk.idNameHints.sort();
|
188 | const chunkName = Array.from(chunk.idNameHints)
|
189 | .concat(shortModuleNames, longModuleNames)
|
190 | .filter(Boolean)
|
191 | .join(delimiter);
|
192 | return shortenLongString(chunkName, delimiter, hashFunction);
|
193 | };
|
194 | exports.getLongChunkName = getLongChunkName;
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 | const getFullChunkName = (
|
204 | chunk,
|
205 | chunkGraph,
|
206 | context,
|
207 | associatedObjectForCache
|
208 | ) => {
|
209 | if (chunk.name) return chunk.name;
|
210 | const modules = chunkGraph.getChunkRootModules(chunk);
|
211 | const fullModuleNames = modules.map(m =>
|
212 | makePathsRelative(context, m.identifier(), associatedObjectForCache)
|
213 | );
|
214 | return fullModuleNames.join();
|
215 | };
|
216 | exports.getFullChunkName = getFullChunkName;
|
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 | const addToMapOfItems = (map, key, value) => {
|
227 | let array = map.get(key);
|
228 | if (array === undefined) {
|
229 | array = [];
|
230 | map.set(key, array);
|
231 | }
|
232 | array.push(value);
|
233 | };
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 | const getUsedModuleIds = compilation => {
|
240 | const chunkGraph = compilation.chunkGraph;
|
241 |
|
242 |
|
243 | const usedIds = new Set();
|
244 | if (compilation.usedModuleIds) {
|
245 | for (const id of compilation.usedModuleIds) {
|
246 | usedIds.add(id + "");
|
247 | }
|
248 | }
|
249 |
|
250 | for (const module of compilation.modules) {
|
251 | const moduleId = chunkGraph.getModuleId(module);
|
252 | if (moduleId !== null) {
|
253 | usedIds.add(moduleId + "");
|
254 | }
|
255 | }
|
256 |
|
257 | return usedIds;
|
258 | };
|
259 | exports.getUsedModuleIds = getUsedModuleIds;
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 | const getUsedChunkIds = compilation => {
|
266 |
|
267 | const usedIds = new Set();
|
268 | if (compilation.usedChunkIds) {
|
269 | for (const id of compilation.usedChunkIds) {
|
270 | usedIds.add(id + "");
|
271 | }
|
272 | }
|
273 |
|
274 | for (const chunk of compilation.chunks) {
|
275 | const chunkId = chunk.id;
|
276 | if (chunkId !== null) {
|
277 | usedIds.add(chunkId + "");
|
278 | }
|
279 | }
|
280 |
|
281 | return usedIds;
|
282 | };
|
283 | exports.getUsedChunkIds = getUsedChunkIds;
|
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 | const assignNames = (
|
296 | items,
|
297 | getShortName,
|
298 | getLongName,
|
299 | comparator,
|
300 | usedIds,
|
301 | assignName
|
302 | ) => {
|
303 |
|
304 | const nameToItems = new Map();
|
305 |
|
306 | for (const item of items) {
|
307 | const name = getShortName(item);
|
308 | addToMapOfItems(nameToItems, name, item);
|
309 | }
|
310 |
|
311 |
|
312 | const nameToItems2 = new Map();
|
313 |
|
314 | for (const [name, items] of nameToItems) {
|
315 | if (items.length > 1 || !name) {
|
316 | for (const item of items) {
|
317 | const longName = getLongName(item, name);
|
318 | addToMapOfItems(nameToItems2, longName, item);
|
319 | }
|
320 | } else {
|
321 | addToMapOfItems(nameToItems2, name, items[0]);
|
322 | }
|
323 | }
|
324 |
|
325 |
|
326 | const unnamedItems = [];
|
327 |
|
328 | for (const [name, items] of nameToItems2) {
|
329 | if (!name) {
|
330 | for (const item of items) {
|
331 | unnamedItems.push(item);
|
332 | }
|
333 | } else if (items.length === 1 && !usedIds.has(name)) {
|
334 | assignName(items[0], name);
|
335 | usedIds.add(name);
|
336 | } else {
|
337 | items.sort(comparator);
|
338 | let i = 0;
|
339 | for (const item of items) {
|
340 | while (nameToItems2.has(name + i) && usedIds.has(name + i)) i++;
|
341 | assignName(item, name + i);
|
342 | usedIds.add(name + i);
|
343 | i++;
|
344 | }
|
345 | }
|
346 | }
|
347 |
|
348 | unnamedItems.sort(comparator);
|
349 | return unnamedItems;
|
350 | };
|
351 | exports.assignNames = assignNames;
|
352 |
|
353 |
|
354 |
|
355 |
|
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 | const assignDeterministicIds = (
|
365 | items,
|
366 | getName,
|
367 | comparator,
|
368 | assignId,
|
369 | ranges = [10],
|
370 | expandFactor = 10,
|
371 | extraSpace = 0
|
372 | ) => {
|
373 | items.sort(comparator);
|
374 |
|
375 |
|
376 | const optimalRange = Math.min(
|
377 | Math.ceil(items.length * 20) + extraSpace,
|
378 | Number.MAX_SAFE_INTEGER
|
379 | );
|
380 |
|
381 | let i = 0;
|
382 | let range = ranges[i];
|
383 | while (range < optimalRange) {
|
384 | i++;
|
385 | if (i < ranges.length) {
|
386 | range = Math.min(ranges[i], Number.MAX_SAFE_INTEGER);
|
387 | } else {
|
388 | range = Math.min(range * expandFactor, Number.MAX_SAFE_INTEGER);
|
389 | }
|
390 | }
|
391 |
|
392 | for (const item of items) {
|
393 | const ident = getName(item);
|
394 | let id;
|
395 | let i = 0;
|
396 | do {
|
397 | id = numberHash(ident + i++, range);
|
398 | } while (!assignId(item, id));
|
399 | }
|
400 | };
|
401 | exports.assignDeterministicIds = assignDeterministicIds;
|
402 |
|
403 |
|
404 |
|
405 |
|
406 |
|
407 |
|
408 | const assignAscendingModuleIds = (modules, compilation) => {
|
409 | const chunkGraph = compilation.chunkGraph;
|
410 |
|
411 | const usedIds = getUsedModuleIds(compilation);
|
412 |
|
413 | let nextId = 0;
|
414 | let assignId;
|
415 | if (usedIds.size > 0) {
|
416 | assignId = module => {
|
417 | if (chunkGraph.getModuleId(module) === null) {
|
418 | while (usedIds.has(nextId + "")) nextId++;
|
419 | chunkGraph.setModuleId(module, nextId++);
|
420 | }
|
421 | };
|
422 | } else {
|
423 | assignId = module => {
|
424 | if (chunkGraph.getModuleId(module) === null) {
|
425 | chunkGraph.setModuleId(module, nextId++);
|
426 | }
|
427 | };
|
428 | }
|
429 | for (const module of modules) {
|
430 | assignId(module);
|
431 | }
|
432 | };
|
433 | exports.assignAscendingModuleIds = assignAscendingModuleIds;
|
434 |
|
435 |
|
436 |
|
437 |
|
438 |
|
439 |
|
440 | const assignAscendingChunkIds = (chunks, compilation) => {
|
441 | const usedIds = getUsedChunkIds(compilation);
|
442 |
|
443 | let nextId = 0;
|
444 | if (usedIds.size > 0) {
|
445 | for (const chunk of chunks) {
|
446 | if (chunk.id === null) {
|
447 | while (usedIds.has(nextId + "")) nextId++;
|
448 | chunk.id = nextId;
|
449 | chunk.ids = [nextId];
|
450 | nextId++;
|
451 | }
|
452 | }
|
453 | } else {
|
454 | for (const chunk of chunks) {
|
455 | if (chunk.id === null) {
|
456 | chunk.id = nextId;
|
457 | chunk.ids = [nextId];
|
458 | nextId++;
|
459 | }
|
460 | }
|
461 | }
|
462 | };
|
463 | exports.assignAscendingChunkIds = assignAscendingChunkIds;
|