fix(server): contain oxc fast refresh when React shares the dev server with Vue - #151
Merged
Merged
Conversation
…r with Vue On Rolldown Vite, @vitejs/plugin-react's config() hook turns oxc JSX fast refresh on for the whole shared development server, and @vitejs/plugin-vue transpiles a `<script setup lang="ts">` block itself by spreading that resolved oxc config into its own transformWithOxc call, with no environment - so Vite's per-module refresh guards never run, oxc reads a `use*` call as a hook, and the Vue SSR module throws `$RefreshSig$ is not defined`. The host now appends one serve-only, post-enforced plugin (`taujs:oxc-refresh-containment`) to the dev chain, gated on the exact pair the defect needs - React's managed compiler sharing that server with Vue's renderer - and nothing broader: it overrides exactly one field, `oxc.jsx.refresh`, and reports the triggering pair at boot. React edits fall back to a full reload in that composition only; React + Solid, Vue alone, React beside any other renderer, Solid + Vue and configs with no managed contribution compose exactly as before, and production was never affected (plugin-vue reads `options.devServer`, which is undefined at build). A generic "any managed compiler + any non-managed renderer" gate was reviewed and rejected: it would switch React's refresh off beside an unrelated renderer and blame plugin-vue, and would report Solid as degraded when only React's refresh is affected. A temporary workaround for one named defect gates on the named keys. Upstream: vitejs/vite-plugin-vue#798, fix pending in vitejs/vite-plugin-vue#814. Removal trigger: when a @vitejs/plugin-vue release carries PR #814, raise packages/vue's @vitejs/plugin-vue peer floor to it and delete the plugin, its tests and the warning. Cells: fixtures/renderer-composition/test/dev-react-vue.test.ts (real Vite dev transforms, both declaration orders, a post-start SFC, and a React-alone control that keeps $RefreshReg$); test/dev-product-path.test.ts (real createServer boot in a child process - both SSR routes 200, the warning line, level and meta); test/taujsBuild.test.ts (production pin: no refresh code in either build); packages/server/src/test/OxcRefreshContainment.test.ts (the React + Vue gate incl. React + other, Solid + Vue and React + Solid + Vue rows, config-hook arithmetic, message text).
The product-path cell pinned `[warn] <containment line>` as a plain substring of the child's output. A shell exporting FORCE_COLOR is inherited by the child, picocolors then wraps the level tag in ANSI codes, and the pin missed in both declaration orders. The child now boots with FORCE_COLOR=0 and NO_COLOR=1, and captured output is ANSI-stripped before every assertion, so the pin holds under any terminal. No product change.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Rolldown Vite, @vitejs/plugin-react's config() hook turns oxc JSX fast refresh on for the whole shared development server, and @vitejs/plugin-vue transpiles a
<script setup lang="ts">block itself by spreading that resolved oxc config into its own transformWithOxc call, with no environment - so Vite's per-module refresh guards never run, oxc reads ause*call as a hook, and the Vue SSR module throws$RefreshSig$ is not defined. One serve-only, post-enforced plugin (taujs:oxc-refresh-containment) is appended to the dev chain only when React's managed compiler shares the server with Vue's renderer, and nothing broader. It overrides exactly one field, oxc.jsx.refresh, and reports that pair at boot. React edits fall back to a full reload in that composition only; React + Solid, Vue alone, React beside any other renderer, Solid + Vue and configs with no managed contribution compose exactly as before, and production was never affected (plugin-vue readsoptions.devServer, which is undefined at build).A generic "any managed compiler + any non-managed renderer" gate was reviewed and rejected: it would switch React's refresh off beside an unrelated renderer and blame plugin-vue, and would report Solid as degraded when only React's refresh is affected. A temporary workaround for one named defect gates on the named keys.
Upstream: vitejs/vite-plugin-vue#798, fix pending in vitejs/vite-plugin-vue#814.
Removal trigger: when a @vitejs/plugin-vue release carries PR #814, raise packages/vue's @vitejs/plugin-vue peer floor to it and delete the plugin, its tests and the warning.
Cells: fixtures/renderer-composition/test/dev-react-vue.test.ts (real Vite dev transforms, both declaration orders, a post-start SFC, and a React-alone control that keeps$RefreshReg$ ); test/dev-product-path.test.ts (real createServer boot in a child process - both SSR routes 200, the warning line, level and meta); test/taujsBuild.test.ts (production pin: no refresh code in either build); packages/server/src/test/OxcRefreshContainment.test.ts (the React + Vue gate incl. React + other, Solid + Vue and React + Solid + Vue rows, config-hook arithmetic, message text).