fix(cjs): expose live exports at CommonJS cycle re-entry - #10282
proggeramlug wants to merge 1 commit into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (11)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe CJS wrapper now publishes the full module record during partial initialization, so cyclic readers observe current ChangesCommonJS cycle export handling
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant ESM
participant CJSWrapper
participant ModuleRegistry
participant CyclicCJS
ESM->>CJSWrapper: import token.cjs
CJSWrapper->>ModuleRegistry: publish module record
CJSWrapper->>CyclicCJS: require consumer.cjs
CyclicCJS->>ModuleRegistry: read current module.exports
ModuleRegistry-->>CyclicCJS: getter-backed exports
CyclicCJS-->>ESM: live values and cycle results
Merge Risk: ⚪ Minimal · up to The CommonJS cycle handling change is covered by targeted regression fixtures for export replacement, getters, warnings, and live bindings. No merge-blocking risk is identified. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 47.62% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 21 functions across 10 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
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 |
…ia the CLI The bun condition unit test flips a process-wide flag that every other resolver test reads, so it could race them under the parallel harness. Run its body in a child test process and assert the child actually ran. Add an integration test that compiles one program with --platform node and --platform bun, covering the flag's wiring into the resolver: bun above node, perry above bun, a package without a bun entry, a missing bun file falling back to node, and a #imports conditional. Key both changelog fragments to their PRs (#10282, #10283).
|
Landed via merge train #10291 (v0.5.1573). All source commits preserve authorship; merged main matches the validated train exactly. |
Summary
An esbuild CommonJS module assigns
module.exports = __toCommonJS(target)before requiring its cyclic peer. The owner record contains the getters, but the path registry retained the initial empty exports object. The peer kept that stale object and an indirect call later threwTypeError: value is not a function. Export-name extraction was already working; #10156's live named getters did not address this replaced object.Changes
exportswhen require re-enters the module.in, without invoking getters.Related issue
Fixes #10178. Refs #10107. Related to #10153 / #10156.
Test plan
All builds, tests, and measurements ran through
./remote.shon Linux, with two build jobs, matching isolated compiler/static archives, and--no-auto-optimizefor native probes.Baseline production sources were built from
1cd160f3d, with no compiler/runtime edits. Both snapshots usedcargo build --release -j2 -p perry -p perry-runtime-static -p perry-stdlib-static; compiler and archives were copied together before test builds could replace them.42, then52; zero early getter reads, two actual reads; empty stderr@ai-sdk/gateway@3.0.104entry,@vercel/oidc@3.2.0getVercelDataDircircular-dependency warninggateway: function, empty stderrvalue is not a function.../com.vercel.cli/auth.jsonpath; empty stderrgetVercelToken()through the opposite cycle entryANYwarning; symbol and intersection result already correctThe installed, unmodified gateway entry compiled 125 native modules; the isolated source-copy/call probe compiled 280 native modules plus 57 pruned forwarding modules. Node 26.5.1 passed the same probes with empty stderr. Only the lane-owned OIDC copy received diagnostic globals exposing the private function and owner record; installed packages were untouched. Test auth data stayed under the lane directory.
Commands and results:
cargo test --release -j2 -p perry --bin perry cjs_wrap: 121 passed.cargo test --release -j2 -p perry --test source_graph_export_regressions: 61 passed, including fix(cjs): preserve live getter re-export bindings #10156's sibling cases, all three new controls, and unrelated source-graph regressions.CARGO_PROFILE_DEV_DEBUG=0 CARGO_PROFILE_TEST_DEBUG=0 CARGO_INCREMENTAL=0 RUST_TEST_THREADS=1 cargo test -j2 -p perry-runtime: 3,931 passed, 1 failed, 4 ignored. Debug assertions remained enabled; debug info was disabled to bound disk use.native_stack::tests::stack_top_respects_custom_thread_stack_sizes(bound must belong to this worker). It also fails alone. Its source is unchanged from1cd160f3d; the same Linux failure was reported in fix(cjs): preserve live getter re-export bindings #10156. This PR changes only comments in runtime Rust code.cargo fmt --all -- --check,scripts/check_file_size.sh,scripts/check_test_registration.py, andscripts/check_node_version_consistency.py --list: passed.Require-heavy benchmark
111.55 ms before → 111.36 ms after (−0.17%, within measurement noise). No measured runtime regression.
The workload has 96 getter-free CommonJS leaves (
module.exports = { value: i }) and one CJS driver. For 1,000 rounds the driver sums each literalrequire("./mN.cjs").value; ESM imports the driver and prints the asserted checksum4560000. Every fresh process performs module publication and 96,000 cached requires.Both native executables used the same source, release-profile compiler/archive package set,
--no-cache --no-auto-optimize, two module jobs and one LLVM worker per module. Measurements used 51 randomly ordered before/after pairs (seed 10178), three warmups per executable, and CPU affinity 15 on the shared Linux host. Compilation is excluded; process startup and module initialization are included. No getter-specific work was added to publication; the existing registry receives the record instead of reading its initial exports property.The full OpenCode build and terminal interface were not run, as requested. CI is informational for this lane; this PR does not wait for unrelated main failures.
Checklist
fix:convention; read CONTRIBUTING.md.Summary by CodeRabbit
Bug Fixes
Tests
Documentation