GraphQL4 min read

CLI plagin

TypeScriptning metadata reflection tizimida bir nechta cheklovlar bor: masalan, klass qaysi xossalardan iboratligini aniqlash yoki berilgan xossa ixtiyoriy yoki majburiyligini bili

Warning

Bu bob faqat code first yondashuviga tegishli.

TypeScriptning metadata reflection tizimida bir nechta cheklovlar bor: masalan, klass qaysi xossalardan iboratligini aniqlash yoki berilgan xossa ixtiyoriy yoki majburiyligini bilish imkonsiz. Biroq, bu cheklovlarning ayrimlarini kompilyatsiya vaqtida hal qilish mumkin. Nest TypeScript kompilyatsiya jarayonini yaxshilaydigan plagin taqdim etadi, bu esa kerakli boilerplate kod miqdorini kamaytiradi.

Hint

Bu plagin opt-in. Xohlasangiz, barcha dekoratorlarni qo'lda e'lon qilishingiz yoki faqat kerak bo'lgan dekoratorlarni qo'shishingiz mumkin.

Umumiy ko'rinish

GraphQL plagin avtomatik ravishda:

  • barcha input object, object type va args klasslaridagi xossalarni @Field bilan annotatsiya qiladi, agar @HideField ishlatilmagan bo'lsa
  • savol belgisi mavjudligiga qarab nullable xossasini o'rnatadi (masalan, name?: string bo'lsa nullable: true bo'ladi)
  • turiga qarab type xossasini o'rnatadi (massivlarni ham qo'llab-quvvatlaydi)
  • kommentariylar asosida xossalar uchun tavsiflarni generatsiya qiladi (introspectComments true bo'lsa)

E'tibor bering, fayl nomlari plagin tomonidan tahlil qilinishi uchun quyidagi suffixlardan biriga ega bo'lishi shart: ['.input.ts', '.args.ts', '.entity.ts', '.model.ts'] (masalan, author.entity.ts). Agar boshqa suffixdan foydalansangiz, typeFileNameSuffix opsiyasini ko'rsatib plagin xatti-harakatini sozlashingiz mumkin (quyida qarang).

Hozirgacha o'rganganlarimiz asosida, type GraphQLda qanday e'lon qilinishi kerakligini paketga bildirish uchun ko'p kodni takrorlashga to'g'ri keladi. Masalan, oddiy Author klassini quyidagicha belgilashingiz mumkin:

TypeScript
authors/models/author.model
1@ObjectType()
2export class Author {
3  @Field(type => ID)
4  id: number;
5
6  @Field({ nullable: true })
7  firstName?: string;
8
9  @Field({ nullable: true })
10  lastName?: string;
11
12  @Field(type => [Post])
13  posts: Post[];
14}

O'rta hajmdagi loyihalar uchun bu katta muammo emas, ammo klasslar to'plami katta bo'lsa, bu yondashuv haddan tashqari batafsil va boshqarish qiyin bo'lib qoladi.

GraphQL plaginini yoqsangiz, yuqoridagi klass ta'rifini quyidagicha soddalashtirib yozishingiz mumkin:

TypeScript
authors/models/author.model
1@ObjectType()
2export class Author {
3  @Field(type => ID)
4  id: number;
5  firstName?: string;
6  lastName?: string;
7  posts: Post[];
8}

Plagin Abstract Syntax Tree asosida kerakli dekoratorlarni dinamik qo'shadi. Shunday qilib, butun kod bo'ylab @Field dekoratorlarini qo'lda tarqatish bilan ovora bo'lmaysiz.

Hint

Plagin yetishmayotgan GraphQL xossalarini avtomatik generatsiya qiladi, ammo ularni override qilish kerak bo'lsa, @Field() orqali ularni aniq belgilang.

Kommentariylarni introspektsiya qilish

Kommentariylarni introspektsiya qilish yoqilgan bo'lsa, CLI plagin kommentariylar asosida fieldlar uchun tavsiflarni generatsiya qiladi.

Masalan, quyidagi roles xossasiga qarang:

TypeScript
1/**
2 * A list of user's roles
3 */
4@Field(() => [String], {
5  description: `A list of user's roles`
6})
7roles: string[];

Bu yerda tavsif qiymatini takrorlashga to'g'ri keladi. introspectComments yoqilganda, CLI plagin bu kommentariylarni ajratib olib, xossalar uchun avtomatik tavsiflarni taqdim eta oladi. Endi yuqoridagi fieldni quyidagicha yozish kifoya:

TypeScript
1/**
2 * A list of user's roles
3 */
4roles: string[];

CLI plaginini ishlatish

Plaginni yoqish uchun nest-cli.json faylini oching (agar Nest CLI dan foydalansangiz) va quyidagi plugins konfiguratsiyasini qo'shing:

JavaScript
1{
2  "collection": "@nestjs/schematics",
3  "sourceRoot": "src",
4  "compilerOptions": {
5    "plugins": ["@nestjs/graphql"]
6  }
7}

Plagin xatti-harakatini sozlash uchun options xossasidan foydalanishingiz mumkin.

JavaScript
1{
2  "collection": "@nestjs/schematics",
3  "sourceRoot": "src",
4  "compilerOptions": {
5    "plugins": [
6      {
7        "name": "@nestjs/graphql",
8        "options": {
9          "typeFileNameSuffix": [".input.ts", ".args.ts"],
10          "introspectComments": true
11        }
12      }
13    ]
14  }
15}

options xossasi quyidagi interfeysga mos bo'lishi kerak:

TypeScript
1export interface PluginOptions {
2  typeFileNameSuffix?: string[];
3  introspectComments?: boolean;
4}
OptionDefaultDescription
typeFileNameSuffix['.input.ts', '.args.ts', '.entity.ts', '.model.ts']GraphQL type fayllari suffixi
introspectCommentsfalseTrue bo'lsa, plagin kommentariylar asosida xossalar uchun tavsiflar generatsiya qiladi

Agar CLI dan foydalanmasangiz va custom webpack konfiguratsiyangiz bo'lsa, bu plaginni ts-loader bilan birga ishlatishingiz mumkin:

JavaScript
1getCustomTransformers: (program: any) => ({
2  before: [require('@nestjs/graphql/plugin').before({}, program)]
3}),

SWC builder

Standart setup (monorepo emas) uchun, SWC builder bilan CLI plaginlaridan foydalanish uchun type checkingni yoqishingiz kerak, bu bu yerda tasvirlangan.

Terminal
1$ nest start -b swc --type-check

Monorepo setup uchun, bu yerdagi ko'rsatmalarga amal qiling.

Terminal
1$ npx ts-node src/generate-metadata.ts
2# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts

Endi serializatsiya qilingan metadata fayli GraphQLModule metodiga quyidagicha yuklanishi kerak:

TypeScript
1import metadata from './metadata'; // <-- file auto-generated by the "PluginMetadataGenerator"
2
3GraphQLModule.forRoot<...>({
4  ..., // other options
5  metadata,
6}),

ts-jest bilan integratsiya (e2e testlar)

Ushbu plagin yoqilgan holda e2e testlarni ishga tushirayotganda, schema kompilyatsiyasida muammo bo'lishi mumkin. Masalan, eng ko'p uchraydigan xatolardan biri:

JSON
1Object type <name> must define one or more fields.

Bu jest konfiguratsiyasi @nestjs/graphql/plugin plaginini hech qayerda import qilmagani uchun sodir bo'ladi.

Buni tuzatish uchun e2e testlar direktoriyangizda quyidagi faylni yarating:

JavaScript
1const transformer = require('@nestjs/graphql/plugin');
2
3module.exports.name = 'nestjs-graphql-transformer';
4// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
5module.exports.version = 1;
6
7module.exports.factory = (cs) => {
8  return transformer.before(
9    {
10      // @nestjs/graphql/plugin options (can be empty)
11    },
12    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
13  );
14};

Shu bilan, jest konfiguratsiya faylida AST transformer ni import qiling. Default holatda (starter ilovada) e2e testlar konfiguratsiya fayli test papkasi ostida bo'ladi va jest-e2e.json deb nomlanadi.

JSON
1{
2  ... // other configuration
3  "globals": {
4    "ts-jest": {
5      "astTransformers": {
6        "before": ["<path to the file created above>"]
7      }
8    }
9  }
10}

Agar jest@^29 dan foydalansangiz, oldingi yondashuv eskirgan bo'lgani uchun quyidagi parcha koddan foydalaning.

JSON
1{
2  ... // other configuration
3  "transform": {
4    "^.+\\.(t|j)s$": [
5      "ts-jest",
6      {
7        "astTransformers": {
8          "before": ["<path to the file created above>"]
9        }
10      }
11    ]
12  }
13}