Skip to content

Commit 90362fc

Browse files
committed
fix(devtools-vite): preserve valid syntax when removing devtools JSX
1 parent 92f69d0 commit 90362fc

2 files changed

Lines changed: 98 additions & 3 deletions

File tree

packages/devtools-vite/src/remove-devtools.test.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,94 @@ export function DevtoolsProvider() {
601601
null
602602
)
603603
}
604+
`),
605+
)
606+
})
607+
608+
test('replaces removed devtools expressions with null', () => {
609+
const output = removeEmptySpace(
610+
removeDevtools(
611+
`
612+
import { TanStackDevtools } from '@tanstack/react-devtools'
613+
614+
function functionCall(value: unknown) {
615+
return value
616+
}
617+
618+
export function DevtoolsProvider() {
619+
const devtools1 = <TanStackDevtools />
620+
const devtools2 = functionCall(<TanStackDevtools />)
621+
const devtools3 = true ? <TanStackDevtools /> : <>fallback</>
622+
const devtools4 = {
623+
devtools: <TanStackDevtools />
624+
}
625+
const devtools5 = (<div>
626+
{<TanStackDevtools plugins={[]} />}
627+
</div>)
628+
return { devtools1, devtools2, devtools3, devtools4, devtools5 }
629+
}
630+
`,
631+
'test.tsx',
632+
)!.code,
633+
)
634+
635+
expect(output).toBe(
636+
removeEmptySpace(`
637+
function functionCall(value: unknown) {
638+
return value
639+
}
640+
641+
export function DevtoolsProvider() {
642+
const devtools1 = null
643+
const devtools2 = functionCall(null)
644+
const devtools3 = true ? null : <>fallback</>
645+
const devtools4 = {
646+
devtools: null
647+
}
648+
const devtools5 = (<div>
649+
{null}
650+
</div>)
651+
return { devtools1, devtools2, devtools3, devtools4, devtools5 }
652+
}
653+
`),
654+
)
655+
})
656+
657+
test('removes devtools jsx children entirely', () => {
658+
const output = removeEmptySpace(
659+
removeDevtools(
660+
`
661+
import { TanStackDevtools } from '@tanstack/react-devtools'
662+
663+
export function DevtoolsProvider() {
664+
return (
665+
<>
666+
<div>
667+
<div>before</div>
668+
<TanStackDevtools />
669+
<div>after</div>
670+
</div>
671+
<TanStackDevtools />
672+
</>
673+
)
674+
}
675+
`,
676+
'test.tsx',
677+
)!.code,
678+
)
679+
680+
expect(output).toBe(
681+
removeEmptySpace(`
682+
export function DevtoolsProvider() {
683+
return (
684+
<>
685+
<div>
686+
<div>before</div>
687+
<div>after</div>
688+
</div>
689+
</>
690+
)
691+
}
604692
`),
605693
)
606694
})

packages/devtools-vite/src/remove-devtools.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,17 @@ export function removeDevtools(code: string, id: string) {
130130

131131
let end = node.end
132132
if (code[end] === '\n') end++
133-
if (parentNode?.type === 'ParenthesizedExpression') {
134-
s.overwrite(node.start, end, 'null')
135-
} else {
133+
/**
134+
* Devtools nodes can be removed safely when nested in JSX.
135+
* In all other contexts, replace them with `null` to avoid leaving invalid syntax.
136+
*/
137+
if (
138+
parentNode?.type === 'JSXElement' ||
139+
parentNode?.type === 'JSXFragment'
140+
) {
136141
s.remove(node.start, end)
142+
} else {
143+
s.overwrite(node.start, end, 'null')
137144
}
138145
})
139146

0 commit comments

Comments
 (0)