build: add rollup plugin for compile-time ESM/CJS code branching#21715
Conversation
size-limit report 📦
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ddd1e16. Configure here.
|
|
||
| /*! rollup-include-esm-only */ | ||
| return false; | ||
| /*! rollup-include-esm-only-end */ |
There was a problem hiding this comment.
Source isCjs always true
Medium Severity
Replacing runtime detection with two unconditional return statements means any execution of the TypeScript source without the Rollup strip step always hits the first return true. Unit tests and other tooling that import from src (for example Vitest in packages/node-core) no longer mirror ESM behavior for isCjs() or callers like supportsEsmLoaderHooks().
Reviewed by Cursor Bugbot for commit ddd1e16. Configure here.
There was a problem hiding this comment.
Look at the PR. These blocks are removed at build time.
| name: 'remove-esm-cjs-mode-blocks', | ||
| transform(code) { | ||
| if (!code.includes('rollup-include-')) return null; | ||
| return { code: code.replace(removeBlock, '').replace(stripMarkers, ''), map: null }; |
There was a problem hiding this comment.
ESM/CJS strip runs after esbuild
Medium Severity
The new remove-esm-cjs-mode-blocks transform is not pinned before esbuild in mergePlugins, unlike remove-dev-mode-blocks. Format-specific blocks are stripped only after transpilation, so top-level imports used solely in a removed branch can remain in the module graph and ship in the wrong format bundle.
Reviewed by Cursor Bugbot for commit ddd1e16. Configure here.
There was a problem hiding this comment.
we're not using esbuild


This PR adds a rollup plugin that strips comment-annotated blocks at build time, letting us write ESM- and CJS-specific code in a single source file without runtime format checks.
That means this for this file:
The CJS output becomes:
This allows us to include or exclude ESM or CJS specific code without resorting to checking globals at runtime. It changes a runtime check into a build time constant.
There is one caveat. Your code must be valid TypeScript and TypeScript doesn't understand the annotations!