befly-tpl 3.2.2 → 3.2.3
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/README.md +240 -14
- package/package.json +21 -3
- package/addon-loader.example.ts +0 -99
- package/bun.lock +0 -140
- package/logs/2025-08-22.0.log +0 -197
- package/logs/2025-08-23.0.log +0 -151
- package/logs/2025-08-24.0.log +0 -296
- package/logs/2025-08-25.0.log +0 -162
- package/logs/2025-08-26.0.log +0 -19
- package/logs/2025-08-27.0.log +0 -63
- package/logs/2025-08-28.0.log +0 -286
- package/logs/2025-08-30.0.log +0 -1
- package/logs/2025-09-01.0.log +0 -296
- package/logs/2025-09-02.0.log +0 -298
- package/logs/2025-10-11.0.log +0 -2718
- package/logs/2025-10-12.0.log +0 -4374
- package/logs/2025-10-13.0.log +0 -759
- package/logs/2025-10-14.0.log +0 -2350
- package/logs/2025-10-15.0.log +0 -2386
- package/logs/2025-10-16.0.log +0 -2807
- package/logs/2025-10-17.0.log +0 -1143
- package/logs/2025-10-18.0.log +0 -1292
- package/logs/2025-10-19.0.log +0 -1752
- package/logs/2025-10-20.0.log +0 -722
- package/logs/2025-10-21.0.log +0 -1075
- package/logs/2025-10-23.0.log +0 -3291
- package/logs/2025-10-24.0.log +0 -2341
- package/logs/2025-10-25.0.log +0 -1367
- package/logs/debug.0.log +0 -25174
- package/temp/addon-route-prefix-migration.md +0 -400
- package/temp/api-route-conflict-analysis.md +0 -441
- package/temp/interactive-cli-guide.md +0 -199
- package/temp/missing-apis-fix.md +0 -362
- package/temp/remove-status-field.md +0 -239
- package/temp/roleid-to-rolecode-optimization.md +0 -321
- package/temp/status-to-state-migration-complete.md +0 -176
- package/temp/syncMenu-guide.md +0 -235
- package/temp/test-admin-menus-cache.ts +0 -125
- package/temp/test-admin-menus.ts +0 -110
- package/temp/test-interactive-cli.ps1 +0 -14
|
@@ -1,441 +0,0 @@
|
|
|
1
|
-
# API 路由冲突分析报告
|
|
2
|
-
|
|
3
|
-
**日期**:2025-10-19
|
|
4
|
-
**分析人**:AI Assistant
|
|
5
|
-
|
|
6
|
-
## 📋 问题描述
|
|
7
|
-
|
|
8
|
-
用户提出的问题:
|
|
9
|
-
|
|
10
|
-
> 如果 admin 组件中有 list 接口,tpl 项目的 apis 目录下有 admin/list.ts,这2个接口路径会不会重复,会不会冲突?
|
|
11
|
-
|
|
12
|
-
具体场景:
|
|
13
|
-
|
|
14
|
-
1. **Addon API**:`packages/tpl/addons/admin/apis/list.ts`
|
|
15
|
-
2. **项目 API**:`packages/tpl/apis/admin/list.ts`
|
|
16
|
-
|
|
17
|
-
## 🔍 深度分析
|
|
18
|
-
|
|
19
|
-
### 1. 路由生成规则
|
|
20
|
-
|
|
21
|
-
根据 `packages/core/lifecycle/loader.ts` 的代码分析(Line 493-497):
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
// 构建路由:addon 接口添加前缀 /api/{addonName}/{apiPath}
|
|
25
|
-
if (isAddon) {
|
|
26
|
-
api.route = `${api.method.toUpperCase()}/api/${addonName}/${apiPath}`;
|
|
27
|
-
} else {
|
|
28
|
-
api.route = `${api.method.toUpperCase()}/api/${apiPath}`;
|
|
29
|
-
}
|
|
30
|
-
apiRoutes.set(api.route, api);
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**关键发现**:
|
|
34
|
-
|
|
35
|
-
- **Addon API** 会添加 addon 名称前缀:`/api/{addonName}/{apiPath}`
|
|
36
|
-
- **项目 API** 只有基础前缀:`/api/{apiPath}`
|
|
37
|
-
- 路由以 `Map` 结构存储,key 为 `${METHOD}${PATH}`
|
|
38
|
-
|
|
39
|
-
### 2. 实际路径映射
|
|
40
|
-
|
|
41
|
-
#### 场景 A:Addon 中的 list.ts
|
|
42
|
-
|
|
43
|
-
**文件位置**:
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
packages/tpl/addons/admin/apis/list.ts
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**生成的路由**:
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
POST/api/admin/list
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**计算过程**:
|
|
56
|
-
|
|
57
|
-
- `isAddon = true`
|
|
58
|
-
- `addonName = 'admin'`
|
|
59
|
-
- `apiPath = 'list'`(相对于 apis 目录的路径)
|
|
60
|
-
- `method = 'POST'`(默认)
|
|
61
|
-
- 结果:`POST/api/admin/list`
|
|
62
|
-
|
|
63
|
-
#### 场景 B:项目中的 admin/list.ts
|
|
64
|
-
|
|
65
|
-
**文件位置**:
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
packages/tpl/apis/admin/list.ts
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**生成的路由**:
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
POST/api/admin/list
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**计算过程**:
|
|
78
|
-
|
|
79
|
-
- `isAddon = false`
|
|
80
|
-
- `apiPath = 'admin/list'`(相对于 apis 目录的路径)
|
|
81
|
-
- `method = 'POST'`(默认)
|
|
82
|
-
- 结果:`POST/api/admin/list`
|
|
83
|
-
|
|
84
|
-
### 3. 冲突分析结论
|
|
85
|
-
|
|
86
|
-
**⚠️ 会发生路由冲突!**
|
|
87
|
-
|
|
88
|
-
两个接口生成的路由完全相同:
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
POST/api/admin/list
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## 🚨 冲突后果
|
|
95
|
-
|
|
96
|
-
### 1. Map 覆盖问题
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
apiRoutes.set(api.route, api);
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
- `apiRoutes` 是 `Map` 结构
|
|
103
|
-
- 如果 key 相同,后加载的会**覆盖**先加载的
|
|
104
|
-
- **最终只有一个接口生效**
|
|
105
|
-
|
|
106
|
-
### 2. 加载顺序
|
|
107
|
-
|
|
108
|
-
根据 `packages/core/lifecycle/lifecycle.ts` 的加载顺序(Line 70-120):
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
// 实际的加载顺序
|
|
112
|
-
1. 先加载所有 addon 的 APIs(按 addon 名称顺序)
|
|
113
|
-
2. 再加载项目(app)的 APIs
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**验证代码**:
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
// 1. 先加载 addon APIs
|
|
120
|
-
for (const addon of addons) {
|
|
121
|
-
if (hasApis) {
|
|
122
|
-
await Loader.loadApis(addon, this.apiRoutes, {
|
|
123
|
-
isAddon: true,
|
|
124
|
-
addonName: addon
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// 2. 后加载 app APIs
|
|
130
|
-
await Loader.loadApis('app', this.apiRoutes);
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
**如果发生冲突**:
|
|
134
|
-
|
|
135
|
-
- Addon 的 `list.ts` 先注册 → `POST/api/admin/list`
|
|
136
|
-
- 项目的 `admin/list.ts` 后注册 → **覆盖** addon 的接口
|
|
137
|
-
- **结果**:addon 的接口失效,项目接口生效,且**没有任何警告**
|
|
138
|
-
|
|
139
|
-
### 3. 实际影响
|
|
140
|
-
|
|
141
|
-
❌ **严重问题**:
|
|
142
|
-
|
|
143
|
-
- 用户无法预期哪个接口会生效
|
|
144
|
-
- 调试困难,没有冲突警告
|
|
145
|
-
- 可能导致接口行为异常
|
|
146
|
-
|
|
147
|
-
## 🎯 为什么会设计成这样?
|
|
148
|
-
|
|
149
|
-
### 当前的路径设计逻辑
|
|
150
|
-
|
|
151
|
-
```
|
|
152
|
-
Addon API 路径格式:
|
|
153
|
-
/api/{addonName}/{apiPath}
|
|
154
|
-
|
|
155
|
-
项目 API 路径格式:
|
|
156
|
-
/api/{apiPath}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
**设计意图**:
|
|
160
|
-
|
|
161
|
-
- Addon 用 addon 名称作为命名空间隔离
|
|
162
|
-
- 项目 API 可以自由组织目录结构
|
|
163
|
-
|
|
164
|
-
### 存在的问题
|
|
165
|
-
|
|
166
|
-
**场景 1**:Addon 名称与项目目录重名
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
✅ Addon: addons/admin/apis/list.ts → /api/admin/list
|
|
170
|
-
❌ 项目: apis/admin/list.ts → /api/admin/list
|
|
171
|
-
⚠️ 冲突!
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
**场景 2**:Addon 名称与项目目录不重名
|
|
175
|
-
|
|
176
|
-
```
|
|
177
|
-
✅ Addon: addons/admin/apis/list.ts → /api/admin/list
|
|
178
|
-
✅ 项目: apis/user/list.ts → /api/user/list
|
|
179
|
-
✅ 不冲突
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**场景 3**:项目 API 在根目录
|
|
183
|
-
|
|
184
|
-
```
|
|
185
|
-
✅ Addon: addons/admin/apis/list.ts → /api/admin/list
|
|
186
|
-
✅ 项目: apis/list.ts → /api/list
|
|
187
|
-
✅ 不冲突
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## 📊 实际案例验证
|
|
191
|
-
|
|
192
|
-
### 当前项目结构
|
|
193
|
-
|
|
194
|
-
**Addon APIs**:
|
|
195
|
-
|
|
196
|
-
```
|
|
197
|
-
packages/tpl/addons/admin/apis/
|
|
198
|
-
├── login.ts → POST/api/admin/login
|
|
199
|
-
├── register.ts → POST/api/admin/register
|
|
200
|
-
├── menuList.ts → POST/api/admin/menuList
|
|
201
|
-
├── roleList.ts → POST/api/admin/roleList
|
|
202
|
-
└── ... (共16个文件)
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
**项目 APIs**:
|
|
206
|
-
|
|
207
|
-
```
|
|
208
|
-
packages/tpl/apis/
|
|
209
|
-
├── article/
|
|
210
|
-
│ ├── list.ts → POST/api/article/list
|
|
211
|
-
│ ├── create.ts → POST/api/article/create
|
|
212
|
-
│ └── ...
|
|
213
|
-
├── user/
|
|
214
|
-
│ ├── list.ts → POST/api/user/list
|
|
215
|
-
│ └── login.ts → POST/api/user/login
|
|
216
|
-
└── test/
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
**当前状态**:
|
|
220
|
-
|
|
221
|
-
- ✅ **没有冲突**:因为项目 API 使用 `article/`、`user/` 等目录
|
|
222
|
-
- ✅ **addon 名称为 `admin`**,项目中没有 `admin/` 目录
|
|
223
|
-
|
|
224
|
-
### 潜在冲突场景
|
|
225
|
-
|
|
226
|
-
**如果创建**:
|
|
227
|
-
|
|
228
|
-
```
|
|
229
|
-
packages/tpl/apis/admin/list.ts
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
**冲突分析**:
|
|
233
|
-
|
|
234
|
-
```
|
|
235
|
-
Addon: addons/admin/apis/list.ts → POST/api/admin/list ❌
|
|
236
|
-
项目: apis/admin/list.ts → POST/api/admin/list ❌
|
|
237
|
-
⚠️ 路由冲突!
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## 💡 解决方案建议
|
|
241
|
-
|
|
242
|
-
### 方案 1:修改 Addon 路由前缀(推荐)
|
|
243
|
-
|
|
244
|
-
**修改 loader.ts**:
|
|
245
|
-
|
|
246
|
-
```typescript
|
|
247
|
-
// 当前
|
|
248
|
-
if (isAddon) {
|
|
249
|
-
api.route = `${api.method.toUpperCase()}/api/${addonName}/${apiPath}`;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// 建议改为
|
|
253
|
-
if (isAddon) {
|
|
254
|
-
api.route = `${api.method.toUpperCase()}/api/addon/${addonName}/${apiPath}`;
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**效果**:
|
|
259
|
-
|
|
260
|
-
```
|
|
261
|
-
Addon: addons/admin/apis/list.ts → POST/api/addon/admin/list ✅
|
|
262
|
-
项目: apis/admin/list.ts → POST/api/admin/list ✅
|
|
263
|
-
✅ 不冲突!
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
**优点**:
|
|
267
|
-
|
|
268
|
-
- 完全隔离 addon 和项目 API
|
|
269
|
-
- 路径更清晰,一看就知道是 addon 接口
|
|
270
|
-
- 符合命名空间最佳实践
|
|
271
|
-
|
|
272
|
-
**缺点**:
|
|
273
|
-
|
|
274
|
-
- 需要修改现有接口路径(破坏性变更)
|
|
275
|
-
- 前端调用需要更新
|
|
276
|
-
|
|
277
|
-
### 方案 2:添加冲突检测
|
|
278
|
-
|
|
279
|
-
**修改 loader.ts**:
|
|
280
|
-
|
|
281
|
-
```typescript
|
|
282
|
-
// 在注册路由前检查
|
|
283
|
-
if (apiRoutes.has(api.route)) {
|
|
284
|
-
const existing = apiRoutes.get(api.route);
|
|
285
|
-
Logger.error(`路由冲突检测:${api.route}`);
|
|
286
|
-
Logger.error(`已存在的接口:${existing.name}`);
|
|
287
|
-
Logger.error(`新接口:${api.name}`);
|
|
288
|
-
throw new Error(`路由冲突:${api.route} 已被注册`);
|
|
289
|
-
}
|
|
290
|
-
apiRoutes.set(api.route, api);
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
**优点**:
|
|
294
|
-
|
|
295
|
-
- 立即发现冲突
|
|
296
|
-
- 不改变路由规则
|
|
297
|
-
- 强制开发者解决冲突
|
|
298
|
-
|
|
299
|
-
**缺点**:
|
|
300
|
-
|
|
301
|
-
- 不解决根本问题
|
|
302
|
-
- 开发者需要手动避免冲突
|
|
303
|
-
|
|
304
|
-
### 方案 3:项目规范约束(临时方案)
|
|
305
|
-
|
|
306
|
-
**在 AGENTS.md 中添加规范**:
|
|
307
|
-
|
|
308
|
-
```markdown
|
|
309
|
-
## API 路由命名规范
|
|
310
|
-
|
|
311
|
-
### 禁止事项
|
|
312
|
-
|
|
313
|
-
❌ 禁止在项目 apis 目录下创建与 addon 名称相同的目录
|
|
314
|
-
|
|
315
|
-
### 允许的目录结构
|
|
316
|
-
|
|
317
|
-
✅ apis/article/
|
|
318
|
-
✅ apis/user/
|
|
319
|
-
✅ apis/product/
|
|
320
|
-
❌ apis/admin/ (admin 是 addon 名称)
|
|
321
|
-
❌ apis/befly/ (befly 是 addon 名称)
|
|
322
|
-
|
|
323
|
-
### Addon 名称清单
|
|
324
|
-
|
|
325
|
-
- admin
|
|
326
|
-
- befly
|
|
327
|
-
- demo
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
**优点**:
|
|
331
|
-
|
|
332
|
-
- 不需要修改代码
|
|
333
|
-
- 立即可用
|
|
334
|
-
|
|
335
|
-
**缺点**:
|
|
336
|
-
|
|
337
|
-
- 依赖开发者自觉
|
|
338
|
-
- 容易被遗忘
|
|
339
|
-
- 没有技术保障
|
|
340
|
-
|
|
341
|
-
### 方案 4:混合方案(最佳实践)
|
|
342
|
-
|
|
343
|
-
结合方案 1 和方案 2:
|
|
344
|
-
|
|
345
|
-
1. **立即**:添加冲突检测(方案 2)
|
|
346
|
-
2. **短期**:添加项目规范(方案 3)
|
|
347
|
-
3. **长期**:修改 addon 路由前缀为 `/api/addon/{name}/`(方案 1)
|
|
348
|
-
|
|
349
|
-
## 📋 影响评估
|
|
350
|
-
|
|
351
|
-
### 如果保持现状(不修改)
|
|
352
|
-
|
|
353
|
-
**风险等级**:🔴 **高风险**
|
|
354
|
-
|
|
355
|
-
**可能出现的问题**:
|
|
356
|
-
|
|
357
|
-
1. 开发者创建 `apis/admin/` 目录
|
|
358
|
-
2. 路由冲突,addon 接口失效
|
|
359
|
-
3. 前端调用报错,但日志没有明确提示
|
|
360
|
-
4. 调试困难,浪费时间
|
|
361
|
-
|
|
362
|
-
**发生概率**:
|
|
363
|
-
|
|
364
|
-
- ⚠️ **中高概率**:`admin` 是常见的目录名
|
|
365
|
-
|
|
366
|
-
### 如果添加冲突检测
|
|
367
|
-
|
|
368
|
-
**风险等级**:🟡 **中等风险**
|
|
369
|
-
|
|
370
|
-
**效果**:
|
|
371
|
-
|
|
372
|
-
- ✅ 能立即发现冲突
|
|
373
|
-
- ✅ 阻止错误部署
|
|
374
|
-
- ⚠️ 开发者需要重命名目录
|
|
375
|
-
|
|
376
|
-
### 如果修改 addon 路由前缀
|
|
377
|
-
|
|
378
|
-
**风险等级**:🟢 **低风险**
|
|
379
|
-
|
|
380
|
-
**效果**:
|
|
381
|
-
|
|
382
|
-
- ✅ 彻底解决冲突问题
|
|
383
|
-
- ✅ 路径更清晰
|
|
384
|
-
- ⚠️ 需要迁移现有接口
|
|
385
|
-
|
|
386
|
-
## 🎯 最终建议
|
|
387
|
-
|
|
388
|
-
### 立即执行(当前版本)
|
|
389
|
-
|
|
390
|
-
**1. 添加冲突检测**:
|
|
391
|
-
|
|
392
|
-
```typescript
|
|
393
|
-
// 在 loader.ts 的 apiRoutes.set() 之前
|
|
394
|
-
if (apiRoutes.has(api.route)) {
|
|
395
|
-
const existing = apiRoutes.get(api.route);
|
|
396
|
-
throw new Error(`❌ 路由冲突:${api.route}\n` + `已存在:${existing.name} (${isAddon ? 'Addon' : '项目'})\n` + `新接口:${api.name} (${isAddon ? 'Addon' : '项目'})\n` + `解决方案:避免项目 apis 目录与 addon 名称重名`);
|
|
397
|
-
}
|
|
398
|
-
apiRoutes.set(api.route, api);
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
**2. 更新 AGENTS.md**:
|
|
402
|
-
|
|
403
|
-
- 添加 API 路由命名规范
|
|
404
|
-
- 列出所有 addon 名称
|
|
405
|
-
- 禁止在项目中使用同名目录
|
|
406
|
-
|
|
407
|
-
### 后续优化(下一个版本)
|
|
408
|
-
|
|
409
|
-
**修改 addon 路由前缀**:
|
|
410
|
-
|
|
411
|
-
- Addon API:`/api/addon/{name}/{path}`
|
|
412
|
-
- 项目 API:`/api/{path}`
|
|
413
|
-
- 完全隔离,永久解决冲突
|
|
414
|
-
|
|
415
|
-
## 📝 总结
|
|
416
|
-
|
|
417
|
-
**问题答案**:
|
|
418
|
-
|
|
419
|
-
> **会冲突!** 如果 addon admin 中有 `list.ts`,项目中又创建 `apis/admin/list.ts`,两个接口会生成相同的路由 `POST/api/admin/list`,后加载的会覆盖先加载的。
|
|
420
|
-
|
|
421
|
-
**核心原因**:
|
|
422
|
-
|
|
423
|
-
- Addon API 路径格式:`/api/{addonName}/{apiPath}`
|
|
424
|
-
- 项目 API 路径格式:`/api/{apiPath}`
|
|
425
|
-
- 当项目目录名与 addon 名称相同时,会产生冲突
|
|
426
|
-
|
|
427
|
-
**解决方向**:
|
|
428
|
-
|
|
429
|
-
1. **短期**:添加冲突检测 + 项目规范
|
|
430
|
-
2. **长期**:修改 addon 路由前缀为 `/api/addon/{name}/`
|
|
431
|
-
|
|
432
|
-
**当前状态**:
|
|
433
|
-
|
|
434
|
-
- ✅ 项目中没有 `apis/admin/` 目录,暂时没有冲突
|
|
435
|
-
- ⚠️ 需要预防未来可能的冲突
|
|
436
|
-
|
|
437
|
-
---
|
|
438
|
-
|
|
439
|
-
**分析人**:AI Assistant
|
|
440
|
-
**建议优先级**:🔴 **高优先级**(添加冲突检测)
|
|
441
|
-
**最后更新**:2025-10-19
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
# Befly CLI 交互式脚本管理器使用指南
|
|
2
|
-
|
|
3
|
-
## 📋 核心特性
|
|
4
|
-
|
|
5
|
-
### 1. 纯交互模式
|
|
6
|
-
|
|
7
|
-
- 运行 `bunx befly` 进入交互模式
|
|
8
|
-
- 通过数字选择要执行的脚本
|
|
9
|
-
- 所有参数通过交互式问答添加
|
|
10
|
-
|
|
11
|
-
### 2. 脚本分类
|
|
12
|
-
|
|
13
|
-
- **内置脚本**:来自 `core/scripts`(如 `syncDb`、`syncDev`)
|
|
14
|
-
- **项目脚本**:来自 `tpl/scripts`(如 `syncDev`)
|
|
15
|
-
- **组件脚本**:来自 `tpl/addons/*/scripts`(如 `initMenu`、`syncDev`)
|
|
16
|
-
|
|
17
|
-
### 3. 脚本执行规则
|
|
18
|
-
|
|
19
|
-
- 选择哪个数字,就执行对应的脚本
|
|
20
|
-
- 即使有同名脚本,也会精确执行选中的那个
|
|
21
|
-
- 列表按来源分组:内置脚本 → 项目脚本 → 组件脚本
|
|
22
|
-
|
|
23
|
-
例如,有 3 个 `syncDev`:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
1. syncDb (内置)
|
|
27
|
-
2. syncDev (内置)
|
|
28
|
-
3. syncDev (项目)
|
|
29
|
-
4. initMenu (组件)
|
|
30
|
-
5. syncDev (组件)
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
- 选择 2 → 执行内置的 syncDev
|
|
34
|
-
- 选择 3 → 执行项目的 syncDev
|
|
35
|
-
- 选择 5 → 执行组件的 syncDev
|
|
36
|
-
|
|
37
|
-
## 🎯 使用方法
|
|
38
|
-
|
|
39
|
-
### 启动交互模式
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
bunx befly
|
|
43
|
-
# 或者
|
|
44
|
-
bunx befly <任何参数> # 参数会被忽略,统一进入交互模式
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### 显示效果
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
🚀 Befly CLI - 脚本管理器
|
|
51
|
-
|
|
52
|
-
📦 内置脚本:
|
|
53
|
-
1. syncDb
|
|
54
|
-
2. syncDev
|
|
55
|
-
|
|
56
|
-
📦 项目脚本:
|
|
57
|
-
3. syncDev
|
|
58
|
-
|
|
59
|
-
📦 组件脚本:
|
|
60
|
-
4. initMenu
|
|
61
|
-
5. syncDev
|
|
62
|
-
|
|
63
|
-
请输入脚本编号 (输入 0 或直接回车退出):
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 操作流程
|
|
67
|
-
|
|
68
|
-
1. **选择脚本**:输入数字(1-5),或输入 0/回车退出
|
|
69
|
-
2. **添加参数**:提示是否添加 `--plan` 参数(y/n,默认 n)
|
|
70
|
-
3. **确认执行**:提示是否执行(y/n,默认 y)
|
|
71
|
-
|
|
72
|
-
### 示例:选择脚本 1(syncDb)并添加 --plan
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
bunx befly
|
|
76
|
-
|
|
77
|
-
请输入脚本编号 (输入 0 或直接回车退出): 1
|
|
78
|
-
|
|
79
|
-
✅ 已选择: syncDb
|
|
80
|
-
是否添加 --plan 参数? (y/n,直接回车默认为 n): y
|
|
81
|
-
是否执行? (y/n,直接回车默认为 y): y
|
|
82
|
-
|
|
83
|
-
# 开始执行 syncDb --plan
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## 开发说明
|
|
87
|
-
|
|
88
|
-
### 添加新脚本
|
|
89
|
-
|
|
90
|
-
1. **内置脚本**:在 `core/scripts/` 下创建 `.ts` 文件
|
|
91
|
-
2. **项目脚本**:在 `tpl/scripts/` 下创建 `.ts` 文件
|
|
92
|
-
3. **组件脚本**:在 `tpl/addons/<addonName>/scripts/` 下创建 `.ts` 文件
|
|
93
|
-
|
|
94
|
-
CLI 会自动扫描这些目录,无需配置。
|
|
95
|
-
|
|
96
|
-
### 脚本命名规范
|
|
97
|
-
|
|
98
|
-
- 使用小驼峰或下划线命名(如 `syncDb`、`initMenu`)
|
|
99
|
-
- 文件扩展名为 `.ts`
|
|
100
|
-
- 脚本名称会自动去除 `.ts` 后缀
|
|
101
|
-
|
|
102
|
-
### 脚本模板
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
#!/usr/bin/env bun
|
|
106
|
-
import { Env, Logger } from 'befly';
|
|
107
|
-
|
|
108
|
-
// 从命令行参数获取 --plan 标志
|
|
109
|
-
const DRY_RUN = process.argv.includes('--plan');
|
|
110
|
-
|
|
111
|
-
async function main() {
|
|
112
|
-
if (DRY_RUN) {
|
|
113
|
-
Logger.info('[计划] 这里描述脚本将要执行的操作');
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// 实际执行逻辑
|
|
118
|
-
Logger.info('开始执行...');
|
|
119
|
-
// ...
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
main().catch((error) => {
|
|
123
|
-
Logger.error('执行失败:', error);
|
|
124
|
-
process.exit(1);
|
|
125
|
-
});
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## 🔍 常见问题
|
|
129
|
-
|
|
130
|
-
### Q: 如何知道执行了哪个来源的脚本?
|
|
131
|
-
|
|
132
|
-
A: 在日志中会显示脚本路径,或者在脚本内添加日志标识:
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
Logger.info('【项目脚本】syncDev 开始执行...');
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### Q: 为什么我的脚本没有显示?
|
|
139
|
-
|
|
140
|
-
A: 检查以下几点:
|
|
141
|
-
|
|
142
|
-
1. 文件扩展名是否为 `.ts`
|
|
143
|
-
2. 文件是否在正确的目录下(`core/scripts`、`tpl/scripts` 或 `tpl/addons/*/scripts`)
|
|
144
|
-
3. 文件名是否符合命名规范
|
|
145
|
-
|
|
146
|
-
### Q: 如何执行特定来源的脚本?
|
|
147
|
-
|
|
148
|
-
A: 使用数字选择即可精确执行:
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
bunx befly
|
|
152
|
-
|
|
153
|
-
# 列表显示:
|
|
154
|
-
# 1. syncDb (内置)
|
|
155
|
-
# 2. syncDev (内置)
|
|
156
|
-
# 3. syncDev (项目)
|
|
157
|
-
# 4. initMenu (组件)
|
|
158
|
-
# 5. syncDev (组件)
|
|
159
|
-
|
|
160
|
-
# 输入 2 → 执行内置的 syncDev
|
|
161
|
-
# 输入 3 → 执行项目的 syncDev
|
|
162
|
-
# 输入 5 → 执行组件的 syncDev
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Q: 如何快速执行脚本而不每次都要交互?
|
|
166
|
-
|
|
167
|
-
A: 目前仅支持交互模式,这样可以:
|
|
168
|
-
|
|
169
|
-
- 避免误执行错误的脚本
|
|
170
|
-
- 清晰看到所有可用脚本
|
|
171
|
-
- 灵活添加 --plan 等参数
|
|
172
|
-
- 执行前再次确认
|
|
173
|
-
|
|
174
|
-
如果需要自动化执行,建议直接使用 `bun` 运行脚本文件:
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
# 直接执行脚本文件
|
|
178
|
-
bun packages/core/scripts/syncDb.ts --plan
|
|
179
|
-
bun packages/tpl/scripts/syncDev.ts
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Q: --plan 参数有什么用?
|
|
183
|
-
|
|
184
|
-
A: 用于预演模式,脚本会输出将要执行的操作但不实际执行,适合:
|
|
185
|
-
|
|
186
|
-
- 查看脚本将做什么
|
|
187
|
-
- 验证参数是否正确
|
|
188
|
-
- 避免误操作
|
|
189
|
-
|
|
190
|
-
## 📊 技术实现
|
|
191
|
-
|
|
192
|
-
- **脚本扫描**:使用 `Bun.Glob` 扫描目录
|
|
193
|
-
- **脚本执行**:使用 `Bun.spawn` 执行子进程
|
|
194
|
-
- **交互输入**:使用 Node.js `readline` 模块
|
|
195
|
-
- **纯交互模式**:所有执行都通过数字选择,无传统命令行模式
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
**最后更新**: 2025-10-19
|