fix: sort ConcatenatedModule export keys for deterministic builds#13425
fix: sort ConcatenatedModule export keys for deterministic builds#13425mango766 wants to merge 1 commit intoweb-infra-dev:mainfrom
Conversation
Sort exports_map entries by key before rendering the
__webpack_require__.d(exports, {...}) object in ConcatenatedModule.
HashMap iteration order is non-deterministic, causing identical source
to produce different content hashes across builds.
This matches the approach already used in ESMExportInitFragment
(init_fragment.rs:356) where export_map is sorted before rendering.
Closes web-infra-dev#13182
Co-Authored-By: Claude (claude-opus-4-6) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6594e19f01
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| ) | ||
| }) | ||
| .collect(); | ||
| definitions.sort_by(|a, b| a.0.cmp(&b.0)); |
There was a problem hiding this comment.
Sort the remaining export-name comments for deterministic output
If the nondeterminism here comes from iterating FxHashMap<Atom, _>, this change only stabilizes the definitions object. The same code path still appends // UNUSED EXPORTS and // INLINED EXPORTS by joining FxHashSet<Atom> iterators directly in crates/rspack_core/src/concatenated_module.rs:1637-1648, so any concatenated module that tree-shakes or inlines an export will still produce run-to-run byte differences in non-minified/comment-preserving builds.
Useful? React with 👍 / 👎.
Merging this PR will not alter performance
Comparing Footnotes
|
|
Thanks You can use IndexMap directly to avoid sorting, and you could do the same for |
Summary
Sort
exports_mapentries by key before rendering the__webpack_require__.d(exports, {...})object inConcatenatedModule.exports_mapis aHashMap<Atom, String>, so.iter()produces non-deterministic iteration order. This means the same source code can produce different export key ordering across builds, leading to different content hashes for the same chunk — even with no code changes.The fix collects entries into a vec, sorts by key, then builds the definitions string. This matches the approach already used in
ESMExportInitFragment(init_fragment.rs:356) whereexport_mapis sorted before rendering.Related links
Closes #13182
Checklist