vitejs / vitejs/vite-plugin-react

Babel plugins that read AST `loc` produce wrong positions when running after OXC

Open
#1,193 12 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

documentation plugin: react
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:

  • __debugSourceDefine line 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 __debugSourceDefine blocks (4+ lines each) before OXC processed the file

With enforce: 'post' — Babel runs after OXC:

  • __debugSourceDefine line numbers are wrong (Babel AST loc refers 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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.