next.js
b785969e - Order loader tree imports by tree depth (#93537)

Commit
1 day ago
Order loader tree imports by tree depth (#93537) ### What? Reorder the imports emitted by the app-page loader-tree builder so that they are grouped by their depth in the loader tree (shallow segments first, deep segments last) instead of the somewhat arbitrary order produced by recursive walking. ### Why? The loader tree is built by walking the app router tree recursively, and each segment contributes a few `require(...)` declarations (layout, error, loading, page, metadata, ...) to a shared list of imports that is later concatenated into the generated entry module. The order of that list is what ends up in the bundle, and walking the tree recursively interleaves segments at different depths in a way that depends on traversal order rather than on the structure of the route. For chunking and readability we want a more predictable order: *outer (shallower) layouts/segments before inner (deeper) ones*, with imports inside the same depth keeping their original relative order. This gives downstream chunking a more useful signal. ### How? In `crates/next-core/src/base_loader_tree.rs`: - `BaseLoaderTreeBuilder::imports` is now `Vec<(u32, RcStr)>` instead of `Vec<RcStr>`. The `u32` is a sort key (the depth at which the import was produced). - `create_module_tuple_code` takes a new `position: u32` argument and stores it alongside the generated `require` line. In `crates/next-core/src/app_page_loader_tree.rs`: - `walk_tree` takes a new `depth: u32` argument. The initial call from `build()` passes `0`. - `depth` is threaded through `write_modules_entry`, `write_metadata`, `write_metadata_items`, `write_metadata_item`, and `write_static_metadata_item`, so the three other places that push directly into `self.base.imports` (dynamic image metadata, static metadata items, and their alt-text companions) also tag their entries with the current depth. - When recursing into `parallel_routes`, depth is incremented only for the `"children"` slot. Named parallel routes (e.g. `@modal`) are sibling slots of the same segment and therefore stay at the same depth. - In `AppPageLoaderTreeBuilder::build`, the collected `(depth, import)` pairs are stable-sorted by depth (`sort_by_key`, which is stable in Rust, preserving the original relative order within each depth) and then stripped back to `Vec<RcStr>` before being placed on `AppPageLoaderTreeModule.imports`. The public type of `AppPageLoaderTreeModule.imports` (`Vec<RcStr>`) is unchanged, so consumers in `crates/next-core/src/next_app/app_page_entry.rs` need no adjustments. Co-authored-by: v-work-app[bot] <262237222+v-work-app[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com>
Author
Parents
Loading