ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## CLI插件 TypeScript的元数据反射系统有一些限制,一些功能因此不可能实现,例如确定一个类由哪些属性组成,或者一个属性是可选的还是必须的。然而,一些限制可以在编译时强调。Nest提供了一个增强TypeScript编译过程的插件来减少需要的原型代码量。 > 这个插件是一个`可选的`,你也可以选择手动声明所有的装饰器,或者仅仅声明你需要的。 ### 概述 Swagger插件可以自动: - 使用`@ApiProperty`注释所有除了用`@ApiHideProperty`装饰的DTO属性。 - 根据问号符号确定`required`属性(例如 `name?: string` 将设置`required: false`) - 根据类型配置`type`为`enum`(也支持数组) - 基于给定的默认值配置默认参数 - 基于`class-validator`装饰器配置一些验证策略(如果`classValidatorShim`配置为`true`) - 为每个终端添加一个响应装饰器,包括合适的状态和类型(响应模式) - 根据注释生成属性和终端的描述(如果`introspectComments`配置为`true`) - 基于注释生成属性的示例数据(如果`introspectComments`配置为`true`) 注意,你的文件名必须有如下后缀: `['.dto.ts', '.entity.ts']` (例如`create-user.dto.ts`) 才能被插件分析。 如果使用其他后缀,你可以调整插件属性来指定`dtoFileNameSuffix`选项(见下文)。 之前,如果你想要通过Swagger提供一个交互体验,你必须复制大量代码让包知道你的模型/组件在该声明中。例如,你可以定义一个`CreateUserDto`类: ```TypeScript export class CreateUserDto { @ApiProperty() email: string; @ApiProperty() password: string; @ApiProperty({ enum: RoleEnum, default: [], isArray: true }) roles: RoleEnum[] = []; @ApiProperty({ required: false, default: true }) isEnabled?: boolean = true; } ``` 在中等项目中这还不是问题,但是一旦有大量类的话这就变得冗余而难以维护。 要应用Swagger插件,可以简单声明上述类定义: ```TypeScript export class CreateUserDto { email: string; password: string; roles: RoleEnum[] = []; isEnabled?: boolean = true; } ``` 插件可以通过抽象语法树添加合适的装饰器,你不在需要在代码中到处写`ApiProperty`装饰器。 > 插件可以自动生成所有缺失的swagger属性,但是如果你要覆盖他们,只需要通过`@ApiProperty()`显式声明即可。 ### 注释自省 注释自省特性使能后,CLI插件可以基于注释生成描述和示例值。 例如,一个给定的`roles`属性示例: ```TypeScript /** * A list of user's roles * @example ['admin'] */ @ApiProperty({ description: `A list of user's roles`, example: ['admin'], }) roles: RoleEnum[] = []; ``` 你必须复制描述和示例值。当`introspectComments`使能后,CLI插件可以自动解压这些注释并提供描述(以及示例,如果定义了的话)。现在,上述属性可以简化为: ```TypeScript /** * A list of user's roles * @example ['admin'] */ roles: RoleEnum[] = []; ``` ### 使用CLI插件 要使能CLI插件,打开`nest-cli.json` (如果你在用[Nest CLI](https://docs.nestjs.com/cli/overview))并添加以下插件配置: ```TypeScript { "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { "plugins": ["@nestjs/swagger"] } } ``` 你可以使用其他`options`属性来自定义插件特性。 ```TypeScript "plugins": [ { "name": "@nestjs/swagger", "options": { "classValidatorShim": false, "introspectComments": true } } ] ``` `options`属性实现以下接口: ```TypeScript export interface PluginOptions { dtoFileNameSuffix?: string[]; controllerFileNameSuffix?: string[]; classValidatorShim?: boolean; introspectComments?: boolean; } ``` 选项|默认|说明 ---|---|--- dtoFileNameSuffix|['.dto.ts', '.entity.ts']|DTO (数据传输对象)文件后缀 controllerFileNameSuffix|.controller.ts|控制文件后缀 classValidatorShim|true|如果配置为`true`,模块将重用`class-validator`验证装饰器 (例如`@Max(10) `将在`schema`定义中增加`max: 10`) introspectComments|false|如果配置为`true`,插件将根据描述注释生成说明和示例 如果不使用CLI,但是使用一个用户定义的`Webpack`配置,可以和`ts-loader`配合使用该插件: ```TypeScript getCustomTransformers: (program: any) => ({ before: [require('@nestjs/swagger/plugin').before({}, program)] }), ``` ### `ts-jest`与(e2e 测试)集成 要运行e2e测试,`ts-jest`在内存汇总编译源码,这意味着不使用Nest Cli编译,不应用任何插件或AST转换,要使用插件,在e2e测试目录下创建以下文件: ```TypeScript const transformer = require('@nestjs/swagger/plugin'); module.exports.name = 'nestjs-swagger-transformer'; // you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes module.exports.version = 1; module.exports.factory = (cs) => { return transformer.before( { // @nestjs/swagger/plugin options (can be empty) }, cs.tsCompiler.program, ); }; ``` 在jest配置文件中引入AST变换。默认在(启动应用中),e2e测试配置文件在测试目录下,名为`jest-e2e.json`。 ```TypeScript { ... // other configuration "globals": { "ts-jest": { "astTransformers": { "before": ["<path to the file created above>"], } } } } ``` #### 故障排除`jest`(e2e 测试) 如果`jest` 似乎没有接收到您的配置更改,则 Jest 可能已经\*\*缓存\*\*了构建结果。要应用新配置,您需要清除 Jest 的缓存目录。 要清除缓存目录,请在 NestJS 项目文件夹中运行以下命令: ~~~bash $ npx jest --clearCache ~~~ 如果自动清除缓存失败,您仍然可以使用以下命令手动删除缓存文件夹: ~~~bash # 查找 jest 缓存目录 (通常是 /tmp/jest_rs) # 通过在您的 NestJS 项目根目录中运行以下命令 $ npx jest --showConfig | grep cache # ex result: # "cache": true, # "cacheDirectory": "/tmp/jest_rs" # Remove or empty the Jest cache directory $ rm -rf <cacheDirectory value> # ex: # rm -rf /tmp/jest_rs ~~~