@youware/vite-plugin-react
Version:
Vite plugin for Youware React applications
205 lines (203 loc) • 6.81 kB
JavaScript
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
};