Skip to content

Conversation

hi-ogawa
Copy link

@hi-ogawa hi-ogawa commented Jul 8, 2025

Description

@vitejs/plugin-react has this check isJSX || code.includes(jsxImportRuntime) || code.includes(jsxImportDevRuntime) for fast refresh. Since the default filter allows non-jsx file, this additional check is necessary on oxc refresh transform side.

I added a test case in vitejs/vite-plugin-react#547 and confirmed it's fixed by pkg.pr.new

Copy link

pkg-pr-new bot commented Jul 8, 2025

Open in StackBlitz

npm i https://pkg.pr.new/vitejs/rolldown-vite/@vitejs/plugin-legacy@318
npm i https://pkg.pr.new/vitejs/rolldown-vite@318

commit: 898632a

hi-ogawa added a commit to vitejs/vite-plugin-react that referenced this pull request Jul 8, 2025
@hi-ogawa hi-ogawa marked this pull request as ready for review July 8, 2025 00:53
hi-ogawa added a commit to vitejs/vite-plugin-react that referenced this pull request Jul 8, 2025
@hi-ogawa hi-ogawa requested a review from sapphi-red July 8, 2025 01:59
@sapphi-red
Copy link
Member

Hmm, this code feels too specific to the plugin to include in the core and feels hard to keep the condition in sync between the core and the plugin.
But if we add an option to configure this behavior, then it would be difficult to make it harder to keep the native transform plugin performant.

Do you have any alternative ideas? Or maybe this trade-off is just inevitable...

@hi-ogawa
Copy link
Author

hi-ogawa commented Jul 8, 2025

Is the coupling between core and plugin so much of concern? For example, I was assuming rolldown-vite's oxc.jsx.refresh: true should be only used by @vitejs/plugin-react-oxc and thus these are expected to be coupled. I don' think code syncing is an real problem here or I might be missing something.

@hi-ogawa
Copy link
Author

hi-ogawa commented Jul 8, 2025

OK, I think technically applying refresh transform to non-jsx is not an issue by itself. Probably @vitejs/plugin-react needed this logic for perf, but I don't think this behavior is something we need to preserve in the future. Other bundlers likely don't have this specific behavior as they normally don't care about jsx in non-jsx file. (I just tested Parcel and it injected $RefreshReg$ everywhere).

The original issue is about $RefreshReg$/$RefreshSig$ not being defined in worker, so we should solve that aspect eventually, but for now, I think having this fix on rolldown-vite js side seems worth it.

@sapphi-red
Copy link
Member

I wouldn't say this is a major problem. It's just something that would be nice to avoid.

The issues I see with this approach are:

  • Changing this condition would require a change in Vite core. Technically, this means plugin-react would need to update its peer dependency to keep things in sync. That said, this could be ignored if the breakage isn't significant.
  • It makes using oxc.refresh: true difficult for other plugins. While oxc.jsx.refresh is somewhat of an internal option, it's still a public one and could be used by other plugins (e.g., maybe by React Router in the future?). It would be better to keep it generic if possible.
  • The react-specific code lives in the core. It is harder to find the specific code as you normally assume the code lives in the plugin-react repo. It would be hard anyways as native related code will live in rolldown repo though.

I don’t have a better alternative at the moment, so I’ll go ahead and merge this unless you have any other suggestions.

@hi-ogawa
Copy link
Author

hi-ogawa commented Jul 8, 2025

I'm interested in trying out no-op $RefreshReg/Sig$ as fallback for worker, but I think landing this as compatibility fix is good. Intentionally changing the behavior from @vitejs/plugin-react can be done a separate step.

@sapphi-red sapphi-red merged commit de24b6b into vitejs:rolldown-vite Jul 9, 2025
18 checks passed
@hi-ogawa hi-ogawa deleted the fix-disable-oxc-refresh-non-jsx branch July 9, 2025 03:29
shulaoda added a commit to rolldown/rolldown that referenced this pull request Jul 17, 2025
github-merge-queue bot pushed a commit to rolldown/rolldown that referenced this pull request Jul 17, 2025
shulaoda pushed a commit to rolldown/rolldown that referenced this pull request Jul 17, 2025
## [1.0.0-beta.28] - 2025-07-17

### 🚀 Features

- rolldown: oxc v0.77.2 (#5328) by @Boshen
- hmr: add `module` and `exports` parameters to CJS initializer
functions (#5322) by @hyf0
- rolldown_plugin_transform: align with `vitejs/rolldown-vite#318`
(#5318) by @shulaoda
- rolldown_plugin_transform: align with `vitejs/rolldown-vite#315`
(#5315) by @shulaoda
- hmr: automatically disable treeshaking in hmr (#5311) by @hyf0
- hmr: use `trait HmrAstBuilder` to unify ast construction (#5310) by
@hyf0
- rolldown_plugin_chunk_import_map: basic implementation (#5307) by
@shulaoda
- add `watch.onInvalidate` (#5239) by @situ2001
- rolldown_plugin_chunk_import_map: implement initial `render_chunk`
logic (#5306) by @shulaoda
- rolldown: oxc v0.77.1 (#5304) by @Boshen
- js: expose `experimental.incrementalBuild` option (#5300) by
@IWANABETHATGUY
- js: support `experimental.onDemandWrapping` option (#5299) by
@IWANABETHATGUY
- support on demand wrapping for entry chunk (#5291) by @IWANABETHATGUY
- rolldown_plugin_chunk_import_map: initialize (#5289) by @shulaoda
- show owner module id for "canonical name not found for" errors (#5288)
by @sapphi-red

### 🐛 Bug Fixes

- only transform VarDeclaration when enable `keepNames` (#5323) by
@IWANABETHATGUY
- keepNames with special Ifstmt (#5320) by @IWANABETHATGUY
- incremental watch panic when adding dynamic import (#5309) by
@IWANABETHATGUY
- make leaf module wrapping optimization opt-in (#5305) by
@IWANABETHATGUY
- `keepNames` should consider exportNamed function declaration (#5298)
by @IWANABETHATGUY
- undefined `process.versions` for browser build (#5295) by @sxzz
- sanitizeFileName: entry name should be sanitized (#5283) by @shulaoda
- minify-internal-exports: ensure minifying internal exports stably
(#5281) by @hyf0
- keep legal and annotation comments for `minify: 'dce-only'` (#5280) by
@sapphi-red
- unstable chunk generation when `preserveEntrySignatures: false` is
used (#5274) by @IWANABETHATGUY

### 🚜 Refactor

- pass the while CodegenOptions to `EcmaCompiler::minify` (#5279) by
@sapphi-red
- avoid iterate `canonical_exports` twice (#5276) by @IWANABETHATGUY

### 📚 Documentation

- pluginutils: add README file (#5262) by @TheAlexLichter

### ⚡ Performance

- inline function expression when rewriting `name` property with
`keepNames` enabled (#5321) by @IWANABETHATGUY
- rolldown_sourcemap: cache source id -> source text mapping (#5285) by
@Boshen
- rolldown_sourcemap: disable rayon (#5284) by @Boshen

### 🧪 Testing

- rust: prevent meaningless snapshot change from bumping oxc runtime
versions (#5312) by @hyf0

### ⚙️ Miscellaneous Tasks

- upgrade to NAPI-RS 3.0 stable (#5324) by @Brooooooklyn
- infra: add onlyBuiltDependencies (#5287) by @situ2001
- improve the order of import keys in the exports field (#5314) by @btea
- deps: update dependency rolldown-plugin-dts to v0.13.14 (#5293) by
@renovate[bot]
- deps: lock file maintenance rust crates (#5267) by @renovate[bot]
- deps: lock file maintenance npm packages (#5266) by @renovate[bot]
- deps: update github-actions (#5265) by @renovate[bot]

### ❤️ New Contributors

* @situ2001 made their first contribution in
[#5287](#5287)

Co-authored-by: IWANABETHATGUY <17974631+IWANABETHATGUY@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Switching to plugin-react-oxc triggers "$RefreshReg$ is not defined" errors
2 participants