* Applies the plugin by registering its hooks on the compiler. * @param {Compiler} compiler the compiler instance * @returns {void}
(compiler)
| 21 | * @returns {void} |
| 22 | */ |
| 23 | apply(compiler) { |
| 24 | compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => { |
| 25 | compilation.hooks.optimizeChunkIds.tap(PLUGIN_NAME, (chunks) => { |
| 26 | const chunkGraph = compilation.chunkGraph; |
| 27 | |
| 28 | // prepare two bit integers for each module |
| 29 | // 2^31 is the max number represented as SMI in v8 |
| 30 | // we want the bits distributed this way: |
| 31 | // the bit 2^31 is pretty rar and only one module should get it |
| 32 | // so it has a probability of 1 / modulesCount |
| 33 | // the first bit (2^0) is the easiest and every module could get it |
| 34 | // if it doesn't get a better bit |
| 35 | // from bit 2^n to 2^(n+1) there is a probability of p |
| 36 | // so 1 / modulesCount == p^31 |
| 37 | // <=> p = sqrt31(1 / modulesCount) |
| 38 | // so we use a modulo of 1 / sqrt31(1 / modulesCount) |
| 39 | /** @type {WeakMap<Module, number>} */ |
| 40 | const moduleBits = new WeakMap(); |
| 41 | const modulesCount = compilation.modules.size; |
| 42 | |
| 43 | // precalculate the modulo values for each bit |
| 44 | const modulo = 1 / (1 / modulesCount) ** (1 / 31); |
| 45 | /** @type {number[]} */ |
| 46 | const modulos = Array.from( |
| 47 | { length: 31 }, |
| 48 | /** |
| 49 | * Handles the callback logic for this hook. |
| 50 | * @param {number} x x |
| 51 | * @param {number} i i |
| 52 | * @returns {number} result |
| 53 | */ |
| 54 | (x, i) => (modulo ** i) | 0 |
| 55 | ); |
| 56 | |
| 57 | // iterate all modules to generate bit values |
| 58 | let i = 0; |
| 59 | for (const module of compilation.modules) { |
| 60 | let bit = 30; |
| 61 | while (i % modulos[bit] !== 0) { |
| 62 | bit--; |
| 63 | } |
| 64 | moduleBits.set(module, 1 << bit); |
| 65 | i++; |
| 66 | } |
| 67 | |
| 68 | // iterate all chunks to generate bitmaps |
| 69 | /** @type {WeakMap<Chunk, number>} */ |
| 70 | const chunkModulesHash = new WeakMap(); |
| 71 | for (const chunk of chunks) { |
| 72 | let hash = 0; |
| 73 | for (const module of chunkGraph.getChunkModulesIterable(chunk)) { |
| 74 | hash |= /** @type {number} */ (moduleBits.get(module)); |
| 75 | } |
| 76 | chunkModulesHash.set(chunk, hash); |
| 77 | } |
| 78 | |
| 79 | for (const chunkA of chunks) { |
| 80 | const chunkAHash = |
nothing calls this directly
no test coverage detected