@fastcar/cli 0.1.2 → 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/bin/cli.js +239 -226
- package/package.json +1 -1
- package/skills/AGENTS.md +251 -0
- package/skills/fastcar-database/SKILL.md +436 -337
- package/skills/fastcar-framework/SKILL.md +577 -856
- package/skills/fastcar-rpc-microservices/SKILL.md +19 -69
- package/skills/fastcar-serverless/SKILL.md +48 -48
- package/skills/fastcar-toolkit/SKILL.md +22 -31
- package/skills/typescript-coding-style/SKILL.md +144 -0
- package/src/init.js +708 -700
- package/src/pack.js +7 -7
- package/src/skill.js +493 -364
- package/src/update.js +301 -0
- package/src/utils.js +2 -2
|
@@ -1,856 +1,577 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: fastcar-framework
|
|
3
|
-
description: FastCar 是一个基于 TypeScript 的 Node.js 企业级应用开发框架,采用 IoC
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# FastCar Framework
|
|
7
|
-
|
|
8
|
-
FastCar 是基于 TypeScript 的 Node.js
|
|
9
|
-
|
|
10
|
-
## 核心概念
|
|
11
|
-
|
|
12
|
-
### IoC 容器与装饰器
|
|
13
|
-
|
|
14
|
-
| 装饰器 | 用途 | 示例 |
|
|
15
|
-
|--------|------|------|
|
|
16
|
-
| `@Application` | 入口应用类 | `@Application class App {}` |
|
|
17
|
-
| `@Component` | 通用组件 | `@Component class UtilService {}` |
|
|
18
|
-
| `@Service` | 服务层 | `@Service class
|
|
19
|
-
| `@Controller` | 控制器层 | `@Controller class
|
|
20
|
-
| `@Repository` | 数据访问层 | `@Repository class
|
|
21
|
-
| `@Autowired` | 依赖注入 | `@Autowired private
|
|
22
|
-
|
|
23
|
-
### 基础应用结构
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
import { FastCarApplication } from "@fastcar/core";
|
|
27
|
-
import { Application, Autowired, Component, Service } from "@fastcar/core/annotation";
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
@
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
@
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
@
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
@
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
@
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
@
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
###
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
app
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
@
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
@
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
###
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
```yaml
|
|
579
|
-
application:
|
|
580
|
-
env: "dev"
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
详细集群配置放在 `application-dev.yml`:
|
|
584
|
-
|
|
585
|
-
```yaml
|
|
586
|
-
settings:
|
|
587
|
-
hotterSysConfig: true # 监听系统配置变更
|
|
588
|
-
|
|
589
|
-
microservices:
|
|
590
|
-
center: # 服务中心
|
|
591
|
-
token: "nW0tT4bZ6qM7mF7wD2rT2pR9dT7gK3hZ"
|
|
592
|
-
servers:
|
|
593
|
-
- host: "localhost"
|
|
594
|
-
clusters: 1 # 实例数,serviceId 和端口号自动递增
|
|
595
|
-
list:
|
|
596
|
-
- type: "ws"
|
|
597
|
-
server: { port: 60000 }
|
|
598
|
-
timeout: 0 # 0 表示永不超时
|
|
599
|
-
connectionLimit: 1
|
|
600
|
-
disconnectInterval: 1000 # 断线重连间隔(毫秒)
|
|
601
|
-
retry:
|
|
602
|
-
retryCount: 3
|
|
603
|
-
retryInterval: 3000
|
|
604
|
-
timeout: 30000
|
|
605
|
-
maxMsgNum: 10000
|
|
606
|
-
increase: true
|
|
607
|
-
|
|
608
|
-
connector: # 连接器服务
|
|
609
|
-
token: "x3TGsWC9uloZu235LA07eAiJ61nQ1A5f"
|
|
610
|
-
servers:
|
|
611
|
-
- host: "localhost"
|
|
612
|
-
clusters: 1
|
|
613
|
-
list:
|
|
614
|
-
- front: true # 标记为面向客户端的前置节点
|
|
615
|
-
type: "ws"
|
|
616
|
-
server: { port: 60100 }
|
|
617
|
-
|
|
618
|
-
chat: # 聊天服务
|
|
619
|
-
token: "go0kbkNM3wQ4e2Vgo0kbkNM3wQ4e2V"
|
|
620
|
-
servers:
|
|
621
|
-
- host: "localhost"
|
|
622
|
-
clusters: 1
|
|
623
|
-
list:
|
|
624
|
-
- type: "ws"
|
|
625
|
-
server: { port: 60200 }
|
|
626
|
-
|
|
627
|
-
web: # Web 服务
|
|
628
|
-
token: "go0kbkNM3wQ4e2Vgo0kbkNM3wQ4e2V"
|
|
629
|
-
koa:
|
|
630
|
-
koaBodyParser:
|
|
631
|
-
enableTypes: ["json", "form", "text"]
|
|
632
|
-
extendTypes: { text: ["text/xml", "application/xml"] }
|
|
633
|
-
servers:
|
|
634
|
-
- host: "localhost"
|
|
635
|
-
clusters: 1
|
|
636
|
-
list:
|
|
637
|
-
- type: "http"
|
|
638
|
-
server: { port: 8080 }
|
|
639
|
-
- type: "ws"
|
|
640
|
-
server: { port: 60300 }
|
|
641
|
-
```
|
|
642
|
-
|
|
643
|
-
- `settings.microservices.<服务名>`:定义各微服务模块的集群配置。
|
|
644
|
-
- `token`:服务间通信鉴权令牌,防止非法节点接入。
|
|
645
|
-
- `servers`:服务器集群列表。
|
|
646
|
-
- `host`:主机地址。
|
|
647
|
-
- `clusters`:集群实例数量。若大于 1,框架会自动递增 `serviceId` 和端口号生成多个实例。
|
|
648
|
-
- `list`:该集群对外暴露的协议端点列表。
|
|
649
|
-
- `type`:协议类型,如 `ws`、`http`。
|
|
650
|
-
- `server`:端口配置 `{ port }`。
|
|
651
|
-
- `front: true`:仅 connector 等前置服务需要,表示该节点直接面向客户端。
|
|
652
|
-
- `timeout`:连接超时时间(毫秒),`0` 表示永不超时。
|
|
653
|
-
- `connectionLimit`:最大连接数限制。
|
|
654
|
-
- `disconnectInterval`:断线后重连间隔(毫秒)。
|
|
655
|
-
- `retry`:消息重试策略。
|
|
656
|
-
- `retryCount`:最大重试次数。
|
|
657
|
-
- `retryInterval`:重试间隔。
|
|
658
|
-
- `timeout`:重试总超时。
|
|
659
|
-
- `maxMsgNum`:消息队列最大长度。
|
|
660
|
-
- `increase`:是否递增重试间隔。
|
|
661
|
-
|
|
662
|
-
## 生命周期钩子
|
|
663
|
-
|
|
664
|
-
```typescript
|
|
665
|
-
import { ApplicationStart, ApplicationStop, ApplicationInit } from "@fastcar/core/annotation";
|
|
666
|
-
|
|
667
|
-
@Component
|
|
668
|
-
class LifecycleService {
|
|
669
|
-
// 应用启动时执行
|
|
670
|
-
@ApplicationStart
|
|
671
|
-
async onStart() {
|
|
672
|
-
console.log("应用启动");
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
// 应用停止前执行
|
|
676
|
-
@ApplicationStop
|
|
677
|
-
async onStop() {
|
|
678
|
-
console.log("应用停止");
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// 初始化(配合 @ApplicationRunner)
|
|
682
|
-
@ApplicationInit
|
|
683
|
-
async init() {
|
|
684
|
-
console.log("初始化完成");
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
## 工具类
|
|
690
|
-
|
|
691
|
-
```typescript
|
|
692
|
-
import { DateUtil, CryptoUtil, FileUtil, TypeUtil } from "@fastcar/core/utils";
|
|
693
|
-
|
|
694
|
-
// 日期时间
|
|
695
|
-
DateUtil.toDateTime(); // "2024-03-10 15:30:45"
|
|
696
|
-
DateUtil.toDay(); // "2024-03-10"
|
|
697
|
-
|
|
698
|
-
// 加密
|
|
699
|
-
CryptoUtil.aesEncode(key, iv, "data");
|
|
700
|
-
CryptoUtil.sha256Encode("password");
|
|
701
|
-
|
|
702
|
-
// 文件操作
|
|
703
|
-
FileUtil.getFilePathList("./src");
|
|
704
|
-
FileUtil.getResource("./config.yml");
|
|
705
|
-
|
|
706
|
-
// 类型判断
|
|
707
|
-
TypeUtil.isFunction(() => {}); // true
|
|
708
|
-
TypeUtil.isClass(MyClass); // true
|
|
709
|
-
```
|
|
710
|
-
|
|
711
|
-
## 完整模块列表
|
|
712
|
-
|
|
713
|
-
| 模块 | 安装命令 | 用途 |
|
|
714
|
-
|------|----------|------|
|
|
715
|
-
| @fastcar/core | `npm i @fastcar/core` | IoC 容器、配置管理 |
|
|
716
|
-
| @fastcar/koa | `npm i @fastcar/koa @fastcar/server` | Web 开发 |
|
|
717
|
-
| @fastcar/mysql | `npm i @fastcar/mysql` | MySQL 数据库 |
|
|
718
|
-
| @fastcar/pgsql | `npm i @fastcar/pgsql` | PostgreSQL |
|
|
719
|
-
| @fastcar/mongo | `npm i @fastcar/mongo` | MongoDB |
|
|
720
|
-
| @fastcar/redis | `npm i @fastcar/redis` | Redis 缓存 |
|
|
721
|
-
| @fastcar/cache | `npm i @fastcar/cache` | 缓存组件 |
|
|
722
|
-
| @fastcar/timer | `npm i @fastcar/timer` | 定时任务 |
|
|
723
|
-
| @fastcar/timewheel | `npm i @fastcar/timewheel` | 时间轮延时任务 |
|
|
724
|
-
| @fastcar/workerpool | `npm i @fastcar/workerpool` | 工作线程池 |
|
|
725
|
-
| @fastcar/rpc | `npm i @fastcar/rpc` | RPC 通信 |
|
|
726
|
-
| @fastcar/serverless | `npm i @fastcar/serverless` | Serverless 支持 |
|
|
727
|
-
| @fastcar/cos-sdk | `npm i @fastcar/cos-sdk` | 对象存储 |
|
|
728
|
-
|
|
729
|
-
## 快速开始新项目
|
|
730
|
-
|
|
731
|
-
### 使用 CLI 创建项目(推荐)
|
|
732
|
-
|
|
733
|
-
```bash
|
|
734
|
-
# Web 项目
|
|
735
|
-
mkdir my-web-app && cd my-web-app
|
|
736
|
-
fastcar-cli init web
|
|
737
|
-
npm install
|
|
738
|
-
npm run debug
|
|
739
|
-
|
|
740
|
-
# Static 项目
|
|
741
|
-
mkdir my-static-app && cd my-static-app
|
|
742
|
-
fastcar-cli init static
|
|
743
|
-
npm install
|
|
744
|
-
npm run debug
|
|
745
|
-
|
|
746
|
-
# RPC 项目
|
|
747
|
-
mkdir my-rpc-app && cd my-rpc-app
|
|
748
|
-
fastcar-cli init rpc
|
|
749
|
-
npm install
|
|
750
|
-
npm run debug
|
|
751
|
-
|
|
752
|
-
# COS 项目
|
|
753
|
-
mkdir my-cos-app && cd my-cos-app
|
|
754
|
-
fastcar-cli init cos
|
|
755
|
-
npm install
|
|
756
|
-
npm run debug
|
|
757
|
-
|
|
758
|
-
# Microservices 项目
|
|
759
|
-
mkdir my-ms-app && cd my-ms-app
|
|
760
|
-
fastcar-cli init microservices
|
|
761
|
-
npm install
|
|
762
|
-
npm run start-node # 单节点模式(子进程启动全部服务)
|
|
763
|
-
# 或
|
|
764
|
-
npm run start-pm2 # PM2 模式
|
|
765
|
-
```
|
|
766
|
-
|
|
767
|
-
### 手动创建项目
|
|
768
|
-
|
|
769
|
-
```bash
|
|
770
|
-
# 1. 创建项目
|
|
771
|
-
mkdir my-fastcar-app && cd my-fastcar-app
|
|
772
|
-
npm init -y
|
|
773
|
-
|
|
774
|
-
# 2. 安装依赖
|
|
775
|
-
npm i @fastcar/core @fastcar/koa @fastcar/server
|
|
776
|
-
npm i -D typescript ts-node @types/node
|
|
777
|
-
|
|
778
|
-
# 3. 初始化 TypeScript
|
|
779
|
-
npx tsc --init
|
|
780
|
-
|
|
781
|
-
# 4. 启用装饰器(tsconfig.json)
|
|
782
|
-
# "experimentalDecorators": true
|
|
783
|
-
# "emitDecoratorMetadata": true
|
|
784
|
-
|
|
785
|
-
# 5. 创建入口文件和配置文件,开始开发
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
## 常见错误与注意事项
|
|
789
|
-
|
|
790
|
-
### 1. 路由装饰器必须有括号
|
|
791
|
-
|
|
792
|
-
❌ **错误:**
|
|
793
|
-
```typescript
|
|
794
|
-
@GET
|
|
795
|
-
async list() { }
|
|
796
|
-
```
|
|
797
|
-
|
|
798
|
-
✅ **正确:**
|
|
799
|
-
```typescript
|
|
800
|
-
@GET()
|
|
801
|
-
async list() { }
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
### 2. 不要使用不存在的装饰器
|
|
805
|
-
|
|
806
|
-
❌ **错误:**
|
|
807
|
-
```typescript
|
|
808
|
-
import { Body, Param, Query } from "@fastcar/koa/annotation";
|
|
809
|
-
|
|
810
|
-
@GET("/:id")
|
|
811
|
-
async getById(@Param("id") id: string) { }
|
|
812
|
-
|
|
813
|
-
@POST()
|
|
814
|
-
async create(@Body body: UserDTO) { }
|
|
815
|
-
```
|
|
816
|
-
|
|
817
|
-
✅ **正确:**
|
|
818
|
-
```typescript
|
|
819
|
-
@GET("/:id")
|
|
820
|
-
async getById(id: string) { }
|
|
821
|
-
|
|
822
|
-
@POST()
|
|
823
|
-
async create(body: UserDTO) { }
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
### 3. 表单验证使用 @ValidForm + @Rule
|
|
827
|
-
|
|
828
|
-
❌ **错误:**
|
|
829
|
-
```typescript
|
|
830
|
-
@POST()
|
|
831
|
-
async create(@Body body: UserDTO) { }
|
|
832
|
-
```
|
|
833
|
-
|
|
834
|
-
✅ **正确:**
|
|
835
|
-
```typescript
|
|
836
|
-
@ValidForm
|
|
837
|
-
@POST()
|
|
838
|
-
async create(@Rule() body: UserDTO) { }
|
|
839
|
-
```
|
|
840
|
-
|
|
841
|
-
### 4. DTO 类放在单独文件夹
|
|
842
|
-
|
|
843
|
-
推荐项目结构:
|
|
844
|
-
```
|
|
845
|
-
src/
|
|
846
|
-
├── controller/ # 控制器
|
|
847
|
-
├── dto/ # DTO 类(表单验证)
|
|
848
|
-
├── service/ # 服务层
|
|
849
|
-
├── model/ # 数据模型
|
|
850
|
-
└── app.ts
|
|
851
|
-
```
|
|
852
|
-
|
|
853
|
-
## 参考资源
|
|
854
|
-
|
|
855
|
-
- 详细 API 文档:[references/api-reference.md](references/api-reference.md)
|
|
856
|
-
- 项目模板:[assets/project-template/](assets/project-template/)
|
|
1
|
+
---
|
|
2
|
+
name: fastcar-framework
|
|
3
|
+
description: FastCar 是一个基于 TypeScript 的 Node.js 企业级应用开发框架,采用 IoC(控制反转)设计思想。Use when working with FastCar framework for: (1) Creating IoC-based Node.js applications, (2) Using dependency injection with decorators (@Component, @Service, @Autowired), (3) Building web APIs with @fastcar/koa, (4) Database operations with MySQL/MongoDB/Redis, (5) Setting up scheduled tasks or worker pools, (6) Managing application lifecycle and configuration.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FastCar Framework
|
|
7
|
+
|
|
8
|
+
FastCar 是基于 TypeScript 的 Node.js 企业级应用开发框架,采用 IoC(控制反转)设计思想。
|
|
9
|
+
|
|
10
|
+
## 核心概念
|
|
11
|
+
|
|
12
|
+
### IoC 容器与装饰器
|
|
13
|
+
|
|
14
|
+
| 装饰器 | 用途 | 示例 |
|
|
15
|
+
|--------|------|------|
|
|
16
|
+
| `@Application` | 入口应用类 | `@Application class App {}` |
|
|
17
|
+
| `@Component` | 通用组件 | `@Component class UtilService {}` |
|
|
18
|
+
| `@Service` | 服务层 | `@Service class BizService {}` |
|
|
19
|
+
| `@Controller` | 控制器层 | `@Controller class ApiController {}` |
|
|
20
|
+
| `@Repository` | 数据访问层 | `@Repository class DataRepository {}` |
|
|
21
|
+
| `@Autowired` | 依赖注入 | `@Autowired private service!: BizService;` |
|
|
22
|
+
|
|
23
|
+
### 基础应用结构
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { FastCarApplication } from "@fastcar/core";
|
|
27
|
+
import { Application, Autowired, Component, Service, Controller } from "@fastcar/core/annotation";
|
|
28
|
+
|
|
29
|
+
@Service
|
|
30
|
+
class BizService {
|
|
31
|
+
getData() {
|
|
32
|
+
return [{ id: 1, name: "示例" }];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Controller
|
|
37
|
+
class ApiController {
|
|
38
|
+
@Autowired
|
|
39
|
+
private service!: BizService;
|
|
40
|
+
|
|
41
|
+
getData() {
|
|
42
|
+
return this.service.getData();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Application
|
|
47
|
+
class App {
|
|
48
|
+
app!: FastCarApplication;
|
|
49
|
+
|
|
50
|
+
async start() {
|
|
51
|
+
console.log("应用启动成功!");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const app = new App();
|
|
56
|
+
app.start();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 模块速查
|
|
60
|
+
|
|
61
|
+
### Web 开发 (@fastcar/koa)
|
|
62
|
+
|
|
63
|
+
**路由装饰器使用方式:**
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { GET, POST, REQUEST } from "@fastcar/koa/annotation";
|
|
67
|
+
import { Context } from "koa";
|
|
68
|
+
|
|
69
|
+
@Controller
|
|
70
|
+
@REQUEST("/api/items")
|
|
71
|
+
class ItemController {
|
|
72
|
+
// GET 请求 - 无路径参数时必须有括号
|
|
73
|
+
@GET()
|
|
74
|
+
async list() {
|
|
75
|
+
return { data: [] };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// GET 请求 - 有路径参数
|
|
79
|
+
@GET("/:id")
|
|
80
|
+
async getById(id: string, ctx: Context) {
|
|
81
|
+
return { id };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// POST 请求
|
|
85
|
+
@POST()
|
|
86
|
+
async create(body: ItemDTO, ctx: Context) {
|
|
87
|
+
return { created: true };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**⚠️ 重要:FastCar 没有 `@Body`, `@Param`, `@Query` 装饰器**
|
|
93
|
+
|
|
94
|
+
- 请求参数直接作为方法参数传入
|
|
95
|
+
- 第一个参数为请求数据(GET 的 query / POST 的 body / 路径参数)
|
|
96
|
+
- 第二个参数为 Koa 上下文 `ctx: Context`,**可省略**
|
|
97
|
+
- `Context` 需从 `koa` 导入:`import { Context } from "koa"`
|
|
98
|
+
|
|
99
|
+
### 数据库 (@fastcar/mysql)
|
|
100
|
+
|
|
101
|
+
**实体定义:**
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { Table, Field, DBType, PrimaryKey, NotNull, Size } from "@fastcar/core/annotation";
|
|
105
|
+
|
|
106
|
+
@Table("entities")
|
|
107
|
+
class Entity {
|
|
108
|
+
@Field("id")
|
|
109
|
+
@DBType("int")
|
|
110
|
+
@PrimaryKey
|
|
111
|
+
id!: number;
|
|
112
|
+
|
|
113
|
+
@Field("name")
|
|
114
|
+
@DBType("varchar")
|
|
115
|
+
@NotNull
|
|
116
|
+
@Size({ maxSize: 50 })
|
|
117
|
+
name!: string;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Mapper 定义:**
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { Entity, Repository } from "@fastcar/core/annotation";
|
|
125
|
+
import { MysqlMapper } from "@fastcar/mysql";
|
|
126
|
+
|
|
127
|
+
@Entity(Entity)
|
|
128
|
+
@Repository
|
|
129
|
+
class EntityMapper extends MysqlMapper<Entity> {}
|
|
130
|
+
export default EntityMapper;
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Service 中使用:**
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { Service, Autowired } from "@fastcar/core/annotation";
|
|
137
|
+
import { OrderEnum } from "@fastcar/core/db";
|
|
138
|
+
import EntityMapper from "./EntityMapper";
|
|
139
|
+
|
|
140
|
+
@Service
|
|
141
|
+
class EntityService {
|
|
142
|
+
@Autowired
|
|
143
|
+
private mapper!: EntityMapper;
|
|
144
|
+
|
|
145
|
+
async getList() {
|
|
146
|
+
return this.mapper.select({
|
|
147
|
+
where: { status: 1 },
|
|
148
|
+
orders: { createTime: OrderEnum.desc },
|
|
149
|
+
limit: 10
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async getOne(id: number) {
|
|
154
|
+
return this.mapper.selectOne({ where: { id } });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async create(data: Entity) {
|
|
158
|
+
return this.mapper.saveOne(data);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async update(id: number, data: Partial<Entity>) {
|
|
162
|
+
return this.mapper.update({ where: { id }, row: data });
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async delete(id: number) {
|
|
166
|
+
return this.mapper.delete({ where: { id } });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 表单验证 (@fastcar/core)
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import { ValidForm, NotNull, Size, Rule } from "@fastcar/core/annotation";
|
|
175
|
+
|
|
176
|
+
class ItemDTO {
|
|
177
|
+
@NotNull
|
|
178
|
+
name!: string;
|
|
179
|
+
|
|
180
|
+
@Size({ minSize: 1, maxSize: 150 })
|
|
181
|
+
value!: number;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@Controller
|
|
185
|
+
@REQUEST("/api/items")
|
|
186
|
+
class ItemController {
|
|
187
|
+
@GET()
|
|
188
|
+
async list(page: number = 1, pageSize: number = 10) {
|
|
189
|
+
return { page, pageSize, data: [] };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@ValidForm
|
|
193
|
+
@POST()
|
|
194
|
+
async create(@Rule() body: ItemDTO) {
|
|
195
|
+
const { name, value } = body;
|
|
196
|
+
return this.service.create({ name, value });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**表单验证规则:**
|
|
202
|
+
|
|
203
|
+
| 装饰器 | 用途 | 示例 |
|
|
204
|
+
|--------|------|------|
|
|
205
|
+
| `@ValidForm` | 开启方法参数校验 | 放在方法上 |
|
|
206
|
+
| `@Rule()` | 标记校验对象 | 放在 DTO 参数前 |
|
|
207
|
+
| `@NotNull` | 参数不能为空 | 放在 DTO 字段上 |
|
|
208
|
+
| `@Size({min, max})` | 大小限制 | 放在 DTO 字段上 |
|
|
209
|
+
|
|
210
|
+
### Redis (@fastcar/redis)
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { Service, Autowired } from "@fastcar/core/annotation";
|
|
214
|
+
import { RedisClient } from "@fastcar/redis/annotation";
|
|
215
|
+
|
|
216
|
+
@Service
|
|
217
|
+
class CacheService {
|
|
218
|
+
@RedisClient
|
|
219
|
+
private redis!: RedisClient;
|
|
220
|
+
|
|
221
|
+
async get(key: string) {
|
|
222
|
+
return this.redis.get(key);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async set(key: string, value: string, ttl?: number) {
|
|
226
|
+
await this.redis.set(key, value, ttl);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### 定时任务 (@fastcar/timer)
|
|
232
|
+
|
|
233
|
+
> **推荐使用 `@fastcar/timer/scheduling2` 模块**
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { ScheduledInterval, ScheduledCron } from "@fastcar/timer/scheduling2";
|
|
237
|
+
|
|
238
|
+
@Component
|
|
239
|
+
class TaskService {
|
|
240
|
+
// 间隔执行(毫秒)
|
|
241
|
+
@ScheduledInterval({ fixedRate: 60000 })
|
|
242
|
+
async intervalTask() {
|
|
243
|
+
console.log("每分钟执行");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Cron 表达式
|
|
247
|
+
@ScheduledCron("0 0 * * * *")
|
|
248
|
+
async hourlyTask() {
|
|
249
|
+
console.log("每小时执行");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### 工作线程池 (@fastcar/workerpool)
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { WorkerPool, WorkerTask } from "@fastcar/workerpool/annotation";
|
|
258
|
+
|
|
259
|
+
@Component
|
|
260
|
+
class ComputeService {
|
|
261
|
+
@WorkerPool({ minWorkers: 2, maxWorkers: 4 })
|
|
262
|
+
private pool!: WorkerPool;
|
|
263
|
+
|
|
264
|
+
@WorkerTask
|
|
265
|
+
heavyComputation(data: number[]): number {
|
|
266
|
+
return data.reduce((a, b) => a + b, 0);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 项目模板速查
|
|
272
|
+
|
|
273
|
+
FastCar CLI 提供 5 种项目模板:
|
|
274
|
+
|
|
275
|
+
| 模板 | 适用场景 | 核心依赖 | 关键注解 |
|
|
276
|
+
|------|---------|---------|---------|
|
|
277
|
+
| web | RESTful API 服务 | @fastcar/koa, @fastcar/server | @EnableKoa |
|
|
278
|
+
| static | 静态资源服务器 | @fastcar/koa, @fastcar/server | @EnableKoa + KoaStatic |
|
|
279
|
+
| rpc | RPC 微服务通信 | @fastcar/rpc, @fastcar/server | @EnableRPC |
|
|
280
|
+
| cos | 对象存储/文件上传 | @fastcar/koa, @fastcar/cossdk, @fastcar/server | @EnableKoa |
|
|
281
|
+
| microservices | 分布式多服务架构 | @fastcar/koa, @fastcar/rpc, @fastcar/server, @fastcar/timer | @EnableKoa / @EnableRPC |
|
|
282
|
+
|
|
283
|
+
### 各模板入口示例
|
|
284
|
+
|
|
285
|
+
**Web 模板**
|
|
286
|
+
```typescript
|
|
287
|
+
import { Application } from "@fastcar/core/annotation";
|
|
288
|
+
import { EnableKoa, KoaMiddleware } from "@fastcar/koa/annotation";
|
|
289
|
+
import { ExceptionGlobalHandler, KoaBodyParser } from "@fastcar/koa";
|
|
290
|
+
|
|
291
|
+
@Application
|
|
292
|
+
@EnableKoa
|
|
293
|
+
@KoaMiddleware(ExceptionGlobalHandler)
|
|
294
|
+
@KoaMiddleware(KoaBodyParser)
|
|
295
|
+
class APP {
|
|
296
|
+
app!: FastCarApplication;
|
|
297
|
+
}
|
|
298
|
+
export default new APP();
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**RPC 模板**
|
|
302
|
+
```typescript
|
|
303
|
+
import { Application } from "@fastcar/core/annotation";
|
|
304
|
+
import { EnableRPC } from "@fastcar/rpc/annotation";
|
|
305
|
+
|
|
306
|
+
@Application
|
|
307
|
+
@EnableRPC
|
|
308
|
+
class APP {}
|
|
309
|
+
export default new APP();
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**Microservices 模板**
|
|
313
|
+
微服务模板包含多服务架构:center(服务中心)、connector(连接器)、message(消息服务)、web(Web服务)、base(基础服务)。
|
|
314
|
+
|
|
315
|
+
### 项目结构示例
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
template/
|
|
319
|
+
├── src/
|
|
320
|
+
│ ├── controller/ # 控制器(web/cos)
|
|
321
|
+
│ ├── dto/ # DTO 类(表单验证)
|
|
322
|
+
│ ├── service/ # 服务层
|
|
323
|
+
│ ├── model/ # 数据模型
|
|
324
|
+
│ └── app.ts # 应用入口
|
|
325
|
+
├── resource/
|
|
326
|
+
│ └── application.yml # 配置文件
|
|
327
|
+
├── package.json
|
|
328
|
+
└── tsconfig.json
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### 模板依赖安装
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
# Web / Static
|
|
335
|
+
npm i @fastcar/core @fastcar/koa @fastcar/server
|
|
336
|
+
|
|
337
|
+
# RPC
|
|
338
|
+
npm i @fastcar/core @fastcar/rpc @fastcar/server
|
|
339
|
+
|
|
340
|
+
# COS
|
|
341
|
+
npm i @fastcar/core @fastcar/koa @fastcar/cossdk @fastcar/server
|
|
342
|
+
|
|
343
|
+
# Microservices
|
|
344
|
+
npm i @fastcar/core @fastcar/koa @fastcar/rpc @fastcar/server @fastcar/timer
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## 配置管理
|
|
348
|
+
|
|
349
|
+
配置文件放在 `resource/application.yml`。支持按 `env` 加载多文件,例如 `application-dev.yml` 会与主配置合并。
|
|
350
|
+
|
|
351
|
+
### 基础配置示例
|
|
352
|
+
|
|
353
|
+
```yaml
|
|
354
|
+
application:
|
|
355
|
+
name: my-app
|
|
356
|
+
version: 1.0.0
|
|
357
|
+
env: dev
|
|
358
|
+
|
|
359
|
+
mysql:
|
|
360
|
+
host: localhost
|
|
361
|
+
port: 3306
|
|
362
|
+
database: mydb
|
|
363
|
+
username: root
|
|
364
|
+
password: password
|
|
365
|
+
|
|
366
|
+
redis:
|
|
367
|
+
host: localhost
|
|
368
|
+
port: 6379
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
使用配置:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
import { Configure, Value } from "@fastcar/core/annotation";
|
|
375
|
+
|
|
376
|
+
@Configure
|
|
377
|
+
class AppConfig {
|
|
378
|
+
@Value("server.port")
|
|
379
|
+
port!: number;
|
|
380
|
+
|
|
381
|
+
@Value("mysql.host")
|
|
382
|
+
dbHost!: string;
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Web 模板 application.yml
|
|
387
|
+
|
|
388
|
+
```yaml
|
|
389
|
+
application:
|
|
390
|
+
env: "dev"
|
|
391
|
+
|
|
392
|
+
settings:
|
|
393
|
+
koa:
|
|
394
|
+
server:
|
|
395
|
+
- { port: 8080, host: "0.0.0.0" }
|
|
396
|
+
koaStatic:
|
|
397
|
+
{ "public": "public" }
|
|
398
|
+
koaBodyParser:
|
|
399
|
+
enableTypes: ["json", "form", "text"]
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### RPC 模板配置
|
|
403
|
+
|
|
404
|
+
```yaml
|
|
405
|
+
application:
|
|
406
|
+
name: "fastcar-boot-rpc"
|
|
407
|
+
|
|
408
|
+
settings:
|
|
409
|
+
rpc:
|
|
410
|
+
list:
|
|
411
|
+
- id: "server-1"
|
|
412
|
+
type: "ws"
|
|
413
|
+
server: { port: 1235 }
|
|
414
|
+
serviceType: "base"
|
|
415
|
+
secure:
|
|
416
|
+
username: "user"
|
|
417
|
+
password: "password"
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Microservices 模板配置
|
|
421
|
+
|
|
422
|
+
```yaml
|
|
423
|
+
settings:
|
|
424
|
+
microservices:
|
|
425
|
+
center:
|
|
426
|
+
token: "your-token-here"
|
|
427
|
+
servers:
|
|
428
|
+
- host: "localhost"
|
|
429
|
+
clusters: 1
|
|
430
|
+
list:
|
|
431
|
+
- type: "ws"
|
|
432
|
+
server: { port: 60000 }
|
|
433
|
+
connector:
|
|
434
|
+
token: "your-token-here"
|
|
435
|
+
servers:
|
|
436
|
+
- host: "localhost"
|
|
437
|
+
clusters: 1
|
|
438
|
+
list:
|
|
439
|
+
- front: true
|
|
440
|
+
type: "ws"
|
|
441
|
+
server: { port: 60100 }
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## 生命周期钩子
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
import { ApplicationStart, ApplicationStop, ApplicationInit } from "@fastcar/core/annotation";
|
|
448
|
+
|
|
449
|
+
@Component
|
|
450
|
+
class LifecycleService {
|
|
451
|
+
@ApplicationStart
|
|
452
|
+
async onStart() {
|
|
453
|
+
console.log("应用启动");
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
@ApplicationStop
|
|
457
|
+
async onStop() {
|
|
458
|
+
console.log("应用停止");
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
@ApplicationInit
|
|
462
|
+
async init() {
|
|
463
|
+
console.log("初始化完成");
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
## 工具类
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
import { DateUtil, CryptoUtil, FileUtil, TypeUtil } from "@fastcar/core/utils";
|
|
472
|
+
|
|
473
|
+
// 日期时间
|
|
474
|
+
DateUtil.toDateTime(); // "2024-03-10 15:30:45"
|
|
475
|
+
DateUtil.toDay(); // "2024-03-10"
|
|
476
|
+
|
|
477
|
+
// 加密
|
|
478
|
+
CryptoUtil.aesEncode(key, iv, "data");
|
|
479
|
+
CryptoUtil.sha256Encode("password");
|
|
480
|
+
|
|
481
|
+
// 文件操作
|
|
482
|
+
FileUtil.getFilePathList("./src");
|
|
483
|
+
FileUtil.getResource("./config.yml");
|
|
484
|
+
|
|
485
|
+
// 类型判断
|
|
486
|
+
TypeUtil.isFunction(() => {}); // true
|
|
487
|
+
TypeUtil.isClass(MyClass); // true
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## 完整模块列表
|
|
491
|
+
|
|
492
|
+
| 模块 | 安装命令 | 用途 |
|
|
493
|
+
|------|----------|------|
|
|
494
|
+
| @fastcar/core | `npm i @fastcar/core` | IoC 容器、配置管理 |
|
|
495
|
+
| @fastcar/koa | `npm i @fastcar/koa @fastcar/server` | Web 开发 |
|
|
496
|
+
| @fastcar/mysql | `npm i @fastcar/mysql` | MySQL 数据库 |
|
|
497
|
+
| @fastcar/pgsql | `npm i @fastcar/pgsql` | PostgreSQL |
|
|
498
|
+
| @fastcar/mongo | `npm i @fastcar/mongo` | MongoDB |
|
|
499
|
+
| @fastcar/redis | `npm i @fastcar/redis` | Redis 缓存 |
|
|
500
|
+
| @fastcar/cache | `npm i @fastcar/cache` | 缓存组件 |
|
|
501
|
+
| @fastcar/timer | `npm i @fastcar/timer` | 定时任务 |
|
|
502
|
+
| @fastcar/timewheel | `npm i @fastcar/timewheel` | 时间轮延时任务 |
|
|
503
|
+
| @fastcar/workerpool | `npm i @fastcar/workerpool` | 工作线程池 |
|
|
504
|
+
| @fastcar/rpc | `npm i @fastcar/rpc` | RPC 通信 |
|
|
505
|
+
| @fastcar/serverless | `npm i @fastcar/serverless` | Serverless 支持 |
|
|
506
|
+
| @fastcar/cos-sdk | `npm i @fastcar/cos-sdk` | 对象存储 |
|
|
507
|
+
|
|
508
|
+
## 快速开始新项目
|
|
509
|
+
|
|
510
|
+
### 使用 CLI 创建项目(推荐)
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
# Web 项目
|
|
514
|
+
mkdir my-web-app && cd my-web-app
|
|
515
|
+
fastcar-cli init web
|
|
516
|
+
npm install
|
|
517
|
+
npm run debug
|
|
518
|
+
|
|
519
|
+
# RPC 项目
|
|
520
|
+
mkdir my-rpc-app && cd my-rpc-app
|
|
521
|
+
fastcar-cli init rpc
|
|
522
|
+
npm install
|
|
523
|
+
npm run debug
|
|
524
|
+
|
|
525
|
+
# Microservices 项目
|
|
526
|
+
mkdir my-ms-app && cd my-ms-app
|
|
527
|
+
fastcar-cli init microservices
|
|
528
|
+
npm install
|
|
529
|
+
npm run start-node
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
## 常见错误与注意事项
|
|
533
|
+
|
|
534
|
+
### 1. 路由装饰器必须有括号
|
|
535
|
+
|
|
536
|
+
❌ **错误:**
|
|
537
|
+
```typescript
|
|
538
|
+
@GET
|
|
539
|
+
async list() { }
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
✅ **正确:**
|
|
543
|
+
```typescript
|
|
544
|
+
@GET()
|
|
545
|
+
async list() { }
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### 2. 不要使用不存在的装饰器
|
|
549
|
+
|
|
550
|
+
❌ **错误:**
|
|
551
|
+
```typescript
|
|
552
|
+
import { Body, Param, Query } from "@fastcar/koa/annotation";
|
|
553
|
+
|
|
554
|
+
@GET("/:id")
|
|
555
|
+
async getById(@Param("id") id: string) { }
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
✅ **正确:**
|
|
559
|
+
```typescript
|
|
560
|
+
@GET("/:id")
|
|
561
|
+
async getById(id: string) { }
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### 3. 表单验证使用 @ValidForm + @Rule
|
|
565
|
+
|
|
566
|
+
❌ **错误:**
|
|
567
|
+
```typescript
|
|
568
|
+
@POST()
|
|
569
|
+
async create(@Body body: ItemDTO) { }
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
✅ **正确:**
|
|
573
|
+
```typescript
|
|
574
|
+
@ValidForm
|
|
575
|
+
@POST()
|
|
576
|
+
async create(@Rule() body: ItemDTO) { }
|
|
577
|
+
```
|