Files
infinite-canvas/plugins/canvas/registry/build.mjs
T

59 lines
2.9 KiB
JavaScript

// 官方插件集中构建:一次进程构建所有官方插件 + 生成清单,产物进 dist/(已 gitignore)。
// 官方插件目录本身不各自安装依赖:统一从本目录 node_modules 解析 SDK(nodePaths)。
// CI(publish-plugins.yml)把 dist/ 强推到 plugins-dist 分支,前端经 jsDelivr 远程拉取。
// 本地自测:`npm install && npm run build`,再把 VITE_PLUGIN_REGISTRY_URL 指向本地 dist。
import { build } from "esbuild";
import { mkdir, rm, writeFile } from "node:fs/promises";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const root = dirname(fileURLToPath(import.meta.url));
const outDir = join(root, "dist");
const nodeModules = join(root, "node_modules");
// 官方插件元数据(单一真源:清单从这里生成)。新增官方插件在此登记即可。
const OFFICIAL = [
{ id: "markdown", dir: "markdown", name: "Markdown 节点", version: "1.0.0", description: "在画布中编辑与渲染 Markdown", icon: "📝" },
{ id: "svg", dir: "svg", name: "SVG 节点", version: "1.0.0", description: "编辑与渲染 SVG,可接收上游文本节点的 SVG 源码", icon: "🔷" },
{ id: "html", dir: "html", name: "HTML 节点", version: "1.0.0", description: "沙箱 iframe 渲染 HTML,支持 {{input}} 注入上游文本", icon: "🌐" },
{ id: "panorama", dir: "panorama", name: "3D 全景节点", version: "1.0.0", description: "查看 360° 等距柱状全景图,可从上游图片节点取图", icon: "🧭" },
{ id: "sticky-note", dir: "sticky-note", name: "便利贴节点", version: "1.0.0", description: "可换色、可编辑、可衍生文本节点的便利贴", icon: "📌" },
];
await rm(outDir, { recursive: true, force: true });
await mkdir(outDir, { recursive: true });
for (const plugin of OFFICIAL) {
await build({
entryPoints: [join(root, "..", plugin.dir, "src", "index.tsx")],
outfile: join(outDir, `${plugin.id}.js`),
bundle: true,
format: "esm",
platform: "browser",
target: "es2020",
// automatic JSX → SDK 的 jsx-runtime(内部用宿主 React),react external
jsx: "automatic",
jsxImportSource: "@infinite-canvas/plugin-sdk",
loader: { ".ts": "ts", ".tsx": "tsx", ".css": "text" },
external: ["react", "react-dom"],
minify: true,
nodePaths: [nodeModules],
});
console.log(`built ${plugin.id}.js`);
}
const manifest = {
// 清单结构版本;entry 为相对本清单的 bundle 文件名,由前端解析成绝对 URL
version: 1,
plugins: OFFICIAL.map((plugin) => ({
id: plugin.id,
name: plugin.name,
version: plugin.version,
description: plugin.description,
icon: plugin.icon,
entry: `${plugin.id}.js`,
})),
};
await writeFile(join(outDir, "official-plugins.json"), JSON.stringify(manifest, null, 4) + "\n");
console.log(`wrote official-plugins.json (${OFFICIAL.length} plugins) → dist/`);