()
| 4817 | } |
| 4818 | |
| 4819 | createHash() { |
| 4820 | this.logger.time(class="st">"hashing: initialize hash"); |
| 4821 | const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); |
| 4822 | const runtimeTemplate = this.runtimeTemplate; |
| 4823 | const outputOptions = this.outputOptions; |
| 4824 | const hashFunction = outputOptions.hashFunction; |
| 4825 | const hashDigest = outputOptions.hashDigest; |
| 4826 | const hashDigestLength = outputOptions.hashDigestLength; |
| 4827 | const hash = createHash(hashFunction); |
| 4828 | if (outputOptions.hashSalt) { |
| 4829 | hash.update(outputOptions.hashSalt); |
| 4830 | } |
| 4831 | this.logger.timeEnd(class="st">"hashing: initialize hash"); |
| 4832 | if (this.children.length > 0) { |
| 4833 | this.logger.time(class="st">"hashing: hash child compilations"); |
| 4834 | for (const child of this.children) { |
| 4835 | hash.update(/** @type {string} */ (child.hash)); |
| 4836 | } |
| 4837 | this.logger.timeEnd(class="st">"hashing: hash child compilations"); |
| 4838 | } |
| 4839 | if (this.warnings.length > 0) { |
| 4840 | this.logger.time(class="st">"hashing: hash warnings"); |
| 4841 | for (const warning of this.warnings) { |
| 4842 | hash.update(`${warning.message}`); |
| 4843 | } |
| 4844 | this.logger.timeEnd(class="st">"hashing: hash warnings"); |
| 4845 | } |
| 4846 | if (this.errors.length > 0) { |
| 4847 | this.logger.time(class="st">"hashing: hash errors"); |
| 4848 | for (const error of this.errors) { |
| 4849 | hash.update(`${error.message}`); |
| 4850 | } |
| 4851 | this.logger.timeEnd(class="st">"hashing: hash errors"); |
| 4852 | } |
| 4853 | |
| 4854 | this.logger.time(class="st">"hashing: sort chunks"); |
| 4855 | /* |
| 4856 | * Chunks are hashed in 4 categories, in this order: |
| 4857 | * 1. Async chunks - no hash dependencies on other chunks |
| 4858 | * 2. Non-entry initial chunks (e.g. shared split chunks) - no hash |
| 4859 | * dependencies on other chunks, but runtime chunks may read their |
| 4860 | * hashes via GetChunkFilenameRuntimeModule (dependentHash) |
| 4861 | * 3. Runtime chunks - may use hashes of async and non-entry initial |
| 4862 | * chunks (via GetChunkFilenameRuntimeModule). Ordered by references |
| 4863 | * between each other (for async entrypoints) |
| 4864 | * 4. Entry chunks - may depend on runtimeChunk.hash (via |
| 4865 | * createChunkHashHandler for ESM/CJS entry importing runtime) |
| 4866 | * |
| 4867 | * This ordering ensures all hash dependencies flow in one direction: |
| 4868 | * async/initial → runtime → entry, with no circular dependencies. |
| 4869 | * Chunks within each category are sorted by id for determinism. |
| 4870 | */ |
| 4871 | /** @type {Chunk[]} */ |
| 4872 | const unorderedRuntimeChunks = []; |
| 4873 | /** @type {Chunk[]} */ |
| 4874 | const initialChunks = []; |
| 4875 | /** @type {Chunk[]} */ |
| 4876 | const entryChunks = []; |
no test coverage detected