Skip to content

Commit d0d5156

Browse files
committed
docs(imports): record why ESM value imports are sorted
Sorting value imports is not semantically free — ESM evaluates modules in first-requested order, so reordering two imports of side-effecting modules changes initialization order, demonstrably (a fixture printing ZA before organize prints AZ after). It stays anyway, and the site now says why: Biome with organizeImports enabled reorders the identical fixture, so this is an accepted ecosystem tradeoff rather than an AFT defect, and pinning value imports would make us the only organizer that silently declines to organize a JS file. Code that genuinely depends on evaluation order has the language's own escape hatch — a bare side-effect import, which this organizer already treats as a hard barrier. Written down because the next reader will find the reordering, recognise the hazard, and otherwise 'fix' it into a behavior change.
1 parent 4270d66 commit d0d5156

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

crates/aft/src/commands/organize_imports.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,24 @@ struct OrganizedImport {
689689
}
690690

691691
/// Organize a group of non-Rust imports: sort by module path, deduplicate.
692+
///
693+
/// Sorting ESM value imports is not semantically free: modules evaluate in the
694+
/// order they are first requested, so reordering two imports of side-effecting
695+
/// modules changes initialization order. That is a deliberate accepted cost,
696+
/// not an oversight — every mainstream JS organizer sorts value imports the
697+
/// same way (verified against Biome, which reorders an identical fixture), so
698+
/// pinning them here would make AFT the only tool that silently declines to
699+
/// organize a JS file, and would break the far commoner case of a developer
700+
/// wanting tidy imports in a codebase of side-effect-free modules.
701+
///
702+
/// The escape hatch is the one the language itself provides and the one those
703+
/// tools honour: a bare `import "./x.js"` is a side-effect import, which this
704+
/// organizer already treats as a hard ordering barrier. Code that depends on
705+
/// evaluation order should express it that way.
706+
///
707+
/// Languages whose EVERY import form is order-dependent (C/C++ textual
708+
/// includes) are excluded from this path entirely — see
709+
/// `preserves_side_effect_order`.
692710
fn organize_generic_group(
693711
imps: &[&ImportStatement],
694712
_lang: LangId,

0 commit comments

Comments
 (0)