### 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 文档。
- 介绍
- 概述
- 第一步
- 控制器
- 提供者
- 模块
- 中间件
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 自定义装饰器
- 基础知识
- 自定义提供者
- 异步提供者
- 动态模块
- 注入作用域
- 循环依赖
- 模块参考
- 懒加载模块
- 应用上下文
- 生命周期事件
- 跨平台
- 测试
- 技术
- 数据库
- Mongo
- 配置
- 验证
- 缓存
- 序列化
- 版本控制
- 定时任务
- 队列
- 日志
- Cookies
- 事件
- 压缩
- 文件上传
- 流式处理文件
- HTTP模块
- Session(会话)
- MVC
- 性能(Fastify)
- 服务器端事件发送
- 安全
- 认证(Authentication)
- 授权(Authorization)
- 加密和散列
- Helmet
- CORS(跨域请求)
- CSRF保护
- 限速
- GraphQL
- 快速开始
- 解析器(resolvers)
- 变更(Mutations)
- 订阅(Subscriptions)
- 标量(Scalars)
- 指令(directives)
- 接口(Interfaces)
- 联合类型
- 枚举(Enums)
- 字段中间件
- 映射类型
- 插件
- 复杂性
- 扩展
- CLI插件
- 生成SDL
- 其他功能
- 联合服务
- 迁移指南
- Websocket
- 网关
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 适配器
- 微服务
- 概述
- Redis
- MQTT
- NATS
- RabbitMQ
- Kafka
- gRPC
- 自定义传输器
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 独立应用
- Cli
- 概述
- 工作空间
- 库
- 用法
- 脚本
- Openapi
- 介绍
- 类型和参数
- 操作
- 安全
- 映射类型
- 装饰器
- CLI插件
- 其他特性
- 迁移指南
- 秘籍
- CRUD 生成器
- 热重载
- MikroORM
- TypeORM
- Mongoose
- 序列化
- 路由模块
- Swagger
- 健康检查
- CQRS
- 文档
- Prisma
- 静态服务
- Nest Commander
- 问答
- Serverless
- HTTP 适配器
- 全局路由前缀
- 混合应用
- HTTPS 和多服务器
- 请求生命周期
- 常见错误
- 实例
- 迁移指南
- 发现
- 谁在使用Nest?