26 lines
1.1 KiB
TypeScript
26 lines
1.1 KiB
TypeScript
// DevVibeCoder Design-mode inspector: a Babel visitor that stamps every JSX
|
|||
|
|
// element with `data-vc-loc="src/App.tsx:41:7"` (path relative to this
|
||
|
|
// folder, 1-based line and column). vite.config.ts hands it to
|
||
|
|
// @vitejs/plugin-react only for `vite dev`, so a build carries no stamps.
|
||
|
|
// The Design pane maps a click in the preview back to that source position.
|
||
|
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||
|
|
import path from 'node:path';
|
||
|
|
|
||
|
|
export const vcBabelLoc = () => ({
|
||
|
|
name: 'vc-loc',
|
||
|
|
visitor: {
|
||
|
|
JSXOpeningElement(p: any, state: any) {
|
||
|
|
const loc = p.node.loc;
|
||
|
|
const file: string | undefined = state.filename || state.file?.opts?.filename;
|
||
|
|
if (!loc || !file) return;
|
||
|
|
if (p.node.attributes.some((a: any) => a.type === 'JSXAttribute' && a.name?.name === 'data-vc-loc')) return;
|
||
|
|
const rel = path.relative(state.cwd || process.cwd(), file).split(path.sep).join('/');
|
||
|
|
p.node.attributes.push({
|
||
|
|
type: 'JSXAttribute',
|
||
|
|
name: { type: 'JSXIdentifier', name: 'data-vc-loc' },
|
||
|
|
value: { type: 'StringLiteral', value: `${rel}:${loc.start.line}:${loc.start.column + 1}` },
|
||
|
|
});
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|