IlmHamroh
JavaScript Full-stack/16-qism. Frontend asboblari: npm, bundlerlar, config38/48-dars21 daqiqa
Mundarija (37)

ESLint plaginlari: typescript-eslint typed linting va React qoidalari

Qisqacha: ESLint o'zi faqat JavaScript'ni biladi; qolgani — plaginlar. typescript-eslint TypeScript'ning turlarini so'rab, tsc ko'rmaydigan xatolarni topadi (typed linting): unutilgan await, shablon satrdagi unknown, any bilan xavfli ish. React loyihasida esa hook qoidalari (eslint-plugin-react-hooks) va HMR qoidasi (eslint-plugin-react-refresh) qo'shiladi. Har plagin — aniq bir turdagi xatoga qarshi.

Bu darsda

  • typed linting nima ekanini va u qanday ishlashini tushuntira olasiz.
  • typescript-eslint to'plamlarini (recommended, recommendedTypeChecked, strictTypeChecked, stylisticTypeChecked) o'lchab tanlaysiz.
  • vazifalar ga recommendedTypeChecked ni ulaysiz va u topgan xatoni tuzatasiz.
  • React loyihasining ESLint sozlamasini o'qiy olasiz: react-hooks, react-refresh, jsx-a11y, Next plagini.
  • eslint-disable izohini sabab bilan yozasiz va keraksizini topasiz.

Oldin bilishingiz kerak: ESLint I: flat config anatomiyasi, Async kod va xatolarni tiplash, ESLint va Prettier.

1. Nega bu kerak?

O'tgan darsda eslint.config.js ni blokma-blok o'qidingiz. Unda .ts fayllar uchun alohida blok bor edi. Async kod darsida unga uchta qoida qo'shgan edik: no-floating-promises, no-misused-promises, only-throw-error. Ular turlarni biladi — Promise qaytaradigan funksiyani await siz chaqirsangiz, ushlaydi.

Sardor savol berdi: "Uchta qoida yaxshi ishladi. Shunday qoidalar yana bormi?" Bor — typescript-eslint'da turlarni biladigan qoidalar o'nlab. Ularni bittalab yozish shart emas: tayyor to'plamlar (config) bor.

Ikkinchi savol kelajakdan. 17-qismda React boshlanadi. React — sahifani komponentlardan yig'adigan kutubxona (17-qismda o'rganamiz, hozir bilish shart emas). Uning o'z qoidalari bor va ularni buzish brauzerda g'alati xatolar beradi. Bu qoidalarni ham ESLint plaginlari kuzatadi. Bugun ularning sozlamasini o'qishni o'rganamiz, 17-qismda esa ishlatamiz.

Plagin (plugin) — ESLint'ga yangi qoidalar qo'shadigan npm paket. Telefonga o'rnatiladigan ilova kabi: telefon (ESLint) bitta, ilovalar (plaginlar) har ishga alohida.

2. Typed linting: ESLint turlarni qanday biladi

2.1 Oddiy va turli qoida

Oddiy qoida faqat kodning shaklini ko'radi. no-unused-vars uchun "o'zgaruvchi e'lon qilingan, lekin o'qilmagan" — shaklning o'zi yetarli.

Turli qoidaga esa ko'proq kerak. saveOrder(total); qatori. Bu xatomi? Shakldan bilib bo'lmaydi: saveOrder oddiy funksiya bo'lsa — hammasi joyida, Promise qaytarsa — unutilgan await. Javob uchun ESLint TypeScript'dan so'rashi kerak: "saveOrder nima qaytaradi?"

Typed linting (turli lint) — ESLint qoidalari TypeScript kompilyatoridan turlar haqida ma'lumot olib ishlashi. Sxemaga qarang:

flowchart LR
  F["order.ts"] --> P["typescript-eslint<br/>parser"]
  P --> A["AST<br/>(kod shakli)"]
  P --> TS["TypeScript 6 API<br/>tsconfig.json"]
  A --> Q["qoida"]
  TS -->|"turi nima?"| Q
  Q --> N["xato yoki<br/>jimlik"]

Parser kodni ikki tomonga beradi: AST (kod shakli — JS dvigateli ichida darsidan tanish daraxt) va TypeScript dasturi. Qoida AST bo'ylab yuradi va kerak bo'lsa TypeScript'dan turni so'raydi.

2.2 projectService: tsconfig'ni o'zi topadi

TypeScript'dan so'rash uchun ESLint qaysi tsconfig.json ishlashini bilishi kerak. vazifalar dagi blok:

js
languageOptions: {
  parserOptions: {
    projectService: true,
    tsconfigRootDir: import.meta.dirname,
  },
},
Kalit Nima qiladi Sukut bo'yicha
projectService: true har fayl uchun eng yaqin tsconfig.json ni o'zi topadi (muharrirdagi TypeScript kabi) false — turlar so'ralmaydi
tsconfigRootDir qidiruv qayerdan boshlanadi; import.meta.dirname — shu config papkasi buyruq ishga tushgan papka

Eski loyihalarda o'rniga project: "./tsconfig.json" yozilgan bo'ladi. U ham ishlaydi, lekin har tsconfig'ni qo'lda sanash kerak.

Diqqat: typescript-eslint 8.71.1 TypeScript'ning dasturiy APIsini ishlatadi. TypeScript 7 da bu API hali yo'q. Shuning uchun vazifalar da ikki TypeScript turibdi: tsc — 7.0.2, ESLint uchun — @typescript/typescript6 6.0.2 (npm buyruqlari chuqur darsida npm view bilan ko'rgan <6.1.0 chegarasi).

2.3 Tuzoq: turlar topilmasa

Typed linting tsconfig qanchalik to'g'ri bo'lsa, shunchalik to'g'ri ishlaydi. Mashq loyihasida @types/node o'rnatilmagan holda readFileSync ishlatdik:

text
  16:3   error  Unsafe return of a value of type error                    @typescript-eslint/no-unsafe-return
  16:10  error  Unsafe call of a type that could not be resolved          @typescript-eslint/no-unsafe-call

"Turi aniqlab bo'lmagan narsani chaqirish xavfli". Kodda xato yo'q — TypeScript node:fs ning turini topa olmadi va readFileSync ni noma'lum deb hisobladi. @types/node o'rnatilib, tsconfig'ga "types": ["node"] yozilgach, ikki xato yo'qoldi. Qoida: no-unsafe-* xatolari to'satdan ko'paysa — avval tsconfig va @types paketlarini tekshiring.

Tekshirib ko'ring: Nega no-unused-vars tez ishlaydi, no-floating-promises esa sekinroq?

Javob

no-unused-vars faqat kod shaklini (AST) ko'radi. no-floating-promises esa har chaqiruvda TypeScript'dan "bu nima qaytaradi?" deb so'raydi. Buning uchun TypeScript butun loyihani o'qib, turlarni hisoblashi kerak. O'lchovini keyingi bo'limda ko'rasiz.

3. typescript-eslint to'plamlari

3.1 To'rt to'plam

typescript-eslint 8.71.1 (2026-10 holatiga eng yangi) bir nechta tayyor to'plam beradi. Asosiylari:

To'plam Turlarni so'raydimi Nima uchun
recommended yo'q aniq xatolar: any, ishlatilmagan o'zgaruvchi
recommendedTypeChecked ha + async, unknown, any bilan xavfli ish
strictTypeChecked ha + qat'iyroq, ba'zan bahsli qoidalar
stylisticTypeChecked ha uslub: interface yoki type, T[] yoki Array<T>

recommended 15-qismdan beri vazifalar da bor. TypeChecked li to'plamlar uning ustiga qo'shiladi. stylistic xato topmaydi — jamoa uslubini bir xil qiladi.

3.2 O'lchab tanlaymiz

Qaysi biri bizga mos? Taxmin qilmaymiz — vazifalar ning src/ papkasida har birini sinab ko'rdik. Natija:

vazifalar src/: to'plam topgan xatolar
  • recommendedTypeChecked1 ta
  • stylisticTypeChecked15 ta
  • strictTypeChecked30 ta

Manba: O'lchov: ESLint 10.12.0, typescript-eslint 8.71.1, vazifalar (16-qism, typed lint qadamidan oldin), 2026-10-07

Har to'plam nimani topdi:

To'plam Qoida Soni
strictTypeChecked restrict-template-expressions 18
no-confusing-void-expression 7
no-unnecessary-condition 3
no-meaningless-void-operator 2
stylisticTypeChecked consistent-type-definitions 9
array-type 5
prefer-for-of 1

strict dagi 18 ta topilmaning ko'pi shunday:

text
src\render.ts
  124:24  error  Invalid type "number" of template literal expression  @typescript-eslint/restrict-template-expressions

"Shablon satrdagi ifodaning turi number — ruxsat yo'q". Ya'ni `vazifa-${vazifa.id}` ham xato hisoblanadi. Son matnga to'g'ri aylanadi, bu yerda xavf yo'q. strict "son ham String() bilan yozilsin" deb talab qiladi — bu uslub tanlovi, xato emas.

Lekin strict qiziq bir joyni ham ko'rsatdi. render.ts ning 317-qatori:

text
  317:20  error  Invalid type "number | null" of template literal expression  @typescript-eslint/restrict-template-expressions

id null bo'lsa, selektor [data-id="null"] bo'ladi. Bizda bu ataylab: element topilmaydi va kod zaxira elementga o'tadi. Ammo boshqa loyihada "null" yoki "undefined" matni foydalanuvchiga chiqib qolishi mumkin. Qat'iy to'plamning qadri shunda: u bahsli joylarni ko'rsatadi, qaror esa sizda.

Kanon qarori: recommendedTypeChecked. U topgan narsa — haqiqiy xavf. strict va stylistic topganlarining ko'pi uslub, ularni tuzatish kodni yaxshilamaydi.

3.3 Narxi: vaqt

Turli qoidalar TypeScript'ni ishga tushiradi, demak, sekinroq. npx eslint . ni vazifalar da 5 martadan ishga tushirdik (Windows 11, Node 24.21.0; o'rtancha natija — mediana):

Sozlama Vaqt (mediana)
turlarsiz (recommended) 2.2 s
recommendedTypeChecked 3.1 s

Taxminan +40 %. Kichik loyihada bu sezilmaydi. Katta loyihada (minglab fayl) farq daqiqalarga yetadi — shuning uchun ba'zi jamoalar turli qoidalarni faqat CI'da ishga tushiradi. Sizda raqamlar boshqacha chiqadi: ular kompyuterga bog'liq.

Maslahat: Birinchi ishga tushirish ancha sekin bo'lishi mumkin. Bizda yangi nusxada birinchi npm run lint 45 s davom etdi: Windows fayllarni birinchi marta o'qidi va antivirus tekshirdi. Vaqtni o'lchaganda birinchi natijani hisobga olmang.

Tekshirib ko'ring: Jamoa strictTypeChecked ni yoqdi va 30 ta xato chiqdi. 18 tasi — shablon satrdagi number. Nima qilish mumkin?

Javob

Ikki yo'l bor. Birinchisi — qoidani sozlash: restrict-template-expressions ga { allowNumber: true } parametrini berish. Ikkinchisi — recommendedTypeChecked da qolish. Qoidani "jim qilish" uchun 18 joyga String() yozish kodni uzaytiradi, foydasi esa yo'q. To'plam — boshlanish nuqtasi, qonun emas.

4. Vazifalar qadami: recommendedTypeChecked

4.1 O'zgarish

Branch: chore/eslint-typed. eslint.config.js dagi turli blokda uchta alohida qoida o'rniga butun to'plam:

js
{
  // Turlarni biladigan qoidalar (typed linting, 16/#38): ESLint
  // tsconfig.json ni o'qiydi (TS 6 API orqali; tsc — TS 7).
  // recommendedTypeChecked ichida 15/#44 dagi uchtasi ham bor
  // (no-floating-promises, no-misused-promises, only-throw-error) va
  // yana: unknown/any bilan xavfli ish (no-unsafe-*), shablon
  // satrdagi obyekt (restrict-template-expressions)...
  files: ["src/**/*.ts"],
  ignores: ["**/*.d.ts"],
  extends: [tseslint.configs.recommendedTypeChecked],
  languageOptions: {
    parserOptions: {
      projectService: true,
      tsconfigRootDir: import.meta.dirname,
    },
  },
},

Nimalar o'zgardi:

  • rules dagi uchta qator o'chdi — ular to'plam ichida bor.
  • extends qo'shildi. O'tgan darsdagi extends — "shu to'plamni shu blokning files iga qo'lla".
  • ignores: ["**/*.d.ts"] — e'lon fayllari (.d.ts) kod emas, ularga qoidalar kerak emas.

4.2 ESLint nima topdi

bash
npm run lint
text

> lint
> eslint .


D:\kurs\vazifalar\src\paket.ts
  130:18  error  Invalid type "unknown" of template literal expression  @typescript-eslint/restrict-template-expressions

✖ 1 problem (1 error, 0 warnings)

Bitta xato. paket.ts — eksport faylini o'qiydigan funksiya:

ts
if (xom.versiya !== PAKET_VERSIYASI) {
  throw new VazifaXatosi(
    `Versiya ${xom.versiya} o'qilmaydi — faqat ${PAKET_VERSIYASI}.`,
    { kod: "VERSIYA" },
  );
}

xom — JSON.parse natijasi, xom.versiya ning turi unknown. unknown — "nima ekanini bilmayman". Faylda u obyekt yoki massiv bo'lsa, xabarda [object Object] chiqadi. tsc bunga indamaydi — TypeScript shablon satrga istalgan turni qo'yishga ruxsat beradi. ESLint esa so'raydi: "bu qiymatni matnga aylantirishni o'ylab ko'rdingizmi?"

Tuzatish — aylantirishni ochiq yozish:

ts
if (xom.versiya !== PAKET_VERSIYASI) {
  // versiya — unknown: shablon satrga String() bilan aniq beramiz
  // (16/#38, ESLint topdi) — xabar matni avvalgidek
  const versiya = String(xom.versiya);
  throw new VazifaXatosi(
    `Versiya ${versiya} o'qilmaydi — faqat ${PAKET_VERSIYASI}.`,
    { kod: "VERSIYA" },
  );
}

Xulq o'zgarmadi: shablon satr ichida ham xuddi String() ishlaydi. Endi esa bu kodni o'qigan odam qarorni ko'radi. npm run lint — xatosiz, npm test — 146/146.

4.3 Nechta qoida yoqilgan

Bitta fayl uchun yakuniy sozlamani ESLint o'zi chiqarib bera oladi:

bash
npx eslint --print-config src/asosiy.ts

Chiqish — uzun JSON. Undagi rules ni sanadik: jami 123 ta qoida tilga olingan, 98 tasi yoqilgan, ulardan 43 tasi typescript-eslint'niki. "Bu faylga qaysi qoida qo'llanyapti?" degan savolga eng aniq javob — shu buyruq.

Commit: chore: ESLint recommendedTypeChecked; paket.ts dagi shablon satr — keyin PR va merge, odatdagidek.

Tekshirib ko'ring: Nega tsc paket.ts dagi joyni xato demadi, ESLint esa dedi?

Javob

Ularning vazifasi har xil. tsc "turlar bir-biriga mosmi?" deb tekshiradi — shablon satrga istalgan tur qo'yish qonuniy. ESLint qoidasi esa "bu joyda xato yashirinishi mumkinmi?" deb so'raydi. Ikkalasi bir-birini to'ldiradi: npm run tip va npm run lint ikkalasi ham npm run check ichida.

5. React loyihasi uchun plaginlar

Bu bo'limni o'qish darajasida o'rganamiz. React kodi 17-qismda, hozir maqsad — sozlama faylini ko'rganda tanib olish.

5.1 Vite'ning React shablonida — Oxlint

Avval bir yangilik. Vite'ning rasmiy shabloni (create-vite 9.2.1, 2026-10) React + TypeScript loyihasini ESLint'siz yaratadi:

bash
npm create vite@9.2.1 react-shablon -- \
  --template react-ts --no-interactive

Yaratilgan package.json da "lint": "oxlint", ildizda esa .oxlintrc.json:

json
{
  "$schema": "./node_modules/oxlint/configuration_schema.json",
  "plugins": ["react", "typescript", "oxc"],
  "rules": {
    "react/rules-of-hooks": "error",
    "react/only-export-components": [
      "warn",
      { "allowConstantExport": true }
    ]
  }
}

Oxlint — Rust'da yozilgan tez linter, keyingi darsning mavzusi. E'tibor bering: qoida nomlari tanish — rules-of-hooks, only-export-components. Ular ESLint plaginlaridan ko'chirilgan. Ko'p jamoalar esa hali ESLint'da: Next.js shabloni ham, eski Vite loyihalari ham. Shuning uchun ESLint variantini bilish shart.

5.2 ESLint varianti

Vite + React + TypeScript loyihasi uchun ESLint sozlamasi:

js
// eslint.config.js — Vite + React + TypeScript loyiha uchun
import { defineConfig, globalIgnores } from "eslint/config";
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import globals from "globals";

export default defineConfig([
  globalIgnores(["dist/"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      js.configs.recommended,
      tseslint.configs.recommended,
      // Hook qoidalari va React Compiler tekshiruvlari
      reactHooks.configs.flat.recommended,
      // HMR: faylda faqat komponentlar eksport qilinsin
      reactRefresh.configs.vite,
    ],
    languageOptions: { globals: globals.browser },
  },
]);

Bu fayl haqiqatan ishlaydi: ESLint 10.12.0, eslint-plugin-react-hooks 7.1.1 va eslint-plugin-react-refresh 0.5.7 bilan sinadik. Tanish qismlar — defineConfig, globalIgnores, files, extends. Yangisi faqat ikki plagin. .tsx — ichida JSX (HTML'ga o'xshash yozuv) bor TypeScript fayl, 17-qismda ko'rasiz.

Diqqat: reactHooks.configs.recommended (flat siz) — eski formatdagi sozlama. Flat config'da reactHooks.configs.flat.recommended yoziladi. Internetdagi misollarda ikkalasi ham uchraydi.

5.3 Har plagin nimani ushlaydi

Kichik komponentda atayin uch qoidani buzdik va lint qildik. Qatorlar juda uzun — har qatorning boshiga (error/warning) va oxiridagi qoida nomiga qarang:

text
D:\kurs\react-lint\src\Taom.tsx
   7:27  error    React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?   react-hooks/rules-of-hooks
   8:3   error    React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?  react-hooks/rules-of-hooks
  10:6   warning  React Hook useEffect has missing dependencies: 'nom' and 'soni'. Either include them or remove the dependency array                                                                          react-hooks/exhaustive-deps
  14:17  error    Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components                                                               react-refresh/only-export-components

✖ 4 problems (3 errors, 1 warning)

Kodni o'qish shart emas — xabarlarning ma'nosi muhim:

Qoida Xabar ma'nosi Nega muhim
rules-of-hooks hook shart ostida chaqirildi React hook'larni tartib raqami bo'yicha eslaydi; tartib buzilsa, holat aralashadi
exhaustive-deps effekt ishlatgan qiymat ro'yxatda yo'q effekt eski qiymat bilan ishlaydi
only-export-components faylda komponentdan boshqa eksport ham bor HMR ishlamay, sahifa to'liq qayta yuklanadi

Hook — React'ning use bilan boshlanadigan maxsus funksiyasi (useState, useEffect), 17-qismda o'rganamiz. Git'dagi hook'dan farqli narsa — nomi bir xil, xolos. HMR — Vite I darsidagi "sahifani qayta yuklamay yangilash".

5.4 React Compiler qoidalari

eslint-plugin-react-hooks 7 versiyasidan boshlab recommended ichida yana o'nlab qoida bor: React Compiler (React kodini avtomatik tezlashtiradigan vosita) talablari. Ikki misol:

text
  5:3   error  Error: Cannot call setState during render
…
  6:17  error  Error: Cannot call impure function during render
…
✖ 2 problems (2 errors, 0 warnings)

Birinchisi — "chizish paytida holatni o'zgartirish cheksiz siklga olib kelishi mumkin" (set-state-in-render). Ikkinchisi — "Math.random toza funksiya emas, chizish paytida chaqirilmasin" (purity). Haqiqiy chiqishda har xato ostida kod parchasi va react.dev havolasi bor; biz ularni … bilan qisqartirdik. Bu xabarlar 17-qismda React'ni o'rganganda to'liq ma'noga ega bo'ladi.

5.5 Tuzoq: plagin ESLint 10 ni hali bilmaydi

jsx-a11y — JSX'dagi qulaylik (a11y) xatolarini ushlaydigan plagin: alt siz rasm, yorliqsiz tugma. Qulaylik 09-qismdan tanish mavzu. Uni o'rnatib ko'ramiz:

bash
npm i -D -E eslint-plugin-jsx-a11y@6.10.2

Chiqishdagi ikki qatorni toping: Found: eslint@10.12.0 (sizda bori) va peer eslint@"…" (plagin kutgani).

text
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: react-lint@1.0.0
npm error Found: eslint@10.12.0
npm error node_modules/eslint
npm error   dev eslint@"10.12.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" from eslint-plugin-jsx-a11y@6.10.2
…

"Bog'liqlik daraxtini yechib bo'lmadi: jsx-a11y 6.10.2 ESLint 3–9 ni kutadi, sizda esa 10". Bu peer xatolari darsidagi ERESOLVE ning aynan o'zi. jsx-a11y ning oxirgi versiyasi 2024-10-26 da chiqqan — ESLint 10 dan ancha oldin.

Nima qilish mumkin?

  • Kutish — plagin yangilanguncha. npm view eslint-plugin-jsx-a11y peerDependencies bilan kuzatib boring.
  • ESLint 9 da qolish — Next.js shabloni aynan shunday qiladi (keyingi bo'lim).
  • --legacy-peer-deps — majburan o'rnatish. Plagin ishlashi ham, ishlamasligi ham mumkin. Buni faqat sinab ko'rib, oqibatini bilgan holda qiling.

5.6 Next.js shabloni

create-next-app 16.4.0 yaratgan eslint.config.mjs:

js
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";

const eslintConfig = defineConfig([
  ...nextVitals,
  ...nextTs,
  // Override default ignores of eslint-config-next.
  globalIgnores([
    // Default ignores of eslint-config-next:
    ".next/**",
    "out/**",
    "build/**",
    "next-env.d.ts",
  ]),
]);

export default eslintConfig;

Bu yerda plaginlar ko'rinmaydi — ular eslint-config-next ichida yig'ilgan. npm view eslint-config-next@16.4.0 dependencies ro'yxati: eslint-plugin-react, eslint-plugin-react-hooks, eslint-plugin-jsx-a11y, eslint-plugin-import, @next/eslint-plugin-next va typescript-eslint. core-web-vitals — Core Web Vitals ko'rsatkichlariga zarar beradigan joylarni xato qiladigan variant. Shablondagi package.json da esa "eslint": "^9" — jsx-a11y sababli ESLint 10 ga hali o'tilmagan.

...nextVitals dagi uch nuqta — spread: to'plam massiv bo'lgani uchun uning elementlari ro'yxatga yoyiladi. Next.js 23-qismda.

6. Yana uch foydali plagin

6.1 Import tartibi: simple-import-sort

Katta faylda importlar aralash yoziladi: node: modullari, npm paketlari, o'z fayllaringiz. eslint-plugin-simple-import-sort 14.0.0 ularni bitta tartibga keltiradi. Mashq loyihasida:

text
   1:1   error  Run autofix to sort these imports!  simple-import-sort/imports

"Importlarni saralash uchun avtomatik tuzatishni ishga tushiring". npx eslint --fix . dan keyin:

ts
import { readFileSync } from "node:fs";
import { join } from "node:path";

import { prices, saveOrder } from "./prices.ts";

Guruhlar: avval paketlar (node: ham), bo'sh qator, keyin nisbiy importlar. Muqobil — eslint-plugin-import-x 4.17.1: u tartibdan tashqari "bunday fayl yo'q", "aylanma import" kabi xatolarni ham topadi, lekin sekinroq.

6.2 eslint-config-prettier

ESLint va Prettier darsidan bilasiz: formatni Prettier qiladi, ESLint — xatolarni. Ikkisi bir joyni turlicha talab qilsa, cheksiz "tuzatish urushi" boshlanadi. eslint-config-prettier 10.1.8 — Prettier bilan to'qnashadigan uslub qoidalarini o'chiradigan to'plam. U ro'yxat oxiriga qo'yiladi.

vazifalar ga u kerak emas. ESLint'ning uslub qoidalari (indent, semi, quotes) 8.53.0 dan beri eskirgan deb belgilangan (11.0.0 gacha qoladi) va hech bir recommended to'plamga kirmaydi. Biz ularni yoqmaganmiz. Uslub qoidali plagin (masalan, @stylistic) qo'shsangiz — kerak bo'ladi.

6.3 Next plagini

@next/eslint-plugin-next 16.4.0 — Next.js'ga xos xatolar: sahifalar orasida <a> o'rniga <Link>, rasm uchun <img> o'rniga <Image>. Yuqoridagi eslint-config-next uni o'zi ulaydi, alohida yozish shart emas.

7. eslint-disable: qoidani bir joyda o'chirish

7.1 Sabab bilan

Ba'zan qoida to'g'ri, lekin aynan shu joyda siz atayin boshqacha qilasiz. Butun qoidani o'chirmaysiz — faqat bitta qatorni:

ts
export function quickSave(total: number): void {
  /* eslint-disable-next-line
     @typescript-eslint/no-floating-promises
     -- natija kerak emas: xato saveOrder ichida yoziladi */
  saveOrder(total);
}
Izoh Ta'siri
eslint-disable-next-line qoida faqat keyingi qator
eslint-disable-line qoida shu qatorning o'zi
eslint-disable qoida … eslint-enable qoida oradagi hamma qator

-- dan keyingi matn — sabab. ESLint uni o'qimaydi, kodni sharhlaydigan odam o'qiydi. Qoida nomini doim yozing: nomsiz eslint-disable-next-line qatordagi hamma qoidani o'chiradi — keyin u yerga tushgan yangi xato ham ko'rinmaydi.

7.2 Keraksiz izohni topish

Kod o'zgaradi, izoh esa qolib ketadi. ESLint 10 buni o'zi aytadi:

text
D:\kurs\mashqlar\16\38-eslint-plaginlar\src\log.ts
  11:3  warning  Unused eslint-disable directive (no problems were reported from 'no-console')

✖ 1 problem (0 errors, 1 warning)
  0 errors and 1 warning potentially fixable with the `--fix` option.

"Ishlatilmagan eslint-disable izohi: no-console hech narsa topmadi". Bu — ogohlantirish, chiqish kodi 0. CI'da qat'iyroq bo'lishni xohlasangiz: --report-unused-disable-directives-severity=error — shunda chiqish kodi 1. --fix esa bunday izohni o'zi o'chiradi.

Tekshirib ko'ring: Malika faylning boshiga /* eslint-disable */ yozdi — "xatolar ko'p, keyin tuzataman". Nima xavfi bor?

Javob

Butun fayl uchun hamma qoida o'chdi — keyin yozilgan yangi xatolar ham ko'rinmaydi. "Keyin" ko'pincha hech qachon kelmaydi. Yaxshisi: qoidani nomi bilan va sabab bilan, faqat kerakli qatorda o'chirish yoki xatolarni bittalab tuzatish.

8. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
Unsafe call of a type that could not be resolved @types/... yo'q yoki tsconfig noto'g'ri @types paketi va "types"
ERESOLVE … peer eslint@"…^9" plagin ESLint 10 ni hali bilmaydi kutish yoki ESLint 9
You have used a rule which requires type information turli qoida, lekin projectService yo'q parserOptions.projectService: true
Unused eslint-disable directive izoh qolib ketgan o'chiring yoki --fix

Uchinchi qatorning to'liq xabari: "Siz tur ma'lumotini talab qiladigan qoidani ishlatdingiz, lekin parser'ga turlar uchun sozlama berilmagan". Odatda turli to'plam yoqilgan blokda languageOptions unutilganda chiqadi.

Yana bir chalkashlik: .js fayllarga turli qoidalar qo'llansa, ular tsconfig'da bo'lmasligi mumkin. vazifalar da shuning uchun turli blok faqat src/**/*.ts ga.

9. Mashqlar

Mashq loyihasi: kurs/mashqlar/16/38-eslint-plaginlar/. Unda package.json (ESLint 10.12.0, typescript-eslint 8.71.1, TypeScript 6.0.3, @types/node 24.19.1, simple-import-sort 14.0.0), tsconfig.json, «Vazifalar qadami» dagi kabi turli eslint.config.js va ikki fayl. src/prices.ts:

ts
// «Bahor» menyusi: narxlar (so'm)
export const prices: Record<string, number> = {
  osh: 35000,
  "lag'mon": 28000,
  manti: 30000,
};

export async function saveOrder(total: number): Promise<void> {
  await new Promise((resolve) => setTimeout(resolve, 10));
  console.log("Saqlandi:", total);
}

src/order.ts:

ts
import { readFileSync } from "node:fs";
import { prices, saveOrder } from "./prices.ts";
import { join } from "node:path";

export function orderTotal(items: string[]): number {
  return items.reduce((sum, name) => sum + (prices[name] ?? 0), 0);
}

export function checkLine(raw: unknown): string {
  return `Buyurtma: ${raw}`;
}

export async function finish(items: string[]) {
  const total = await orderTotal(items);
  saveOrder(total);
  return readFileSync(join(".", "chek.txt"), "utf8");
}

1-mashq (oson): kim nimani ko'radi

npx tsc va npx eslint . ni ishga tushiring.

  • tsc nechta xato topdi:
  • ESLint nechta xato topdi:
  • --fix bilan nechtasi tuzaladi:
Yechim
bash
npx eslint .
text

D:\kurs\mashqlar\16\38-eslint-plaginlar\src\order.ts
   1:1   error  Run autofix to sort these imports!                                                                                                                                  simple-import-sort/imports
  10:23  error  Invalid type "unknown" of template literal expression                                                                                                               @typescript-eslint/restrict-template-expressions
  14:17  error  Unexpected `await` of a non-Promise (non-"Thenable") value                                                                                                          @typescript-eslint/await-thenable
  15:3   error  Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator  @typescript-eslint/no-floating-promises

✖ 4 problems (4 errors, 0 warnings)
  1 error and 0 warnings potentially fixable with the `--fix` option.

tsc jim (chiqish kodi 0): hamma tur mos. ESLint — 4 ta, ulardan uchtasi turli qoidalar. --fix faqat importlarni saralay oladi; qolganini odam hal qiladi, chunki to'g'ri yechim ma'noga bog'liq.

2-mashq (o'rta): to'rttasini tuzating

order.ts ni shunday tuzatingki, npx eslint . jim bo'lsin. eslint-disable ishlatmang. Yordam: await-thenable — "Promise bo'lmagan narsani kutyapsiz"; no-floating-promises — "Promise ni kutmadingiz". Ular bir-biriga teskari.

Yechim
ts
import { readFileSync } from "node:fs";
import { join } from "node:path";

import { prices, saveOrder } from "./prices.ts";

export function orderTotal(items: string[]): number {
  return items.reduce((sum, name) => sum + (prices[name] ?? 0), 0);
}

export function checkLine(raw: unknown): string {
  return `Buyurtma: ${String(raw)}`;
}

export async function finish(items: string[]) {
  const total = orderTotal(items);
  await saveOrder(total);
  return readFileSync(join(".", "chek.txt"), "utf8");
}
  • Importlar — --fix.
  • orderTotal oddiy son qaytaradi — await keraksiz, olib tashlandi.
  • saveOrder Promise qaytaradi — await qo'shildi. Busiz saqlash xatosi hech qayerda ushlanmasdi.
  • unknown — String() bilan ochiq aylantirildi.

npx eslint . — chiqish yo'q, chiqish kodi 0.

3-mashq (o'rta): sabab bilan o'chirish

src/log.ts faylini yarating. Unda ikki funksiya: quickSave(total) — saveOrder ni kutmasdan chaqiradi (ataylab), double(n) — n * 2 qaytaradi. quickSave dagi xatoni qoida nomi va sabab bilan o'chiring. double ga esa keraksiz // eslint-disable-next-line no-console -- vaqtinchalik izohini qo'ying. ESLint nima deydi? Qanday bayroq bilan bu CI'ni to'xtatadi?

Yechim
ts
import { saveOrder } from "./prices.ts";

export function quickSave(total: number): void {
  /* eslint-disable-next-line
     @typescript-eslint/no-floating-promises
     -- natija kerak emas: xato saveOrder ichida yoziladi */
  saveOrder(total);
}

export function double(n: number): number {
  // eslint-disable-next-line no-console -- vaqtinchalik
  return n * 2;
}
bash
npx eslint src/log.ts \
  --report-unused-disable-directives-severity=error
text

D:\kurs\mashqlar\16\38-eslint-plaginlar\src\log.ts
  11:3  error  Unused eslint-disable directive (no problems were reported from 'no-console')

✖ 1 problem (1 error, 0 warnings)
  1 error and 0 warnings potentially fixable with the `--fix` option.

Bayroqsiz — ogohlantirish (chiqish kodi 0), bayroq bilan — xato (1). quickSave dagi izoh ishlatilgan — u haqida hech narsa demadi. Uzun izohni /* … */ ichida bir necha qatorga bo'lish mumkin, shunda qator 70 belgidan oshmaydi.

4-mashq (qiyin): Vazifalar qadami

kurs/vazifalar da «Vazifalar qadami» ni bajaring: branch chore/eslint-typed, eslint.config.js da uchta qoida o'rniga recommendedTypeChecked va ignores: ["**/*.d.ts"], paket.ts dagi tuzatish. So'ng:

  1. npm run lint dan oldin taxmin qiling: nechta xato? Keyin tekshiring.
  2. npx eslint --print-config src/asosiy.ts chiqishidan @typescript-eslint/no-floating-promises ning qiymatini toping:
  3. npm run check — hammasi o'tsin, keyin commit, PR, merge.

Yordam: --print-config da qoida darajasi son bilan yoziladi: 0 — off, 1 — warn, 2 — error.

Yechim
  1. Bitta xato — paket.ts:130:18, restrict-template-expressions (to'liq chiqish «ESLint nima topdi» bo'limida).
  2. "@typescript-eslint/no-floating-promises": [2, {…}] — 2, ya'ni error. Biz uni endi alohida yozmaymiz, lekin u to'plam orqali yoqiq.
  3. Commit:
bash
git switch -c chore/eslint-typed
git add eslint.config.js src/paket.ts
git commit -m "chore: ESLint recommendedTypeChecked; paket.ts dagi shablon satr"

npm run check — format, lint, tip va 146 ta test toza.

10. Real ishda

  • Har TypeScript loyihada typescript-eslint bor; jamoalarning ko'pi recommendedTypeChecked yoki strictTypeChecked dan boshlaydi va ba'zi qoidalarni sozlaydi.
  • React loyihasida react-hooks plagini — majburiy minimum. Hook qoidalari buzilgan kod ko'pincha "ba'zan ishlaydi" — eng qiyin topiladigan xato turi.
  • Plagin versiyalari — ESLint yangi MAJOR versiyasi chiqqanda eng ko'p muammo plaginlarda bo'ladi (jsx-a11y kabi). Yangilashdan oldin npm view <plagin> peerDependencies.
  • Kod sharhida eslint-disable izohi sababsiz bo'lsa, sharhlovchi "nega?" deb so'raydi. Sabab yozish — odat.
  • Intervyu: "typed linting nima va narxi qanday?", "rules-of-hooks nimani ushlaydi?", "eslint-config-prettier nega kerak?".

Xulosa

  • Plagin ESLint'ga yangi qoidalar qo'shadi; to'plam (configs.*) — tayyor qoidalar ro'yxati, extends bilan ulanadi.
  • Typed linting — qoidalar TypeScript'dan tur so'raydi (projectService); tsc ko'rmaydigan async va unknown xatolarini topadi, narxi — vaqt (bizda +40 %).
  • vazifalar — recommendedTypeChecked: 1 ta haqiqiy topilma, String() bilan tuzatildi; strict (30) va stylistic (15) — asosan uslub.
  • React: react-hooks (hook tartibi, effekt bog'liqliklari, Compiler qoidalari), react-refresh (HMR), jsx-a11y (qulaylik) — ESLint 10 bilan hali ERESOLVE.
  • eslint-disable-next-line qoida -- sabab; keraksiz izohni ESLint o'zi ko'rsatadi.

Keyingi dars: Biome va Oxlint: Rust asosidagi muqobillar — Vite shabloni nega ESLint o'rniga Oxlint'ni tanladi, Biome va Oxlint vazifalar da ESLint'dan necha baravar tez ishlaydi va nimani qila olmaydi.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
ESLint plaginlari: typescript-eslint typed linting va React qoidalari — IlmHamroh