source: trip-planner-front/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js@ ceaed42

Last change on this file since ceaed42 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.7 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
8/** @typedef {import("../Chunk")} Chunk */
9/** @typedef {import("../Compiler")} Compiler */
10/** @typedef {import("../Module")} Module */
11
12class FlagIncludedChunksPlugin {
13 /**
14 * Apply the plugin
15 * @param {Compiler} compiler the compiler instance
16 * @returns {void}
17 */
18 apply(compiler) {
19 compiler.hooks.compilation.tap("FlagIncludedChunksPlugin", compilation => {
20 compilation.hooks.optimizeChunkIds.tap(
21 "FlagIncludedChunksPlugin",
22 chunks => {
23 const chunkGraph = compilation.chunkGraph;
24
25 // prepare two bit integers for each module
26 // 2^31 is the max number represented as SMI in v8
27 // we want the bits distributed this way:
28 // the bit 2^31 is pretty rar and only one module should get it
29 // so it has a probability of 1 / modulesCount
30 // the first bit (2^0) is the easiest and every module could get it
31 // if it doesn't get a better bit
32 // from bit 2^n to 2^(n+1) there is a probability of p
33 // so 1 / modulesCount == p^31
34 // <=> p = sqrt31(1 / modulesCount)
35 // so we use a modulo of 1 / sqrt31(1 / modulesCount)
36 /** @type {WeakMap<Module, number>} */
37 const moduleBits = new WeakMap();
38 const modulesCount = compilation.modules.size;
39
40 // precalculate the modulo values for each bit
41 const modulo = 1 / Math.pow(1 / modulesCount, 1 / 31);
42 const modulos = Array.from(
43 { length: 31 },
44 (x, i) => Math.pow(modulo, i) | 0
45 );
46
47 // iterate all modules to generate bit values
48 let i = 0;
49 for (const module of compilation.modules) {
50 let bit = 30;
51 while (i % modulos[bit] !== 0) {
52 bit--;
53 }
54 moduleBits.set(module, 1 << bit);
55 i++;
56 }
57
58 // iterate all chunks to generate bitmaps
59 /** @type {WeakMap<Chunk, number>} */
60 const chunkModulesHash = new WeakMap();
61 for (const chunk of chunks) {
62 let hash = 0;
63 for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
64 hash |= moduleBits.get(module);
65 }
66 chunkModulesHash.set(chunk, hash);
67 }
68
69 for (const chunkA of chunks) {
70 const chunkAHash = chunkModulesHash.get(chunkA);
71 const chunkAModulesCount =
72 chunkGraph.getNumberOfChunkModules(chunkA);
73 if (chunkAModulesCount === 0) continue;
74 let bestModule = undefined;
75 for (const module of chunkGraph.getChunkModulesIterable(chunkA)) {
76 if (
77 bestModule === undefined ||
78 chunkGraph.getNumberOfModuleChunks(bestModule) >
79 chunkGraph.getNumberOfModuleChunks(module)
80 )
81 bestModule = module;
82 }
83 loopB: for (const chunkB of chunkGraph.getModuleChunksIterable(
84 bestModule
85 )) {
86 // as we iterate the same iterables twice
87 // skip if we find ourselves
88 if (chunkA === chunkB) continue;
89
90 const chunkBModulesCount =
91 chunkGraph.getNumberOfChunkModules(chunkB);
92
93 // ids for empty chunks are not included
94 if (chunkBModulesCount === 0) continue;
95
96 // instead of swapping A and B just bail
97 // as we loop twice the current A will be B and B then A
98 if (chunkAModulesCount > chunkBModulesCount) continue;
99
100 // is chunkA in chunkB?
101
102 // we do a cheap check for the hash value
103 const chunkBHash = chunkModulesHash.get(chunkB);
104 if ((chunkBHash & chunkAHash) !== chunkAHash) continue;
105
106 // compare all modules
107 for (const m of chunkGraph.getChunkModulesIterable(chunkA)) {
108 if (!chunkGraph.isModuleInChunk(m, chunkB)) continue loopB;
109 }
110 chunkB.ids.push(chunkA.id);
111 }
112 }
113 }
114 );
115 });
116 }
117}
118module.exports = FlagIncludedChunksPlugin;
Note: See TracBrowser for help on using the repository browser.