mini-figma-code-connect 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -9
- package/README.md +14 -3
- package/dist/build.mjs +228 -0
- package/dist/figma-mapping.mjs +618 -0
- package/dist/generate-registry.mjs +86 -0
- package/dist/install-skill.mjs +91 -0
- package/dist/main/code.d.ts +1 -0
- package/dist/main/code.js +388 -0
- package/dist/main/handle.d.ts +55 -0
- package/dist/main/handle.js +167 -0
- package/dist/main/mapping-table.generated.json +1 -0
- package/dist/main/messages.d.ts +71 -0
- package/dist/main/messages.js +1 -0
- package/dist/main/schema.d.ts +9 -0
- package/dist/main/schema.js +39 -0
- package/dist/main/validate.d.ts +16 -0
- package/dist/main/validate.js +40 -0
- package/dist/runtime/define.d.ts +3 -0
- package/dist/runtime/define.js +4 -0
- package/{src/runtime/index.ts → dist/runtime/index.d.ts} +3 -14
- package/dist/runtime/index.js +9 -0
- package/dist/runtime/registry.d.ts +5 -0
- package/dist/runtime/registry.generated.d.ts +3 -0
- package/dist/runtime/registry.generated.js +1 -0
- package/{src/runtime/registry.ts → dist/runtime/registry.js} +7 -8
- package/dist/runtime/render.d.ts +6 -0
- package/dist/runtime/render.js +27 -0
- package/dist/runtime/tagged.d.ts +6 -0
- package/dist/runtime/tagged.js +45 -0
- package/dist/runtime/types.d.ts +107 -0
- package/dist/runtime/types.js +7 -0
- package/dist/scaffold-manifest.mjs +87 -0
- package/dist/scaffold-plugin.mjs +468 -0
- package/dist/ui/ui.d.ts +84 -0
- package/dist/ui/ui.js +190 -0
- package/package.json +23 -18
- package/scripts/build-plugin.mjs +0 -132
- package/scripts/copy-mapping-table.mjs +0 -19
- package/scripts/figma-mapping/ai-generate.mjs +0 -102
- package/scripts/figma-mapping/index.mjs +0 -250
- package/scripts/figma-mapping/lib.mjs +0 -112
- package/scripts/figma-mapping/registry.mjs +0 -12
- package/scripts/figma-mapping/scaffold.mjs +0 -153
- package/scripts/generate-registry.mjs +0 -94
- package/scripts/install-skill.mjs +0 -79
- package/scripts/is-cli-entrypoint.mjs +0 -21
- package/scripts/scaffold-manifest.mjs +0 -84
- package/scripts/scaffold-plugin.mjs +0 -172
- package/src/dev/demo.ts +0 -207
- package/src/dev/export.ts +0 -28
- package/src/main/code.ts +0 -422
- package/src/main/handle.ts +0 -207
- package/src/main/messages.ts +0 -49
- package/src/main/schema.ts +0 -45
- package/src/main/validate.ts +0 -49
- package/src/runtime/define.ts +0 -6
- package/src/runtime/render.ts +0 -26
- package/src/runtime/tagged.ts +0 -46
- package/src/runtime/types.ts +0 -86
- package/src/ui/ui.ts +0 -271
- /package/{src → dist}/ui/ui.html +0 -0
package/LICENSE
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
Proprietary License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2026 elaine.ma
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
5
|
+
All rights reserved.
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
This software and associated documentation files (the "Software") are the
|
|
8
|
+
proprietary property of the copyright holder.
|
|
9
|
+
|
|
10
|
+
Permission is granted to install and use the Software via the published npm
|
|
11
|
+
package for your own projects, subject to the npm package terms.
|
|
12
|
+
|
|
13
|
+
You may not copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software source code, except as allowed by applicable law or
|
|
15
|
+
with prior written permission from the copyright holder.
|
|
14
16
|
|
|
15
17
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
18
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
@@ -19,3 +21,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
19
21
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
22
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
23
|
SOFTWARE.
|
|
24
|
+
|
|
25
|
+
Issues and feedback: https://github.com/elainema0215/mini-figma-code-connect/issues
|
package/README.md
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
**Local Code Connect for Figma Professional** — 无 Org / Enterprise 也能做确定性的 `f(instance) → snippet`。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> 源码未开源。npm 仅分发编译产物(`dist/`)。问题与反馈请到 [GitHub Issues](https://github.com/elainema0215/mini-figma-code-connect/issues)。
|
|
6
6
|
|
|
7
|
+
面向 Pro 档团队的轻量替代引擎:Figma 插件 + 将设计组件映射到消费方真实代码库的工作流。
|
|
7
8
|
官方 Code Connect 与 Builder.io Design System Intelligence 均要求 Organization / Enterprise 订阅;团队当前为 Professional,相关 MCP 绑定工具不可用。本引擎在本地实现等价的「组件绑定 + 属性映射」:映射进消费方仓库、执行在 Figma 插件,不依赖云端 publish。插件沙箱无法读写本地代码,因此映射生成在沙箱外(agent / CLI)完成,再经构建打包进插件。
|
|
8
9
|
|
|
9
10
|
---
|
|
@@ -56,7 +57,7 @@ pnpm add -D mini-figma-code-connect
|
|
|
56
57
|
# 或:npm install -D mini-figma-code-connect
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
包尚未安装时,后续 CLI 命令均不存在。
|
|
60
61
|
|
|
61
62
|
#### 2. 执行一次性脚手架
|
|
62
63
|
|
|
@@ -107,7 +108,7 @@ pnpm exec mini-code-connect-scaffold-manifest --id <manifest-id>
|
|
|
107
108
|
|
|
108
109
|
无 agent 可用时,`pnpm exec figma-mapping <schema.json>` 提供本地正则打分作为兜底方案(同样支持批量 schema 数组与 `--ai` 模式),判断准确度低于 agent 现场读取代码,但落盘规则保持一致。
|
|
109
110
|
|
|
110
|
-
|
|
111
|
+
## 常见问题
|
|
111
112
|
|
|
112
113
|
1. **Q:** 命令找不到 / `EACCES: spawn …`
|
|
113
114
|
**A:** 先在已安装依赖的目录执行 `pnpm install`,刷新 `node_modules/.bin`。若仍报错,多半是引擎包脚本权限问题,反馈给引擎仓库。
|
|
@@ -120,3 +121,13 @@ pnpm exec mini-code-connect-scaffold-manifest --id <manifest-id>
|
|
|
120
121
|
|
|
121
122
|
4. **Q:** 改了 manifest,Figma 没变化?
|
|
122
123
|
**A:** `editorType` / `capabilities` 在导入时缓存。需在 Figma 里删掉该开发插件后重新导入。`figma-plugin-dist/` 下的 `code.js` / `ui.html` 每次运行都会重读,改构建产物不必重导。
|
|
124
|
+
|
|
125
|
+
5. **Q:** 导入/运行插件时报 `EPERM: operation not permitted, open '…/figma-plugin-dist/code.js'`,或提示 *Unable to load code* / *loading the plugin environment*?
|
|
126
|
+
**A:** 这通常不是包本身坏了,而是 **macOS 隐私权限拦住了 Figma 读取本地文件**(项目在 `Desktop` / `Documents` 下时很常见)。处理:
|
|
127
|
+
1. **系统设置 → 隐私与安全性 → 文件与文件夹**(必要时再开「完全磁盘访问权限」),给 **Figma** 勾选桌面 / 文稿等对应目录。
|
|
128
|
+
2. 完全退出并重启 Figma。
|
|
129
|
+
3. 在 Development 里删掉旧插件后,重新 **Import plugin from manifest…**。
|
|
130
|
+
也可把消费方仓库挪出受保护目录(例如 `~/Projects/`)再导入。
|
|
131
|
+
|
|
132
|
+
6. **Q:** `pnpm exec mini-code-connect-scaffold-plugin --id …` 报 `generate-registry: glob 里没有 *: "--id"`?
|
|
133
|
+
**A:** `0.1.3` 打包把多个 CLI 打进同一文件,导致 `generate-registry` 误跑并把 `--id` 当成 glob。请升级到 **`>=0.1.4`** 后重试。
|
package/dist/build.mjs
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// scripts/build-plugin.mjs
|
|
4
|
+
import * as esbuild from "esbuild";
|
|
5
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
6
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
7
|
+
import path4 from "node:path";
|
|
8
|
+
|
|
9
|
+
// scripts/is-cli-entrypoint.mjs
|
|
10
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
function isCliEntrypoint(importMetaUrl, entryName) {
|
|
14
|
+
if (!process.argv[1]) return false;
|
|
15
|
+
try {
|
|
16
|
+
const argvPath = realpathSync(process.argv[1]);
|
|
17
|
+
const metaPath = realpathSync(fileURLToPath(importMetaUrl));
|
|
18
|
+
if (argvPath !== metaPath) return false;
|
|
19
|
+
if (entryName) {
|
|
20
|
+
return path.basename(argvPath).includes(entryName);
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
} catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function findPackageRoot(importMetaUrl) {
|
|
28
|
+
let dir = path.dirname(fileURLToPath(importMetaUrl));
|
|
29
|
+
while (true) {
|
|
30
|
+
const pkgPath = path.join(dir, "package.json");
|
|
31
|
+
if (existsSync(pkgPath)) {
|
|
32
|
+
try {
|
|
33
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
34
|
+
if (pkg.name === "mini-figma-code-connect") return dir;
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const parent = path.dirname(dir);
|
|
39
|
+
if (parent === dir) {
|
|
40
|
+
throw new Error("[mini-figma-code-connect] \u627E\u4E0D\u5230\u5305\u6839\u76EE\u5F55\uFF08package.json\uFF09");
|
|
41
|
+
}
|
|
42
|
+
dir = parent;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// scripts/generate-registry.mjs
|
|
47
|
+
import fs from "node:fs";
|
|
48
|
+
import path2 from "node:path";
|
|
49
|
+
function parseGlob(glob) {
|
|
50
|
+
const starIdx = glob.indexOf("*");
|
|
51
|
+
if (starIdx === -1) throw new Error(`generate-registry: glob \u91CC\u6CA1\u6709 *\uFF1A"${glob}"`);
|
|
52
|
+
const dir = glob.slice(0, starIdx).replace(/\/$/, "");
|
|
53
|
+
const recursive = glob.includes("**");
|
|
54
|
+
return { dir, recursive };
|
|
55
|
+
}
|
|
56
|
+
function findFigmaFiles(dir, recursive) {
|
|
57
|
+
const results = [];
|
|
58
|
+
function walk(d) {
|
|
59
|
+
if (!fs.existsSync(d)) return;
|
|
60
|
+
for (const entry of fs.readdirSync(d, { withFileTypes: true })) {
|
|
61
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
|
|
62
|
+
const full = path2.join(d, entry.name);
|
|
63
|
+
if (entry.isDirectory()) {
|
|
64
|
+
if (recursive) walk(full);
|
|
65
|
+
} else if (entry.name.endsWith(".figma.ts")) {
|
|
66
|
+
results.push(full);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
walk(dir);
|
|
71
|
+
return results.sort();
|
|
72
|
+
}
|
|
73
|
+
function identifierFor(filePath, index) {
|
|
74
|
+
const base = path2.basename(filePath).replace(/\.figma\.ts$/, "").replace(/[^a-zA-Z0-9]/g, "");
|
|
75
|
+
const safe = base && /^[a-zA-Z_]/.test(base) ? base : `M${base}`;
|
|
76
|
+
return `${safe || "Mapping"}_${index}`;
|
|
77
|
+
}
|
|
78
|
+
function generateRegistry({ cwd, mappingsGlob, outFile, typesImport = "./types" }) {
|
|
79
|
+
const { dir, recursive } = parseGlob(mappingsGlob);
|
|
80
|
+
const files = findFigmaFiles(path2.resolve(cwd, dir), recursive);
|
|
81
|
+
const outDir = path2.dirname(outFile);
|
|
82
|
+
const imports = files.map((f, i) => {
|
|
83
|
+
const id = identifierFor(f, i);
|
|
84
|
+
let rel = path2.relative(outDir, f).replace(/\.ts$/, "");
|
|
85
|
+
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
86
|
+
rel = rel.split(path2.sep).join("/");
|
|
87
|
+
return { id, importPath: rel };
|
|
88
|
+
});
|
|
89
|
+
const typeLine = typesImport == null ? "" : `import type { Template } from '${typesImport}'
|
|
90
|
+
`;
|
|
91
|
+
const templatesAnn = typesImport == null ? "" : ": Template[]";
|
|
92
|
+
const body = `// \u81EA\u52A8\u751F\u6210\uFF0C\u4E0D\u8981\u624B\u6539 \u2014\u2014 \u7531 scripts/generate-registry.mjs \u626B .figma.ts \u751F\u6210\uFF0C\u6BCF\u6B21 build \u524D\u91CD\u8DD1
|
|
93
|
+
` + typeLine + imports.map((i) => `import ${i.id} from '${i.importPath}'`).join("\n") + (imports.length ? "\n\n" : "\n") + `export const templates${templatesAnn} = [${imports.map((i) => i.id).join(", ")}]
|
|
94
|
+
`;
|
|
95
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
96
|
+
fs.writeFileSync(outFile, body);
|
|
97
|
+
return { count: files.length, files };
|
|
98
|
+
}
|
|
99
|
+
if (isCliEntrypoint(import.meta.url, "generate-registry")) {
|
|
100
|
+
const [, , mappingsGlob, outFile] = process.argv;
|
|
101
|
+
if (!mappingsGlob || !outFile) {
|
|
102
|
+
console.error("\u7528\u6CD5: node scripts/generate-registry.mjs <mappingsGlob> <outFile>");
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
const result = generateRegistry({ cwd: process.cwd(), mappingsGlob, outFile: path2.resolve(outFile) });
|
|
106
|
+
console.log(`[generate-registry] \u5199\u5165 ${result.count} \u6761\u6620\u5C04\u5230 ${outFile}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// scripts/copy-mapping-table.mjs
|
|
110
|
+
import fs2 from "node:fs";
|
|
111
|
+
import path3 from "node:path";
|
|
112
|
+
function copyMappingTable({ cwd, mappingTablePath, outFile }) {
|
|
113
|
+
const src = path3.resolve(cwd, mappingTablePath);
|
|
114
|
+
const content = fs2.existsSync(src) ? fs2.readFileSync(src, "utf8") : "[]\n";
|
|
115
|
+
fs2.mkdirSync(path3.dirname(outFile), { recursive: true });
|
|
116
|
+
fs2.writeFileSync(outFile, content);
|
|
117
|
+
return { found: fs2.existsSync(src) };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// scripts/build-plugin.mjs
|
|
121
|
+
var PACKAGE_ROOT = findPackageRoot(import.meta.url);
|
|
122
|
+
function resolvePluginEntries(packageRoot) {
|
|
123
|
+
const main = path4.join(packageRoot, "dist/main/code.js");
|
|
124
|
+
const ui = path4.join(packageRoot, "dist/ui/ui.js");
|
|
125
|
+
const html = path4.join(packageRoot, "dist/ui/ui.html");
|
|
126
|
+
for (const file of [main, ui, html]) {
|
|
127
|
+
if (!existsSync2(file)) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`[build-plugin] \u7F3A\u5C11 ${file}\u3002\u8BF7\u5148\u5728\u5F15\u64CE\u5305\u76EE\u5F55\u6267\u884C npm run build\uFF08\u53EA\u4F7F\u7528 dist/\uFF0C\u4E0D\u56DE\u9000 src/\uFF09\u3002`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return { main, ui, html };
|
|
134
|
+
}
|
|
135
|
+
function consumerGeneratedPlugin(genDir) {
|
|
136
|
+
const registryFile = path4.join(genDir, "registry.generated.ts");
|
|
137
|
+
const mappingTableFile = path4.join(genDir, "mapping-table.generated.json");
|
|
138
|
+
return {
|
|
139
|
+
name: "consumer-generated",
|
|
140
|
+
setup(build2) {
|
|
141
|
+
build2.onResolve({ filter: /(?:^|[\\/])registry\.generated(?:\.(?:ts|js))?$/ }, () => ({
|
|
142
|
+
path: registryFile
|
|
143
|
+
}));
|
|
144
|
+
build2.onResolve({ filter: /(?:^|[\\/])mapping-table\.generated\.json$/ }, () => ({
|
|
145
|
+
path: mappingTableFile
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
async function buildPlugin({
|
|
151
|
+
cwd,
|
|
152
|
+
mappingsGlob,
|
|
153
|
+
mappingTablePath = "figma-mapping-table.json",
|
|
154
|
+
outDir = "dist",
|
|
155
|
+
watch = false
|
|
156
|
+
}) {
|
|
157
|
+
const { main: mainEntry, ui: uiEntry, html: uiHtml } = resolvePluginEntries(PACKAGE_ROOT);
|
|
158
|
+
const absOutDir = path4.resolve(cwd, outDir);
|
|
159
|
+
const genDir = path4.join(absOutDir, ".generated");
|
|
160
|
+
const registryOut = path4.join(genDir, "registry.generated.ts");
|
|
161
|
+
const mappingTableOut = path4.join(genDir, "mapping-table.generated.json");
|
|
162
|
+
const { count } = generateRegistry({
|
|
163
|
+
cwd,
|
|
164
|
+
mappingsGlob,
|
|
165
|
+
outFile: registryOut,
|
|
166
|
+
typesImport: null
|
|
167
|
+
});
|
|
168
|
+
console.log(`[build-plugin] \u626B\u5230 ${count} \u6761\u6620\u5C04\uFF08${mappingsGlob}\uFF09`);
|
|
169
|
+
const { found } = copyMappingTable({ cwd, mappingTablePath, outFile: mappingTableOut });
|
|
170
|
+
if (!found) console.log(`[build-plugin] \u6CA1\u627E\u5230 ${mappingTablePath}\uFF0C\u4E0B\u8F7D\u6309\u94AE\u4F1A\u7ED9\u7A7A\u6570\u7EC4`);
|
|
171
|
+
const generatedPlugin = consumerGeneratedPlugin(genDir);
|
|
172
|
+
const inlineUi = {
|
|
173
|
+
name: "inline-ui",
|
|
174
|
+
setup(build2) {
|
|
175
|
+
build2.onEnd(async (res) => {
|
|
176
|
+
if (res.errors.length) return;
|
|
177
|
+
const js = res.outputFiles ? res.outputFiles[0].text : await readFile(path4.join(absOutDir, ".ui.tmp.js"), "utf8");
|
|
178
|
+
const html = await readFile(uiHtml, "utf8");
|
|
179
|
+
await mkdir(absOutDir, { recursive: true });
|
|
180
|
+
await writeFile(path4.join(absOutDir, "ui.html"), html.replace("/*__UI_JS__*/", () => js));
|
|
181
|
+
console.log(`[inline-ui] ${path4.join(outDir, "ui.html")} \u5DF2\u66F4\u65B0`);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const codeOpts = {
|
|
186
|
+
entryPoints: [mainEntry],
|
|
187
|
+
bundle: true,
|
|
188
|
+
format: "iife",
|
|
189
|
+
target: "es2020",
|
|
190
|
+
outfile: path4.join(absOutDir, "code.js"),
|
|
191
|
+
logLevel: "info",
|
|
192
|
+
plugins: [generatedPlugin]
|
|
193
|
+
};
|
|
194
|
+
const uiOpts = {
|
|
195
|
+
entryPoints: [uiEntry],
|
|
196
|
+
bundle: true,
|
|
197
|
+
format: "iife",
|
|
198
|
+
target: "es2020",
|
|
199
|
+
outfile: path4.join(absOutDir, ".ui.tmp.js"),
|
|
200
|
+
logLevel: "warning",
|
|
201
|
+
plugins: [inlineUi, generatedPlugin]
|
|
202
|
+
};
|
|
203
|
+
if (watch) {
|
|
204
|
+
const a = await esbuild.context(codeOpts);
|
|
205
|
+
const b = await esbuild.context(uiOpts);
|
|
206
|
+
await Promise.all([a.watch(), b.watch()]);
|
|
207
|
+
console.log("[build-plugin] watching...");
|
|
208
|
+
return { watching: true };
|
|
209
|
+
}
|
|
210
|
+
await esbuild.build(codeOpts);
|
|
211
|
+
await esbuild.build(uiOpts);
|
|
212
|
+
return { watching: false };
|
|
213
|
+
}
|
|
214
|
+
if (isCliEntrypoint(import.meta.url, "build")) {
|
|
215
|
+
const args = process.argv.slice(2);
|
|
216
|
+
const watch = args.includes("--watch");
|
|
217
|
+
const outIdx = args.indexOf("--out");
|
|
218
|
+
const outDir = outIdx !== -1 ? args[outIdx + 1] : "dist";
|
|
219
|
+
const mappingsGlob = args.find((a, i) => !a.startsWith("--") && args[i - 1] !== "--out");
|
|
220
|
+
if (!mappingsGlob) {
|
|
221
|
+
console.error("\u7528\u6CD5: node scripts/build-plugin.mjs <mappingsGlob> [--out dist] [--watch]");
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
await buildPlugin({ cwd: process.cwd(), mappingsGlob, outDir, watch });
|
|
225
|
+
}
|
|
226
|
+
export {
|
|
227
|
+
buildPlugin
|
|
228
|
+
};
|