🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### Nest Commander 扩展 \[独立应用程序\](https://docs.nestjs.com/standalone-applications)docs 还有 \[nest-commander\](https://jmcdo29.github.io/nest-commander) 包用于编写命令行应用程序的结构类似于典型的 Nest 应用程序。 > **INFO**`nest-commander`是第三方包,不由整个NestJS核心团队管理。请报告在\[适当的存储库\](https://github.com/jmcdo29/nest-commander/issues/new/choose) 中发现的库中的任何问题 #### 安装 就像任何其他软件包一样,您必须先安装它才能使用它。 ~~~bash $ npm i nest-commander ~~~ #### 命令文件 `nest-commander` 使得使用 \[decorators\](https://www.typescriptlang.org/docs/handbook/decorators.html) 通过类的`@Command()`装饰器编写新的命令行应用程序和该类的方法的`@Option()`装饰器。每个命令文件都应该实现`CommandRunner`接口并且应该用`@Command()`装饰器来装饰。 Nest 将每个命令都视为一个`@Injectable()`,因此您的正常依赖注入仍然可以正常工作。唯一需要注意的是接口`CommandRunner`,应该由每个命令实现。 `CommandRunner`接口确保所有命令都有一个`run`方法,该方法返回一个`Promise`并接受参数`string\[\], Record`。 `run` 命令是您可以从其中启动所有逻辑的地方,它将接收任何与选项标志不匹配的参数并将它们作为数组传递,以防万一您真的打算使用多个参数。至于选项,`Record`,这些属性的名称与给定给`@Option()`装饰器的`name`属性匹配,而它们的值与选项处理程序的返回值匹配。如果您想要更好的类型安全性,也欢迎您为您的选项创建一个界面。 #### 运行命令 类似于在 NestJS 应用程序中我们可以使用`NestFactory` 为我们创建服务器,并使用`listen` 运行它,`nest-commander` 包公开了一个简单易用的 API 来运行您的服务器。导入`CommandFactory`并使用`static`方法`run`并传入应用程序的根模块。这可能如下所示 ~~~ts import { CommandFactory } from 'nest-commander'; import { AppModule } from './app.module'; async function bootstrap() { await CommandFactory.run(AppModule); } bootstrap(); ~~~ 默认情况下,使用 CommandFactory 时 Nest 的记录器是禁用的。不过可以提供它,作为`run`函数的第二个参数。您可以提供自定义的 NestJS 记录器,或者您想要保留的日志级别数组 - 如果您只想打印 Nest 的错误日志,至少在此处提供`\['error'\]` 可能很有用。 ~~~ts import { CommandFactory } from 'nest-commander'; import { AppModule } from './app.module'; import { LogService } './log.service'; async function bootstrap() { await CommandFactory.run(AppModule, new LogService()); // or, if you only want to print Nest's warnings and errors await CommandFactory.run(AppModule, ['warn', 'error']); } bootstrap(); ~~~ 就是这样。在底层,`CommandFactory` 会为你调用`NestFactory` 并在必要时调用`app.close()`,所以你不必担心那里的内存泄漏。如果你需要添加一些错误处理,总是有`try/catch`包装`run`命令,或者你可以将一些`.catch()`方法链接到`bootstrap()`调用。 #### 测试 那么如果你不能超级容易地测试它,那么编写一个超级棒的命令行脚本有什么用,对吧?幸运的是,`nest-commander` 有一些实用程序,您可以使用它们与 NestJS 生态系统完美契合,任何 Nestlings 都会有宾至如归的感觉。您可以使用“CommandTestFactory”并传入元数据,而不是使用“CommandFactory”在测试模式下构建命令,这与来自“@nestjs/testing”的“Test.createTestingModule”的工作方式非常相似。事实上,它在后台使用了这个包。你还可以在调用`compile()`之前链接`overrideProvider`方法,这样你就可以在测试中换掉DI片段。 #### 一起使用 下面的类相当于有一个 CLI 命令,它可以接受子命令`basic` 或直接调用,支持`-n`、`-s` 和`-b`(以及它们的长标志)并为每个选项使用自定义解析器。也支持`--help`标志,这是指挥官的习惯。 ~~~ts import { Command, CommandRunner, Option } from 'nest-commander'; import { LogService } from './log.service'; interface BasicCommandOptions { string?: string; boolean?: boolean; number?: number; } @Command({ name: 'basic', description: 'A parameter parse' }) export class BasicCommand implements CommandRunner { constructor(private readonly logService: LogService) {} async run( passedParam: string[], options?: BasicCommandOptions, ): Promise<void> { if (options?.boolean !== undefined && options?.boolean !== null) { this.runWithBoolean(passedParam, options.boolean); } else if (options?.number) { this.runWithNumber(passedParam, options.number); } else if (options?.string) { this.runWithString(passedParam, options.string); } else { this.runWithNone(passedParam); } } @Option({ flags: '-n, --number [number]', description: 'A basic number parser', }) parseNumber(val: string): number { return Number(val); } @Option({ flags: '-s, --string [string]', description: 'A string return', }) parseString(val: string): string { return val; } @Option({ flags: '-b, --boolean [boolean]', description: 'A boolean parser', }) parseBoolean(val: string): boolean { return JSON.parse(val); } runWithString(param: string[], option: string): void { this.logService.log({ param, string: option }); } runWithNumber(param: string[], option: number): void { this.logService.log({ param, number: option }); } runWithBoolean(param: string[], option: boolean): void { this.logService.log({ param, boolean: option }); } runWithNone(param: string[]): void { this.logService.log({ param }); } } ~~~ 确保将命令类添加到模块 ~~~ts @Module({ providers: [LogService, BasicCommand], }) export class AppModule {} ~~~ 现在为了能够在 main.ts 中运行 CLI,您可以执行以下操作 ~~~ts async function bootstrap() { await CommandFactory.run(AppModule); } bootstrap(); ~~~ 就像这样,你有一个命令行应用程序。 #### 更多信息 访问 \[nest-commander 文档站点\](https://jmcdo29.github.io/nest-commander) 了解更多信息、示例和 API 文档。