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>