Nest Commander 시도

개시하다

  • 이번에는 NestJS가 콘솔 응용 프로그램Nest Commander을 간단하게 만들 수 있는 것을 시험해 보고 싶습니다.
  • 독자 대상

  • NestJS에서 콘솔 애플리케이션을 효과적으로 쓰고 싶은 사람
  • Nest Commander란


    https://docs.nestjs.com/recipes/nest-commander

  • 콘솔 애플리케이션은 @Command 단위로 설치할 수 있습니다.
  • NestJS의 DI 및 로그 기능을 직접 사용할 수 있습니다.
  • @Command 내용에 따라 명령줄이 실행될 때 파라미터를 지정할 수 있습니다.
  • 단일 콘솔 애플리케이션을 통해 여러 개@Command를 관리할 수 있습니다.시작할 때 명령행 매개 변수로 실행할 것을 지정할 수 있습니다 @Command.
  • 명령행 파라미터를 통해 변수를 전송할 때의 변환 처리는 @Option로 정의할 수 있다.

  • NestJS 공식 Standalone 애플리케이션 페이지에는 NestJS를 사용하는 콘솔 애플리케이션에 대한 쓰기 방법이 기재되어 있습니다.이 방법으로 하면 여러 개의 컨트롤러 프로그램을 관리하려면monorepo화가 필요하다.Nest Commander의 경우 monorepo를 사용할 필요가 없습니다.
  • 작업 환경

  • Node.js - 16.x
  • Yarn - 1.22.x
  • 라이브러리 작업

  • nestjs - 8.x
  • nest-commander - 2.4.x
  • 작업 방침

  • 콘솔 로그만 출력하는 2개@Command
  • 작성
  • 하나@Command에 명령행 파라미터를 통해 변수를 제공하고 변환
  • 실행 시 명령행 매개 변수를 통해 전환할 수 있는지 확인
  • 샘플 코드


    src/sample1.command.ts
    import { Logger } from '@nestjs/common';
    import { CommandRunner, Command, Option } from 'nest-commander';
    
    /** コマンドライン引数で渡す変数の型管理 */
    type CommandOptions = {
      id?: number;
    };
    
    @Command({
      // コマンドライン引数で`sample1`を指定することで起動可能
      name: 'sample1',
      // isDefault=true: コマンドライン引数を指定しない場合に起動できる。アプリケーション内で1つのみ指定可能
      options: { isDefault: true },
    })
    export class Sample1Command implements CommandRunner {
      /** 
       * --idの数字変換処理
       * --id=数字を指定するとrunのoptions.idに値が設定される
       */
      @Option({
        flags: '--id [number]',
      })
      parseId(value: string): number {
        return Number(value);
      }
    
      /**
       * @Command.nameで呼び出された時に実行される処理
       */
      async run(passedParams: string[], options?: CommandOptions): Promise<void> {
        Logger.log({ passedParams, options }, Sample1Command.name);
        return Promise.resolve();
      }
    }
    
    src/sample2.command.ts
    import { Logger } from '@nestjs/common';
    import { CommandRunner, Command } from 'nest-commander';
    
    @Command({
      name: 'sample2',
    })
    export class Sample2Command implements CommandRunner {
      /**
       * @Command.nameで呼び出された時に実行される処理
       */
      async run(passedParams: string[], options?: Record<string, unknown>): Promise<void> {
        Logger.log({ passedParams, options }, Sample2Command.name);
        return Promise.resolve();
      }
    }
    
    src/app.module.ts
    import { Module } from '@nestjs/common';
    import { Sample1Command } from './sample1.command';
    import { Sample2Command } from './sample2.command';
    
    @Module({
      imports: [],
      // Sample1Command, Sample2Commandを指定する
      providers: [Sample1Command, Sample2Command],
    })
    export class AppModule {}
    
    src/main.ts
    import { CommandFactory } from 'nest-commander';
    import { AppModule } from './app.module';
    
    async function bootstrap() {
      // nest-commanderのCommandFactoryにAppModuleを指定する
      // 出力されるログレベルを指定する(標準だとログ出力されないため)
      await CommandFactory.run(AppModule, ['warn', 'error', 'debug', 'log']);
    }
    bootstrap();
    

    동작 확인


    # Sample1Command実行(デフォルトCommand)
    node dist/main --id=123 
    node dist/main sample1 --id=123
    
    # Sample2Command実行
    node dist/main sample2
    

    소스 코드 세트


    https://github.com/yasu-s/nest-commander-sample/tree/demo

    끝말

  • NestJS의 기본 기능을 사용할 수 있고 거기에 여러 개의 컨트롤러 앱을 설치할 수 있기 때문에 NestJS에 익숙해진 사람에게는 편리한 프로그램 라이브러리라고 느낀다.
  • DI와 로그 기능 등을 직접 사용하는 것이 좋다.
  • 명령행 매개 변수의 변환 처리를 선언적으로 할 수 있어 매우 편리하다.
  • Node.js로 처음부터 컨트롤러 프로그램을 만드는 것보다 모델과 도층이 튼튼하기 때문에 원본 코드의 치안이 일정한 수준을 유지할 수 있다고 생각합니다.

  • Sub Commands도 만들 수 있는데 CLI 스타일의 물건을 만들고 싶을 때 한번 해보고 싶어요.
  • 새로운 비트레이트를 구축할 때 도입이 어떤지 연구해 보자.
  • 참조 링크


    https://docs.nestjs.com/recipes/nest-commander
    https://nest-commander.jaymcdoniel.dev/

    좋은 웹페이지 즐겨찾기