UNPKG

react-vfor

Version:

`ReactVFor` is a Vite/React plugin that allows you to use Vue-like `v-for` syntax in React components.

60 lines (59 loc) 2.27 kB
import * as e from "@babel/types"; import E from "@babel/traverse"; import { parse as g } from "@babel/parser"; import b from "@babel/generator"; function S(o) { const [t, l] = o.split(" in ").map((a) => a.trim()); let u = t, i = null; return t.includes(",") && ([u, i] = t.split(",").map((a) => a.trim())), { items: l, item: u, index: i }; } function C() { return { name: "vite-plugin-vfor-react", enforce: "pre", transform(o, t) { if (!t.endsWith(".jsx") && !t.endsWith(".tsx")) return null; const l = g(o, { sourceType: "module", plugins: ["jsx", "typescript"] }); return E(l, { JSXElement(i) { const n = i.node.openingElement.attributes.find( (s) => e.isJSXAttribute(s) && e.isJSXIdentifier(s.name, { name: "v-for" }) ); if (!n || !n.value) return; let m = null; if (e.isStringLiteral(n.value) ? m = n.value.value : e.isJSXExpressionContainer(n.value) && e.isStringLiteral(n.value.expression) && (m = n.value.expression.value), !m) return; const { items: p, item: c, index: f } = S(m); try { const s = e.objectExpression( i.node.openingElement.attributes.filter((r) => !(e.isJSXAttribute(r) && e.isJSXIdentifier(r.name, { name: "v-for" }))).map((r) => e.objectProperty( e.identifier(r.name.name), e.isJSXExpressionContainer(r.value) ? r.value.expression : e.stringLiteral(r.value.value) )) ), d = e.callExpression( e.memberExpression(e.identifier("React"), e.identifier("createElement")), [ e.identifier(i.node.openingElement.name.name), s, ...i.node.children ] ), x = e.arrowFunctionExpression( [e.identifier(c), e.identifier(f || "index")], d ), v = e.jsxExpressionContainer( e.callExpression( e.memberExpression(e.identifier(p), e.identifier("map")), [x] ) ); i.replaceWith(v); } catch { return; } } }), { code: b(l, {}, o).code, map: null }; } }; } export { C as default };