Skip to content

fix(externals): trace CJS require() dependencies in production builds#4094

Open
dake3601 wants to merge 1 commit intonitrojs:mainfrom
dake3601:fix/externals-cjs-require-tracing
Open

fix(externals): trace CJS require() dependencies in production builds#4094
dake3601 wants to merge 1 commit intonitrojs:mainfrom
dake3601:fix/externals-cjs-require-tracing

Conversation

@dake3601
Copy link

@dake3601 dake3601 commented Mar 10, 2026

🔗 Linked issue

#4093

❓ Type of change

  • 📖 Documentation (updates to the documentation, readme, or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

The resolveId handler had if (rOpts.custom?.["node-resolve"]) return null; which blanket-skipped CJS require resolutions, preventing packages like bufferutil (in NodeNativePackages) from being externalized and traced even when matched by the include filter.

Fix: check opts.trace before skipping. In dev mode (no tracing), skip as before. In production, resolve directly via tryResolve to avoid recursion and externalize if the resolved path matches the include filter.

Includes test fixtures (nitro-cjs-untrace → @fixture/nitro-native-mock) and a node preset test that verifies CJS require deps are traced to the output node_modules.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@dake3601 dake3601 requested a review from pi0 as a code owner March 10, 2026 21:28
@vercel
Copy link

vercel bot commented Mar 10, 2026

@dake3601 is attempting to deploy a commit to the Nitro Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

📝 Walkthrough

Walkthrough

Modified externals resolution logic to handle nested node-resolve scenarios with conditional tracing-based resolution and CommonJS unwrapping. Re-enabled nitro and static presets in presets export. Added CommonJS untrace utility exposure in test fixtures and a new test case verifying CJS require() dependency tracing.

Changes

Cohort / File(s) Summary
Externals Resolution Logic
src/build/plugins/externals.ts
Enhanced resolve path handling for nested node-resolve scenarios: added trace-mode-dependent resolution behavior, implemented CommonJS unwrapping when filter conditions are met, and differentiated resolution paths based on resolver type.
Presets Configuration
src/presets/_all.gen.ts
Re-enabled nitro and static presets by re-adding imports and spreads; relocated preset spreads from earlier position to end of export array.
Test Fixtures and Coverage
test/fixture/server/routes/modules.ts, test/presets/node.test.ts
Exposed cjsUntrace utility from nitro-cjs-untrace module in test fixtures; added test case verifying CommonJS require() dependencies are properly externalized and traced.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title follows conventional commits format with 'fix' type and descriptive subject clearly related to the changeset.
Description check ✅ Passed The PR description clearly explains the bug being fixed: the resolveId handler was unconditionally skipping CJS require resolutions, preventing packages from being externalized. It describes the solution (checking opts.trace and using tryResolve), mentions the linked issue #4093, and references the test fixtures and node preset test added.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pi0
Copy link
Member

pi0 commented Mar 10, 2026

Please provide a reproduction first 🙏🏼

@dake3601
Copy link
Author

Done! https://github.com/dake3601/nitro-cjs-trace-repro
also added the repro to the github issue.

@giggo1604
Copy link

@dake3601 would that solve #4068?

@dake3601
Copy link
Author

@giggo1604 I don't think so, this just helps trace cjs deps.

@dake3601
Copy link
Author

@pi0 could I please get a review?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants