Problem
In a Vite React/TSX app, Impeccable live mode wrote invalid TSX during variant wrapping/acceptance and crashed the dev server.
The selected element was a React-rendered aside in a component with multiple similar aside branches.
Observed behavior
There were three related failures:
live-wrap.mjs initially inserted live wrapper JSX in a way that produced invalid TSX.
Vite error:
[plugin:vite:oxc] Transform failed with 1 error:
[PARSE_ERROR] Error: Expected `,` or `)` but found `Identifier`
src/components/images/lightbox-dialog.tsx:279:12
- After accept/carbonize, Impeccable wrote malformed JSX style output.
Example malformed output shape:
<style data-impeccable-css="...">{`
{`
@scope ([data-impeccable-variant="1"]) {
...
`}
`}</style>
Vite error:
[plugin:vite:oxc] Transform failed with 1 error:
[PARSE_ERROR] Error: Expected `}` but found `@`
src/components/images/lightbox-dialog.tsx:371:7
- The preview looked wrong before accept: variants mostly reused the original component body, with only outer
aside classes changing. One variant became vertically squished, but the internal layout did not meaningfully change.
Expected behavior
For React/TSX source files:
- Live wrapper insertion should produce valid JSX.
- Variant preview should replace the selected element with each full variant body, not just alter the outer wrapper class.
- Accept/carbonize should leave valid TSX.
- If Impeccable cannot safely target the source node, it should fail with a clear fallback error instead of mutating the wrong branch.
Likely root causes
1. JSX wrapper insertion is not always syntactically safe
When inserting comments plus wrapper elements inside return (...), JSX needs a valid single parent, usually a fragment:
return (
<>
{/* impeccable-variants-start ... */}
<div data-impeccable-variants="...">...</div>
{/* impeccable-variants-end ... */}
</>
)
Raw sibling comments/elements in the wrong position can break TSX parsing.
2. Carbonize serializes scoped CSS incorrectly for TSX
The accepted CSS should serialize as one valid JSX expression:
<style data-impeccable-css="...">{`
@scope (...) {
...
}
`}</style>
Instead, it produced nested template literal fragments, causing Vite/OXC parse errors.
3. Source matching is too weak for repeated component branches
The component had multiple aside elements with similar classes. Class/tag matching selected the wrong branch at least once. In React components, repeated class patterns are common, so first-match wrapping is unsafe.
Suggested fix
- Add React/TSX-specific wrapper insertion that always preserves JSX syntax.
- Fix
live-accept.mjs carbonize serialization for JSX/TSX style tags.
- Improve source matching for repeated JSX branches, or fail safely when the source node is ambiguous.
- Add a Vite React fixture that covers:
- wrapping a selected JSX element,
- previewing three variants,
- accepting a variant,
- carbonizing scoped CSS,
- repeated sibling/branch elements with similar classes.
Repro shape
- Use a Vite React app with a
.tsx component.
- Render multiple similar
aside branches in one component.
- Select one
aside with Impeccable live mode.
- Generate variants with scoped CSS.
- Accept a variant.
Expected: valid TSX and correct accepted variant.
Actual: invalid TSX is written and Vite crashes with parse errors.
Problem
In a Vite React/TSX app, Impeccable live mode wrote invalid TSX during variant wrapping/acceptance and crashed the dev server.
The selected element was a React-rendered
asidein a component with multiple similarasidebranches.Observed behavior
There were three related failures:
live-wrap.mjsinitially inserted live wrapper JSX in a way that produced invalid TSX.Vite error:
Example malformed output shape:
Vite error:
asideclasses changing. One variant became vertically squished, but the internal layout did not meaningfully change.Expected behavior
For React/TSX source files:
Likely root causes
1. JSX wrapper insertion is not always syntactically safe
When inserting comments plus wrapper elements inside
return (...), JSX needs a valid single parent, usually a fragment:Raw sibling comments/elements in the wrong position can break TSX parsing.
2. Carbonize serializes scoped CSS incorrectly for TSX
The accepted CSS should serialize as one valid JSX expression:
Instead, it produced nested template literal fragments, causing Vite/OXC parse errors.
3. Source matching is too weak for repeated component branches
The component had multiple
asideelements with similar classes. Class/tag matching selected the wrong branch at least once. In React components, repeated class patterns are common, so first-match wrapping is unsafe.Suggested fix
live-accept.mjscarbonize serialization for JSX/TSX style tags.Repro shape
.tsxcomponent.asidebranches in one component.asidewith Impeccable live mode.Expected: valid TSX and correct accepted variant.
Actual: invalid TSX is written and Vite crashes with parse errors.