fix(bundler): barrel optimization defers export * as Name targets#28167
fix(bundler): barrel optimization defers export * as Name targets#28167
export * as Name targets#28167Conversation
When the barrel optimizer's BFS encountered `export * as Name from './file'`, it propagated the alias (e.g. "Toast") as a named export request to the target module. But the target exports individual members (Root, Title), not "Toast", so all its exports were incorrectly deferred as unused. Track `alias_is_star` in `BarrelExportResolution` and propagate as a star import when the export resolves to a namespace re-export, ensuring the target module's exports are all preserved. Closes #28166 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Updated 12:17 AM PT - Mar 17th, 2026
❌ @Jarred-Sumner, your commit 39a6035 has 2 failures in
🧪 To try this PR locally: bunx bun-pr 28167That installs a local version of the PR into your bun-28167 --bun |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughAdds tracking for Changes
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📝 Coding Plan
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/bake/dev/bundle.test.ts`:
- Around line 616-668: The test case named in devTest("barrel optimization:
export * as Name through nested barrels (`#28166`)") only covers the dev server;
add a production/bundler twin that uses the production test helper (e.g.
prodTest or bundleTest matching your test harness) with the identical files
fixture (same nested outer-lib/inner-lib structure and module files) and the
same assertion (expecting "result: ROOT TITLE") to verify the production build
path also preserves the namespace re-exports; place it next to the existing
devTest and use the same test body (build/serve the bundle and verify output) so
the regression is guarded in both dev and prod.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4b3ebaf8-bc8b-4a38-aa75-0206ef2ea571
📒 Files selected for processing (2)
src/bundler/barrel_imports.zigtest/bake/dev/bundle.test.ts
|
Found 5 issues this PR may fix:
🤖 Generated with Claude Code |
|
Can you come up with a test that fails in the regular |
There was a problem hiding this comment.
LGTM — focused fix correctly propagating namespace re-exports as star imports through barrel optimization.
Extended reasoning...
Overview
This PR fixes a bug in the barrel optimization where export * as Name from "..." targets were incorrectly deferred. Two files are changed: src/bundler/barrel_imports.zig (the fix) and test/bake/dev/bundle.test.ts (regression test). The fix adds an alias_is_star boolean to BarrelExportResolution, then uses it in two places: (1) early-return in applyBarrelOptimizationImpl to skip barrel deferral entirely when a namespace re-export is requested, and (2) propagate as a star import in scheduleBarrelDeferredImports BFS so the target module keeps all its exports.
Security risks
No security implications — this is bundler optimization logic that affects which submodules are lazily loaded during dev server builds. No auth, crypto, or permission-related code is touched.
Level of scrutiny
Moderate scrutiny is appropriate. The barrel optimization is non-trivial logic, but this change is small (adding one boolean field and two conditional checks), follows existing patterns (alias_is_star is already used elsewhere in the codebase at LinkerContext.zig and ImportScanner.zig), and the logic is straightforward: namespace re-exports need all exports from the target, not just the alias name.
Other factors
The regression test is well-structured, mirroring a real-world Chakra UI / Ark UI package structure with nested barrels and namespace re-exports. The PR description notes all existing barrel optimization tests continue to pass. No outstanding reviewer comments exist.
|
FYI @Jarred-Sumner it is not dev-only; more info in the related issue #28166 |
Add a production bundler twin of the dev server test to guard against regressions in both code paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/bundler/bundler_barrel.test.ts`:
- Around line 1597-1648: Add a runtime execution check to the
"barrel/ExportStarAsNameNestedBarrels" test: enable the test runner's run option
(or set run: true) so the generated bundle executes, then assert the process
stdout contains the expected runtime output "ROOT TITLE" produced by /entry.js's
console.log (in addition to the existing onAfterBundle static checks for
ToastRoot/ToastTitle).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2d419d05-afc5-4d32-af11-5d1f25664dd0
📒 Files selected for processing (1)
test/bundler/bundler_barrel.test.ts
Jarred-Sumner
left a comment
There was a problem hiding this comment.
Neither of the tests fail on main. No proof this PR fixes the issue.
|
@robobun Read the comments and adopt this PR |
Verification —
|
robobun
left a comment
There was a problem hiding this comment.
Gate 3 (Test proof): FAIL
Both new tests pass on the baked main binary (d50ab984, v1.3.11-debug), which means the tests don't reproduce the bug.
Root cause: The test fixture uses export * from './components/index.js' in outer-lib/index.js. This marks components/index.js as is_export_star_target = true (barrel_imports.zig:68), causing the barrel optimization to be skipped entirely on that module. The buggy code path — where alias_is_star propagation is incorrect — is never exercised.
Required changes:
- Test fixture: Change outer-lib/index.js from
export * from './components/index.js'to named re-exports likeexport { Toast } from './components/index.js'(or add more barrel layers), socomponents/index.jsis NOT an export star target and the barrel optimization actually runs on it. - Production test: Add
run: { stdout: "ROOT TITLE" }to theitBundledtest for runtime verification. - Comment fix: Reword barrel_imports.zig:104 comment — says "Mark all non-internal records as needed" but the mechanism is an early return that skips the unused-marking loop.
Verify after fixing: the new test must FAIL on the baked binary (USE_SYSTEM_BUN=1 build/debug/bun-debug test ...) and PASS on the rebuilt PR binary.
Change outer-lib/index.js from `export * from` to `export { Toast } from`
so that components/index.js is not marked as is_export_star_target, allowing
barrel optimization to actually run on it. Add runtime verification to the
production bundler test. Reword comment in barrel_imports.zig for accuracy.
https://claude.ai/code/session_01EnB4DmogoHrPTjPA617dJd
…l bug The previous test fixture imported the namespace directly from the barrel entry, which allowed Phase 1 seeding in scheduleBarrelDeferredImports to correctly mark the target as needing all exports. The bug only manifests when a DIFFERENT package (codec) imports the namespace from the barrel (utils), causing the barrel optimization to incorrectly defer the namespace target's sub-modules. New fixture: entry → codec (uses typed.toDataView) → utils barrel (export * as typed). On the buggy code path, barrel optimization for the utils barrel defers typed/index.js, so toDataView is never defined in the bundle output (ReferenceError at runtime). Test proof: USE_SYSTEM_BUN=1 bun test → FAILS (ReferenceError: toDataView is not defined) bun bd test → PASSES (2 8)
Summary
export * as Name from '...'targets in the dev serverexport * as Toast from './namespace'), it propagated the alias ("Toast") as a named export request to the target module, but the target exports individual members (Root, Title), not "Toast" — so all exports were deferred as unusedalias_is_starinBarrelExportResolutionand propagate as a star import when the resolution is a namespace re-exportTest plan
barrel optimization: export * as Name through nested barrels (#28166)mirroring the Chakra UI / Ark UI package structurebarrel/ExportStarAsNameNestedBarrelswith identical fixturebundle.test.tstests passCloses #28166
🤖 Generated with Claude Code