bake: give each DevServer module its own renamer scope - #39375
Open
undeemed wants to merge 1 commit into
Open
Conversation
DevServer prints every module inside its own closure, but rename_symbols_in_chunk still pushed every file's top-level symbols into the single chunk-level NumberScope. Two files declaring the same top-level name collided at the chunk root, so the second one came out as `App2` and `App.name` returned "App2". For Format::InternalBakeDev, each non-runtime file now gets its own NumberScope parented to the chunk root, seeded from its live parts' declared symbols. Name lookup still walks the parent chain, so nothing can collide with a name already taken at the chunk root. Fixes oven-sh#18017
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan includes up to 10 reviews per rolling hour; 9 remain after this review. WalkthroughChangesDev-server symbol scopes
Possibly related PRs
Suggested reviewers: Merge Risk: ⚪ Minimal · up to This localized DevServer renaming change is supported by targeted tests and lint checks, with no actionable merge-blocking risk remaining. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes #18017. In DevServer, two modules that both declare a top-level
Appended up with the second one renamed toApp2, soApp.namecame back as"App2". The same thing happens tomodule, which is why the screenshot on the issue shows a numberedmodule.DevServer prints every module inside its own closure -
generateCodeForFileInChunkJS.rs:72-174wraps each file in(hmr, module, exports) => { ... }- butrename_symbols_in_chunkstill pushed every file's top-level symbols into the single chunk-levelNumberScopethroughadd_top_level_declared_symbols. Two files declaring the same name therefore collided at the chunk root, even though neither name is actually at the chunk's top level.For
Format::InternalBakeDev, each file now gets its ownNumberScopeparented to the chunk root. Its live parts' top-level symbols and their nested scopes are numbered inside it. Nothing can collide with a name already taken at the chunk root, becauseNumberScopelookup walks the parent chain.The branch predicate is deliberately the same one the codegen uses (
is_dev_server && !source_index.is_runtime()). The runtime file stays on the chunk-root path because it prints unwrapped, and it is only in the chunk at all underbun build --format=internal_bake_dev. Everything else is untouched: the new code sits behindoutput_format == Format::InternalBakeDev, so production bundling runs exactly the path it ran before.Two things worth a second look in review:
part.declared_symbols, not from the module scope the wayWrapKind::Cjsdoes it. React Fast Refresh temp refs (var _s = $RefreshSig$()) are registered on the enclosing function scope but print at the file's top level, andpart.declared_symbolsis the only thing that carries them to the renamer. Seeding from the module scope instead drops them and two components in one file both end up as_s.test/bake/dev/react-spa.test.tscatches that.NumberRenamerexist becauseNumberScope::{parent, name_counts}andassign_namearepub(crate)tobun_js_printer, so the bundler cannot build a child scope or write into one itself.One existing test needed updating.
test/bake/dev/server-sourcemap.test.tsasserted the buggy name,doSomething2, and the column that went with it. It now assertsdoSomething. The frame still resolves to the same file and the same line, only the column moves, 28 to 31, because the identifier is a character shorter so the frame's generated column lands in the neighbouring mapping segment. Inexport function doSomething() {, 28 is the(and 31 is the{.This is the
// TODO: instead of running a renamer per chunk, run it per fileatgenerateChunksInParallel.rs:61that the issue points at, scoped to DevServer only.How did you verify your code works?
Debug build (
bun bd) on Linux x64 throughout. Steps 3 and 5 ran with the branch rebased ontoc3995e43d5; steps 2 and 4 ran two commits earlier at8326d1bd39, and the two commits in between are a WebKit bump and a CI allowlist revert that touch neither the bundler nortest/bake.1. Reproduced it first on the released bun. Two files that each export
function App:Same command on this branch:
2. The new test fails without the fix. It runs those two modules through a real DevServer client and asserts
App.name + " " + Other.name === "App App". With the test applied butsrc/reverted to main:3. Targeted runs with the fix applied.
bundler_loader.test.tsis in there for itsinternal_bake_dev lazy exportsblock, andreact-spa.test.tsfor React Fast Refresh. Both are 0 fail on main too (58 pass and 6 pass respectively).4. Full
test/bake/suite, main vs this branch.The two failure sets are identical, name for name. All 10 are
production > ...indev-and-prod.test.ts, and every one of them is the 5000 ms default test timeout on a debug build on this machine, not an assertion.5. Lints.