Skip to content

Commit c211dbe

Browse files
mango766easonysliuclaude
authored
fix: sort ConcatenatedModule export keys for deterministic builds (#13425)
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 #13182 Co-authored-by: easonysliu <easonysliu@tencent.com> Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com>
1 parent bc12760 commit c211dbe

1 file changed

Lines changed: 15 additions & 8 deletions

File tree

crates/rspack_core/src/concatenated_module.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,14 +1621,21 @@ impl Module for ConcatenatedModule {
16211621

16221622
// Define exports
16231623
if !exports_map.is_empty() {
1624-
let mut definitions = Vec::new();
1625-
for (key, value) in exports_map.iter() {
1626-
definitions.push(format!(
1627-
"\n {}: {}",
1628-
property_name(key).expect("should convert to property_name"),
1629-
runtime_template.returning_function(value, "")
1630-
));
1631-
}
1624+
let mut definitions: Vec<_> = exports_map
1625+
.iter()
1626+
.map(|(key, value)| {
1627+
(
1628+
key.clone(),
1629+
format!(
1630+
"\n {}: {}",
1631+
property_name(key).expect("should convert to property_name"),
1632+
runtime_template.returning_function(value, "")
1633+
),
1634+
)
1635+
})
1636+
.collect();
1637+
definitions.sort_by(|a, b| a.0.cmp(&b.0));
1638+
let definitions: Vec<_> = definitions.into_iter().map(|(_, s)| s).collect();
16321639

16331640
let exports_argument = self.get_exports_argument();
16341641

0 commit comments

Comments
 (0)