vitejs / vitejs/vite-plugin-react
Babel plugins that read AST `loc` produce wrong positions when running after OXC
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.2k
- Forks
- 269
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 19
Description
Related plugins
Describe the bug
When a Babel plugin runs after @vitejs/plugin-react's OXC transform (using @rolldown/plugin-babel with enforce: 'post' or a custom plugin), the Babel AST loc values refer to the OXC-transformed code, not the original source. Any Babel plugin that reads loc.start.line / loc.start.column to embed source positions in the output will produce incorrect values.
This was not an issue with @vitejs/plugin-react v5 where Babel handled both JSX transform and custom plugins in a single pass — loc always pointed to the original source.
Example
We have a Babel plugin that inserts ComponentName.__debugSourceDefine = { fileName, lineNumber, columnNumber } after each React function component, using the function body's loc:
FunctionDeclaration(path, state) {
const name = path.node.id.name;
const loc = path.node.body.loc; // ← wrong after OXC transform
// inserts: Foo.__debugSourceDefine = { fileName: "...", lineNumber: loc.start.line, ... }
path.insertAfter(createDebugInfo(name, state.file.opts.filename, loc));
}
With v5 (react({ babel: { plugins: [myPlugin] } })), loc.start.line referred to the original .tsx file. With v6, OXC transforms JSX first, changing line numbers. Babel sees the transformed code and its loc values are offset.
The dilemma — no configuration produces correct results
With enforce: 'pre' (default) — Babel runs before OXC:
- ✅
__debugSourceDefineline numbers are correct (Babel sees original source) - ❌ OXC's
jsxDEV()source info is wrong — every JSX element in the app gets shifted line numbers because Babel inserted__debugSourceDefineblocks (4+ lines each) before OXC processed the file
With enforce: 'post' — Babel runs after OXC:
- ❌
__debugSourceDefineline numbers are wrong (Babel ASTlocrefers to OXC-transformed code, not the original source) - ✅ OXC's
jsxDEV()source info is correct (OXC saw the original source)
Reproduction
https://github.com/Artur-/vite-babel-order-repro
Steps to reproduce
npm install
npx vite
Open in browser — the page automatically verifies source positions.
System Info
System:
OS: macOS 26.3.1
CPU: (10) arm64 Apple M1 Max
Binaries:
Node: 24.14.0
npm: 11.9.0
Used Package Manager
npm
Logs
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked vite-babel-order-repro and trace the @vitejs/plugin-react OXC transform alongside the @rolldown/plugin-babel post-processing path. Compare Babel AST loc values and OXC jsxDEV source information under pre and post ordering. Done means custom Babel plugins receive original source positions without shifting OXC's positions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- babel, react, typescript
- Domain
- build-system, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100