Nest Commander
standalone application hujjatlariga qo'shimcha ravishda, oddiy Nest ilovasiga o'xshash tuzilma bilan command line ilovalar yozish uchun nest-commander paketi ham mavjud.
standalone application hujjatlariga qo'shimcha ravishda, oddiy Nest ilovasiga o'xshash tuzilma bilan command line ilovalar yozish uchun nest-commander paketi ham mavjud.
nest-commander third-party paket hisoblanadi va NestJS core jamoasi tomonidan to'liq boshqarilmaydi. Kutubxonadagi muammolarni mos repository ga yuboring.
O'rnatish
Boshqa paketlar kabi, undan foydalanishdan oldin uni o'rnatishingiz kerak.
1$ npm i nest-commanderCommand fayli
nest-commander class'lar uchun @Command() va shu class metodlari uchun @Option() dekoratorlari orqali yangi command-line ilovalar yozishni osonlashtiradi. Har bir command fayli CommandRunner abstract class'ini implement qilishi va @Command() dekoratori bilan belgilanishi kerak.
Har bir command Nest tomonidan @Injectable() sifatida ko'riladi, shuning uchun odatiy Dependency Injection kutilganidek ishlaydi. E'tibor qaratish kerak bo'lgan asosiy narsa - har bir command implement qilishi kerak bo'lgan CommandRunner abstract class'i. CommandRunner barcha command'larda Promise<void> qaytaradigan va string[], Record<string, any> parametrlarini qabul qiladigan run metodi bo'lishini kafolatlaydi. run - barcha asosiy business logic boshlanadigan joy. U option flag'lariga mos tushmagan parametrlarni massiv sifatida qabul qiladi, bu bir nechta parametr bilan ishlamoqchi bo'lgan holatlar uchun foydali. options qismi esa Record<string, any> ko'rinishida bo'ladi; uning xossa nomlari @Option() dekoratorlarida berilgan name qiymatiga, xossa qiymatlari esa option handler qaytargan natijaga teng bo'ladi. Yaxshiroq type safety kerak bo'lsa, options uchun alohida interface yaratishingiz mumkin.
Command'ni ishga tushirish
NestJS ilovasida NestFactory orqali server yaratib, uni listen bilan ishga tushirganimiz kabi, nest-commander paketi ham command ilovasini ishga tushirish uchun sodda API beradi. CommandFactory ni import qiling, uning static run metodidan foydalaning va ilovangizning root module'ini uzating. Bu quyidagicha ko'rinadi:
1import { CommandFactory } from 'nest-commander';
2import { AppModule } from './app.module';
3
4async function bootstrap() {
5 await CommandFactory.run(AppModule);
6}
7
8bootstrap();Standart holatda CommandFactory ishlatilganda Nest logger'i o'chirilgan bo'ladi. Biroq uni run funksiyasining ikkinchi argumenti sifatida uzatish mumkin. Siz custom NestJS logger yoki saqlab qolmoqchi bo'lgan log level'lar massivini berishingiz mumkin. Masalan, faqat Nest xato loglari chiqishini istasangiz, bu yerda hech bo'lmaganda ['error'] uzatish foydali bo'ladi.
1import { CommandFactory } from 'nest-commander';
2import { AppModule } from './app.module';
3import { LogService } './log.service';
4
5async function bootstrap() {
6 await CommandFactory.run(AppModule, new LogService());
7
8 // or, if you only want to print Nest's warnings and errors
9 await CommandFactory.run(AppModule, ['warn', 'error']);
10}
11
12bootstrap();Hammasi shu. Ichki qatlamda CommandFactory siz uchun NestFactory ni chaqiradi va kerak bo'lganda app.close() ni ham bajaradi, shuning uchun memory leak haqida alohida qayg'urishingiz shart emas. Agar qo'shimcha error handling kerak bo'lsa, run chaqiruvini try/catch bilan o'rashingiz yoki bootstrap() ga .catch() zanjirlashingiz mumkin.
Testing
Ajoyib command line skript yozib, uni oson test qila olmaslikning foydasi yo'q. Yaxshiyamki, nest-commander NestJS ekotizimiga juda mos tushadigan utilitalarni taqdim etadi. Test rejimida command yaratish uchun CommandFactory o'rniga CommandTestFactory dan foydalanishingiz va metadata uzatishingiz mumkin. Bu @nestjs/testing dagi Test.createTestingModule ga juda o'xshaydi. Hatto ichki qatlamda aynan shu paketdan foydalanadi. compile() ni chaqirishdan oldin overrideProvider metodlarini zanjirlab, test ichida DI qismlarini almashtirishingiz ham mumkin.
Hammasini birlashtirish
Quyidagi class basic subcommand'ini qabul qiladigan yoki bevosita chaqiriladigan CLI command'ga teng bo'ladi. U -n, -s, va -b flag'larini (ularning uzun variantlari bilan birga) qo'llab-quvvatlaydi va har bir option uchun custom parser'ga ega. Odatdagidek --help flag'i ham ishlaydi.
1import { Command, CommandRunner, Option } from 'nest-commander';
2import { LogService } from './log.service';
3
4interface BasicCommandOptions {
5 string?: string;
6 boolean?: boolean;
7 number?: number;
8}
9
10@Command({ name: 'basic', description: 'A parameter parse' })
11export class BasicCommand extends CommandRunner {
12 constructor(private readonly logService: LogService) {
13 super()
14 }
15
16 async run(
17 passedParam: string[],
18 options?: BasicCommandOptions,
19 ): Promise<void> {
20 if (options?.boolean !== undefined && options?.boolean !== null) {
21 this.runWithBoolean(passedParam, options.boolean);
22 } else if (options?.number) {
23 this.runWithNumber(passedParam, options.number);
24 } else if (options?.string) {
25 this.runWithString(passedParam, options.string);
26 } else {
27 this.runWithNone(passedParam);
28 }
29 }
30
31 @Option({
32 flags: '-n, --number [number]',
33 description: 'A basic number parser',
34 })
35 parseNumber(val: string): number {
36 return Number(val);
37 }
38
39 @Option({
40 flags: '-s, --string [string]',
41 description: 'A string return',
42 })
43 parseString(val: string): string {
44 return val;
45 }
46
47 @Option({
48 flags: '-b, --boolean [boolean]',
49 description: 'A boolean parser',
50 })
51 parseBoolean(val: string): boolean {
52 return JSON.parse(val);
53 }
54
55 runWithString(param: string[], option: string): void {
56 this.logService.log({ param, string: option });
57 }
58
59 runWithNumber(param: string[], option: number): void {
60 this.logService.log({ param, number: option });
61 }
62
63 runWithBoolean(param: string[], option: boolean): void {
64 this.logService.log({ param, boolean: option });
65 }
66
67 runWithNone(param: string[]): void {
68 this.logService.log({ param });
69 }
70}Command class modulga qo'shilganiga ishonch hosil qiling:
1@Module({
2 providers: [LogService, BasicCommand],
3})
4export class AppModule {}Endi main.ts ichida CLI'ni ishga tushirish uchun quyidagini yozishingiz mumkin:
1async function bootstrap() {
2 await CommandFactory.run(AppModule);
3}
4
5bootstrap();Shu bilan command line ilovangiz tayyor bo'ladi.
Qo'shimcha ma'lumot
Ko'proq ma'lumot, misollar va API hujjatlari uchun nest-commander docs site ga tashrif buyuring.