UNPKG

@youware/vite-plugin-react

Version:

Vite plugin for Youware React applications

205 lines (203 loc) 6.81 kB
import g, { resolve as d, dirname as E } from "path"; import { createRequire as b } from "module"; import { parse as h } from "@babel/parser"; import * as e from "@babel/types"; import { existsSync as S, mkdirSync as w, copyFileSync as j } from "fs"; const v = { sourceType: "module", allowImportExportEverywhere: !0, ranges: !0, tokens: !0, plugins: [ // 基础语法支持 "jsx", "typescript" ] }; function x(t, n) { const i = g.relative(process.cwd(), n), r = t.loc, o = r ? `${r.start.line}:${r.start.column}` : "unknown", s = `${i}@${o}`; return Buffer.from(s, "utf8").toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); } const y = b(import.meta.url), A = y("@babel/traverse").default, I = y("@babel/generator").default; function _(t) { const n = t.children; if (n.length !== 1) return !1; const i = n[0]; return e.isJSXText(i) ? i.value.trim().length > 0 : !1; } function J(t) { return !e.isJSXIdentifier(t.openingElement.name) || t.openingElement.name.name.toLowerCase() !== "img" ? !1 : !!t.openingElement.attributes.find( (r) => e.isJSXAttribute(r) && e.isJSXIdentifier(r.name) && r.name.name === "src" && e.isStringLiteral(r.value) ); } function X(t) { const n = t.openingElement.attributes.find( (i) => e.isJSXAttribute(i) && e.isJSXIdentifier(i.name) && i.name.name === "style" ); if (!n) return !0; if (e.isJSXAttribute(n) && e.isJSXExpressionContainer(n.value)) { const i = n.value.expression; return e.isObjectExpression(i) ? i.properties.every((r) => { if (e.isObjectProperty(r)) { const o = e.isIdentifier(r.key) || e.isStringLiteral(r.key), s = e.isStringLiteral(r.value) || e.isNumericLiteral(r.value); return o && s; } return !1; }) : !1; } return !1; } function C(t) { return !e.isJSXIdentifier(t.openingElement.name) || t.openingElement.name.name.toLowerCase() !== "a" ? !1 : !!t.openingElement.attributes.find( (r) => e.isJSXAttribute(r) && e.isJSXIdentifier(r.name) && r.name.name === "href" && e.isStringLiteral(r.value) ); } function L(t) { return t.children.some((n) => e.isJSXText(n) && n.value.trim().length > 0); } function P(t, n) { t.children = t.children.map((i) => { if (e.isJSXText(i) && i.value.trim()) { const o = x(i, n); return e.jsxElement( e.jsxOpeningElement( e.jsxIdentifier("span"), [ e.jsxAttribute(e.jsxIdentifier("data-yw"), e.stringLiteral(o)), e.jsxAttribute(e.jsxIdentifier("data-yw-t"), null), e.jsxAttribute(e.jsxIdentifier("data-yw-auto"), null) // 标记为自动包装 ], !1 ), e.jsxClosingElement(e.jsxIdentifier("span")), [e.jsxText(i.value)], !1 ); } return i; }); } function T(t, n, i) { const r = t.openingElement.attributes; r.push(e.jsxAttribute(e.jsxIdentifier("data-yw"), e.stringLiteral(n))), _(t) ? r.push(e.jsxAttribute(e.jsxIdentifier("data-yw-t"), null)) : L(t) && P(t, i), J(t) && r.push(e.jsxAttribute(e.jsxIdentifier("data-yw-i"), null)), X(t) && r.push(e.jsxAttribute(e.jsxIdentifier("data-yw-s"), null)), C(t) && r.push(e.jsxAttribute(e.jsxIdentifier("data-yw-l"), null)); } function O(t, n) { try { const i = h(t, v); let r = !1; if (A(i, { JSXElement(o) { const s = o.node; if (s.openingElement.attributes.some( (u) => e.isJSXAttribute(u) && e.isJSXIdentifier(u.name) && u.name.name === "data-yw-auto" )) return; const c = x(s, n); T(s, c, n), r = !0; } }), r) { const o = I(i, { retainLines: !0, compact: !1 }); return { code: o.code, map: o.map }; } return null; } catch (i) { return console.warn(`Error processing JSX elements in file ${n}:`, i), null; } } const R = (t, n) => { const i = g.basename(t); return n.some((r) => i === r); }, $ = () => `; // Visual Editor HMR Bridge - Auto-injected if (import.meta.hot) { import.meta.hot.on('vite:beforeUpdate', (payload) => { if (window.__visualEditorCommunication) { window.__visualEditorCommunication.handleViteBeforeUpdate(payload); } }); import.meta.hot.on('vite:afterUpdate', (payload) => { if (window.__visualEditorCommunication) { window.__visualEditorCommunication.handleViteAfterUpdate(payload); } }); } `, p = (t) => { let n = t.replace(/\*\*/g, "___DOUBLESTAR___"); return n = n.replace(/[.+^${}()|[\]\\]/g, "\\$&"), n = n.replace(/\*/g, "[^/]*"), n = n.replace(/___DOUBLESTAR___/g, ".*"), new RegExp(`^${n}$`); }, k = (t, n, i) => i.some((s) => p(s).test(t)) ? !1 : n.some((s) => p(s).test(t)); function B(t = {}) { const { include: n = ["**/*.tsx", "**/*.jsx"], exclude: i = ["node_modules/**", "**/dist/**"], entryFiles: r = ["main.tsx", "main.ts", "main.jsx", "main.js"] } = t; return { name: "visual-editor-plugin", enforce: "pre", transform(o, s) { const l = R(s, r), c = s.endsWith(".tsx") || s.endsWith(".jsx"); if (!l && !c || !(l || k(s, n, i))) return null; try { let a = o, m = null; if (!l || c) { const f = O(o, s); f && (a = f.code, m = f.map); } return l && (a += $()), a !== o ? { code: a, map: m } : null; } catch (a) { return console.warn(`Error processing file ${s}:`, a), null; } } }; } function V() { return { name: "youware-manifest", buildStart() { try { const t = d(process.cwd(), "yw_manifest.json"), n = d(process.cwd(), "public", "yw_manifest.json"); S(t) && (w(E(n), { recursive: !0 }), j(t, n)); } catch (t) { console.error("❌ [Youware Manifest] Copy yw_manifest.json failed:", t); } } }; } function D(t = {}) { const { enableReactVisualEditor: n = !!process.env.YOUWARE_SANDBOX, enableCopyManifest: i = !0 } = t, r = []; return i && r.push(V()), n && r.push(B(t.reactVisualEditorOptions)), { name: "youware-vite-plugin", enforce: "pre", // Combine buildStart hooks buildStart(o) { for (const s of r) s.buildStart && typeof s.buildStart == "function" && s.buildStart.call(this, o); }, // Combine transform hooks transform(o, s) { let l = o, c = null; for (const u of r) if (u.transform && typeof u.transform == "function") { const a = u.transform.call(this, l, s); a && (typeof a == "string" ? l = a : a && typeof a == "object" && "code" in a && a.code && (l = a.code, "map" in a && (c = a.map))); } return l !== o ? { code: l, map: c } : null; } }; } export { D as youwareVitePlugin };