## CLI 插件
> 此章節僅適用于代碼優先模式。
TypeScript 的元數據反射系統有幾個限制,例如,確定一個類包含哪些屬性或識別給定的屬性是可選還是必須的。但是,其中一些約束可以在編譯時解決。Nest 提供了一個插件,它可以增強 TypeScript 的編譯進程,以減少依賴的模板代碼量。
> 這個插件是<span style="color:blue">可配置的</span>。如果你愿意,你可以手動聲明所有的裝飾器,或者只在需要的地方聲明特定的裝飾器。
### 概覽
GraphQL 插件會自動地:
- 除非使用 `@HideField`,否則使用 `@Field` 注釋所有輸入對象、對象類型和參數類屬性
- 根據問號設置 `nullable` 屬性(例如,`name?: string` 將會設置 `nullable: true`)
- 根據類型設置 `type` 屬性(支持數組)
- 根據注釋生成屬性描述(如果 `introspectComments` 設為 `true`)
請注意,為了能被插件分析,你的文件名**必須包含**以下后綴之一:`['.input.ts', '.args.ts', '.entity.ts', '.model.ts']`(例如,`author.entity.ts`)。如果你用了其他的后綴,你可以通過指定 `typeFileNameSuffix` 配置來調整插件的行為(看下文)。
根據我們到目前為止所學的知識,你必須復制大量代碼才能讓包知道你的類型在 GraphQL 中應該如何被聲明。例如,你可以定義一個簡單的 `Author` 類,如下所示:
```typescript
authors/models/author.model.ts
@ObjectType()
export class Author {
@Field(type => ID)
id: number;
@Field({ nullable: true })
firstName?: string;
@Field({ nullable: true })
lastName?: string;
@Field(type => [Post])
posts: Post[];
}
```
雖然對于中型項目來說這不是一個重大問題,但一旦你有大量的類,它就會變得冗長且難以維護。
通過啟用 GraphQL 插件,以上的類聲明將會變得簡單:
```typescript
authors/models/author.model.ts
@ObjectType()
export class Author {
@Field(type => ID)
id: number;
firstName?: string;
lastName?: string;
posts: Post[];
}
```
該插件基于**抽象語法樹**即時添加適當的裝飾器。因此,你不必為散布在整個代碼中的 `@Field` 裝飾器而煩惱。
> 該插件將自動生成任何缺失的 GraphQL 屬性,但如果你需要覆蓋他們,只需通過 `@Feild` 顯示地設置它們。
### 注釋內省
啟用注釋內省功能,CLI 插件會根據注釋為字段生成描述。
例如,給出一個 `roles` 屬性示例:
```typescript
/**
* A list of user's roles
*/
@Field(() => [String], {
description: `A list of user's roles`
})
roles: string[];
```
你必須復制描述值。當 `introspectComments` 啟用時,CLI 插件可以提取這些注釋并自動為屬性提供屬性。現在,上面的字段可以被簡單地聲明如下:
```typescript
/**
* A list of user's roles
*/
roles: string[];
```
### CLI 插件的使用
要開啟插件,請打開 `nest-cli.json`(如果你使用 <span style="color:red">Nest CLI</span>)并添加以下的 `plugins` 配置:
```typescript
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"plugins": ["@nestjs/graphql"]
}
}
```
你可以用 `options` 屬性來自定義插件的行為。
```typescript
"plugins": [
{
"name": "@nestjs/graphql",
"options": {
"typeFileNameSuffix": [".input.ts", ".args.ts"],
"introspectComments": true
}
}
]
```
`options` 屬性必須滿足以下接口:
```typescript
export interface PluginOptions {
typeFileNameSuffix?: string[];
introspectComments?: boolean;
}
```
| 選項 | 默認值 | 描述 |
|:---:|---|---|
| `typeFileNameSuffix` | ```['.input.ts', '.args.ts', '.entity.ts', '.model.ts']``` | GraphQL 類型文件后綴 |
| `introspectComments` | `false` | 如果為真,插件將會根據注釋為屬性生成描述 |
如果你不使用 CLI 而是用自定義的 `webpack` 配置,則可以將此插件與 `ts-loader` 結合使用:
```typescript
getCustomTransformers: (program: any) => ({
before: [require('@nestjs/graphql/plugin').before({}, program)]
}),
```
### `ts-jest` 集成(e2e 測試)
在啟用此插件的情況下運行 e2e 測試時,你可能會遇到編譯 schema 的問題。例如,其中一個最常見的錯誤是:
```typescript
Object type <name> must define one or more fields.
```
發生這種情況是原因是 `jest` 配置沒有在任何地方導入 `@nestjs/graphql/plugin` 插件。
為解決此問題,我們需要在 e2e 測試目錄中創建如下文件:
```typescript
const transformer = require('@nestjs/graphql/plugin');
module.exports.name = 'nestjs-graphql-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/graphql/plugin options (can be empty)
},
cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
);
};
```
在這里,將 AST 轉換器導入到你的 `jest` 配置中。默認情況下(在啟動應用中),e2e 測試配置文件在 `test` 文件夾下并且名字是 `jest-e2e.json`。
```json
{
... // other configuration
"globals": {
"ts-jest": {
"astTransformers": {
"before": ["<path to the file created above>"],
}
}
}
}
```
- 介紹
- 概述
- 第一步
- 控制器
- 提供者
- 模塊
- 中間件
- 異常過濾器
- 管道
- 守衛
- 攔截器
- 自定義裝飾器
- 基礎知識
- 自定義提供者
- 異步提供者
- 動態模塊
- 注入作用域
- 循環依賴
- 模塊參考
- 懶加載模塊
- 應用上下文
- 生命周期事件
- 跨平臺
- 測試
- 技術
- 數據庫
- 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?