Mundarija (36)
- Bu darsda
- 1. Nega bu kerak?
- 2. Linter va formatlagich
- 2.1 Ikki xil ish
- 2.2 Statik tahlil
- 3. ESLint'ni o'rnatish
- 3.1 Uch paket
- 3.2 eslint.config.js
- 3.3 Birinchi ishga tushirish
- 3.4 Chiqish kodi
- 4. Qoidalar
- 4.1 Uch daraja
- 4.2 --fix: avtomatik tuzatish
- 4.3 Qoidani bir joyda o'chirish
- 4.4 Tavsiya to'plamida yo'q, lekin foydali qoidalar
- 4.5 Funksiya o'lchovi qoidalari
- 5. Prettier JavaScript uchun
- 5.1 Tanish vosita, yangi til
- 5.2 Prettier nimani o'zgartirmaydi
- 5.3 ESLint va Prettier birga
- 6. VS Code bilan
- 7. Tekshiruv qayerda ishlaydi
- 8. Ko'p uchraydigan xatolar
- 8.1 Eski qo'llanma bo'yicha .eslintrc.json
- 8.2 Brauzer kodi uchun globals unutildi
- 8.3 "type": "module" yo'q
- 8.4 --fix ni ko'r-ko'rona ishlatish
- 8.5 Butun faylni o'chirish
- 9. Mashqlar
- 1-mashq (oson): Chiqishni o'qing
- 2-mashq (o'rta): Skriptlar
- 3-mashq (qiyin): Ikki muhit, bitta sozlama
- 4-mashq: Vazifalar qadami — ESLint va Prettier
- 10. Real ishda
- Xulosa
- Manbalar
ESLint va Prettier: JavaScript kodini avtomatik tekshirish va formatlash
Qisqacha: ESLint — kodni ishga tushirmasdan o'qib, xatoga o'xshash joylarni ko'rsatadigan linter: e'lon qilinmagan nom, ishlatilmagan o'zgaruvchi,
==. Prettier — kodning ko'rinishini bir xil qiladigan formatlagich. Ikkalasinpm install --save-devbilan loyihaga o'rnatiladi, sozlamasi faylda turadi (eslint.config.js,.prettierrc) vanpm run lint,npm run formatbilan ishlaydi. VS Code ularni yozayotgan paytingizda ko'rsatadi.
Bu darsda
- Linter va formatlagich farqini va nega ikkalasi ham kerakligini tushuntira olasiz.
- ESLint'ni o'rnatasiz,
eslint.config.js(flat config) yozasiz va uning chiqishini o'qiysiz. - Qoidalarni yoqasiz, darajasini tanlaysiz (
warn/error) va--fixnimani tuzata olishini bilasiz. - Prettier'ni JavaScript uchun sozlaysiz va ESLint bilan birga ishlatasiz.
- VS Code'ni saqlaganda formatlaydigan qilib sozlaysiz va tekshiruvni commitdan oldin ishlatish g'oyasini bilasiz.
Oldin bilishingiz kerak: HTML kod uslubi va konventsiyalar, Kengaytmalar: tanlash va xavfsizlik, npm'ga birinchi qadam, Legacy kod va texnik qarz.
1. Nega bu kerak?
Kursda bu darsga ko'p va'da bergan edik:
letvaconstdarsida — "letni o'zgartirmasangiz, ESLintconstyozing deydi";vardarsida — "varyozsangiz, darhol ogohlantiradi";evaldarsida — "kodni haqiqatan tahlil qiladigan vosita — ESLint";- Unicode regex darsida — "
\pbor regex'dauflagini eslatadigan qoida bor".
Bugun hammasini ulaymiz.
Avval bitta voqea. Sardor yangi total.js faylida buyurtma hisobini yozdi. Nomlar — Toza kod: nomlash darsidagi qoida bo'yicha inglizcha:
const prices = { plov: 35000, lagman: 28000, manti: 30000 };
function calculateTotal(order) {
let total = 0;
let discount = 0;
for (const dish of order) {
total += prices[dish];
}
return totl;
}
console.log(calculateTotal(["plov", "manti"]));Xatoni ko'rdingizmi? return totl — total emas. Node buni faqat funksiya chaqirilganda aytadi: ReferenceError: totl is not defined. Agar bu funksiya kamdan-kam ishlatiladigan tugma ortida bo'lsa — xato haftalab yashirinib yotadi va birinchi bo'lib mehmon ko'radi.
Kodni ishga tushirmasdan o'qib, bunday joylarni ko'rsatadigan dastur bor. U kodni sizdan oldin "o'qib chiqadi". Bu dars — shu haqda.
2. Linter va formatlagich
2.1 Ikki xil ish
04-qismda HTML uchun ikki vositani ishlatgan edingiz (HTML kod uslubi): Prettier HTML'ni tekislardi, html-validate esa yopilmagan teg kabi xatolarni topardi. JavaScript'da ham xuddi shu juftlik:
| Formatlagich | Linter | |
|---|---|---|
| Nimaga qaraydi | ko'rinish: bo'sh joy, qavs, qator uzunligi | mazmun: shubhali, xatoga olib boradigan kod |
| JavaScript'da | Prettier | ESLint |
| Natija | faylni qayta yozadi | ro'yxat: qator, sabab, qoida |
| Kod ma'nosi | hech qachon o'zgarmaydi | ba'zi tuzatishlar o'zgartirishi mumkin |
O'xshatish. Formatlagich — kiyimni dazmollash: kiyim o'zgarmaydi, faqat tekis bo'ladi. Linter — mashinaning texnik ko'rigi: usta tormozga, chiroqlarga qaraydi va "bu yer xavfli" deydi. Dazmollangan, lekin tormozi ishlamaydigan mashina ham, tormozi zo'r, lekin g'ijim kiyimdagi haydovchi ham — to'liq emas.
2.2 Statik tahlil
Linter (linter) — kodni ishga tushirmasdan tekshiradigan dastur. Bunday tekshiruv statik tahlil (static analysis) deyiladi: "statik" — kod harakatsiz, faqat matn sifatida o'qiladi.
ESLint kodni JS dvigateli ichida darsida ko'rgan AST'ga (kodning daraxt ko'rinishi) aylantiradi. Keyin har bir qoida (rule) daraxt bo'ylab yurib, o'z naqshini qidiradi: "e'lon qilinmagan nom", "hech qachon o'qilmaydigan o'zgaruvchi", "== ishlatilgan". Har qoida — bitta kichik dastur, ESLint'da ularning yuzdan ortig'i bor.
Statik tahlilning chegarasi ham bor. ESLint kodni ishga tushirmaydi, shuning uchun funksiyaga qaysi turdagi qiymat kelishini bilmaydi: calculateTotal("plov") ga massiv o'rniga satr berilsa, u jim. Bu muammoni keyingi darsda boshqa vosita hal qiladi.
Tekshirib ko'ring: Prettier
return totlxatosini topadimi?
Javob
Yo'q. Prettier faqat ko'rinish bilan ishlaydi: return totl; uning nazarida chiroyli yozilgan qator. Nom e'lon qilinganmi yoki yo'qmi — bu mazmun, uni linter tekshiradi.
3. ESLint'ni o'rnatish
3.1 Uch paket
Loyiha papkasida (package.json bor joyda):
npm install --save-dev --save-exact \
eslint@10.12.0 @eslint/js@10.0.1 globals@17.13.0eslint— dasturning o'zi (10.12.0 versiya).@eslint/js— ESLint jamoasi tavsiya qilgan qoidalar to'plami.globals— "qaysi muhitda qaysi global nomlar bor" ro'yxati: brauzerdadocument,localStorage, Node'daprocess.
--save-dev — npm darsidan tanish: paket faqat dasturchiga kerak, saytga yuklanmaydi. --save-exact — package.json ga ^10.12.0 emas, aynan 10.12.0 yoziladi. Jamoadagi hamma bir xil versiya bilan ishlaydi: ESLint'ning yangi versiyasi yangi qoida qo'shsa, kechagi "toza" kod bugun to'satdan "xato" bo'lib qolmaydi.
3.2 eslint.config.js
Sozlama loyiha ildizidagi eslint.config.js faylida yoziladi. U oddiy JavaScript moduli:
// eslint.config.js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
import globals from "globals";
export default defineConfig([
js.configs.recommended,
{
files: ["**/*.js"],
languageOptions: { globals: globals.node },
},
]);Qatorma-qator:
defineConfig([...])— sozlamalar massivi. Har element — bitta blok. Bu shakl flat config ("tekis sozlama") deyiladi: hamma narsa bitta ro'yxatda, bloklar tepadan pastga qo'llanadi, keyingisi oldingisini ustidan yozadi.js.configs.recommended— tavsiya etilgan qoidalar bloki. ESLint 10.12 da unda 64 ta qoida bor, hammasi aniq xatolarni ushlaydi.files— blok qaysi fayllarga tegishli.**/*.js— hamma papkadagi.jsfayllar.languageOptions.globals— bu fayllarda qaysi global nomlar "e'lon qilingan" hisoblanadi. Bizningtotal.jsNode'da ishlaydi, shuning uchunglobals.node.
package.json da "type": "module" bo'lsin — eslint.config.js import ishlatadi (ES modullar).
3.3 Birinchi ishga tushirish
npx eslint .. — "joriy papkadagi hamma fayl". Sardorning total.js i uchun haqiqiy chiqish:
...\bahor-hisob\total.js
5:7 error 'discount' is assigned a value but never used no-unused-vars
7:5 error 'total' is assigned a value but never used no-unused-vars
9:10 error 'totl' is not defined no-undef
✖ 3 problems (3 errors, 0 warnings)Birinchi qatorda — faylning to'liq yo'li (sizda boshqacha bo'ladi). Keyin har muammo bitta qatorda, to'rt ustun:
5:7— qator va ustun: 5-qator, 7-belgi.error— daraja.- Xabar — inglizcha.
- Qoida nomi —
no-unused-vars. Qoida haqida to'liq ma'lumot: eslint.org saytida shu nom bilan.
Xabarlarning tarjimasi:
'discount' is assigned a value but never used— "discount(chegirma) ga qiymat berilgan, lekin u hech qachon ishlatilmagan". Ortiqcha o'zgaruvchi — yoki unutilgan ish, yoki o'chirish kerak.'total' is assigned a value but never used— xuddi shu xabartotaluchun. Qiziq:totalishlatilyapti-ku? Yo'q — unga faqat yoziladi (+=), o'qilmaydi, chunkireturndatotlturibdi. ESLint ikkinchi xato orqali uchinchisiga ishora qilyapti.'totl' is not defined— "totle'lon qilinmagan". Aynan bizning xato.
Oxirgi qator — jami: 3 muammo, 3 ta error, 0 ta warning. Hammasi funksiyani bir marta ham chaqirmasdan topildi.
3.4 Chiqish kodi
ESLint ham chiqish kodi bilan javob beradi:
| Holat | Kod |
|---|---|
muammo yo'q yoki faqat warning |
0 |
kamida bitta error |
1 |
| ESLint'ning o'zi ishlay olmadi (sozlama yo'q, buzuq) | 2 |
Faqat ogohlantirishlar bo'lsa ham "yiqilish" kerak bo'lsa — --max-warnings 0:
ESLint found too many warnings (maximum: 0).Tarjimasi: "ESLint juda ko'p ogohlantirish topdi (ko'pi bilan: 0)". Kod — 1. Bu kelajakda tekshiruvni avtomatlashtirganda kerak bo'ladi.
Maslahat: VS Code'ga ESLint kengaytmasini Kengaytmalar darsida o'rnatgan edingiz (
dbaeumer.vscode-eslint). U hozirgacha jim edi — chunki loyihada naeslintpaketi, na sozlama bor edi. Endi ikkalasi paydo bo'ldi va kengaytma xuddi shu xatolarni kodning ostida qizil to'lqinli chiziq bilan ko'rsatadi.
4. Qoidalar
4.1 Uch daraja
Har qoidaning darajasi bor:
"off"(yoki0) — o'chiq;"warn"(1) — ogohlantirish: sariq, chiqish kodi 0;"error"(2) — xato: qizil, chiqish kodi 1.
Tavsiya etilgan to'plamdagi hamma qoida error. Boshqalarini o'zingiz yoqasiz — sozlama blokiga rules qo'shib. 08-qismdagi va'dalarni bajaramiz:
{
files: ["**/*.js"],
languageOptions: { globals: globals.node },
rules: {
"prefer-const": "error",
"no-var": "error",
eqeqeq: "warn",
},
},prefer-const— o'zgartirilmaydiganleto'rnigaconst.no-var—vartaqiqlanadi (varva nega undan voz kechildi).eqeqeq—==o'rniga===(Taqqoslash operatorlari). Bu safarwarn— farqini ko'rish uchun.
Qoida nomida - bo'lsa, kalit qo'shtirnoqda yoziladi ("no-var"), bo'lmasa — qo'shtirnoqsiz ham bo'ladi (eqeqeq). Bu oddiy obyekt qoidasi.
Endi total.js ning yangi versiyasi:
const prices = { plov: 35000, lagman: 28000, manti: 30000 };
function calculateTotal(order) {
var total = 0;
for (let dish of order) {
total += prices[dish];
}
return total;
}
let total = calculateTotal(["plov", "manti"]);
if (total == "65000") {
console.log("Hisob to'g'ri");
}Konsolda:
Hisob to'g'riKod ishlaydi. ESLint esa:
...\bahor-hisob\total.js
4:3 error Unexpected var, use let or const instead no-var
5:12 error 'dish' is never reassigned. Use 'const' instead prefer-const
11:5 error 'total' is never reassigned. Use 'const' instead prefer-const
12:11 warning Expected '===' and instead saw '==' eqeqeq
✖ 4 problems (3 errors, 1 warning)
3 errors and 0 warnings potentially fixable with the `--fix` option.Tarjimalar: "Kutilmagan var, let yoki const ishlating"; "dish qayta tayinlanmaydi. const ishlating"; "=== kutilgan edi, == uchradi". Oxirgi qator yangi: "3 ta xatoni --fix bilan tuzatish mumkin".
4.2 --fix: avtomatik tuzatish
npx eslint --fix .ESLint tuzata oladiganlarini faylning o'zida tuzatadi va qolganini ko'rsatadi:
...\bahor-hisob\total.js
12:11 warning Expected '===' and instead saw '==' eqeqeq
✖ 1 problem (0 errors, 1 warning)Fayl endi shunday:
function calculateTotal(order) {
let total = 0;
for (const dish of order) {
total += prices[dish];
}
return total;
}
const total = calculateTotal(["plov", "manti"]);
if (total == "65000") {var → let (o'zgaradi, chunki +=), let dish → const, tashqi let total → const. == esa tuzatilmadi. Nega? Chunki == → === almashtirish kodning ma'nosini o'zgartiradi:
console.log(65000 == "65000"); // true
console.log(65000 === "65000"); // falseAvtomatik === qo'yilsa, "Hisob to'g'ri" endi chiqmay qolardi. ESLint faqat ma'noni saqlaydigan tuzatishni o'zi qiladi. Ma'noni o'zgartiradiganini siz qaror qilasiz: bu yerda to'g'ri tuzatish — total === 65000 (son bilan son).
4.3 Qoidani bir joyda o'chirish
Ba'zan qoida buzilishi ataylab bo'ladi. Unda butun qoidani o'chirmaysiz — faqat bitta qatorni:
// eslint-disable-next-line eqeqeq -- API son yoki satr qaytaradi
if (response.count == 6) {eslint-disable-next-line — "keyingi qatorda shu qoidani tekshirma". -- dan keyingi matn — sabab: kodni o'qigan odam nega istisno qilinganini biladi. Sababsiz istisno — kichik texnik qarz.
Izoh keraksiz bo'lib qolsa (qator tuzatildi, lekin izoh qoldi), ESLint buni ham aytadi:
4:1 warning Unused eslint-disable directive (no problems were reported from 'no-var')Tarjimasi: "Ishlatilmagan eslint-disable direktivasi (no-var hech qanday muammo topmadi)".
4.4 Tavsiya to'plamida yo'q, lekin foydali qoidalar
12-qismdagi va'dalar:
rules: {
eqeqeq: "error",
"no-eval": "error",
"no-implied-eval": "error",
"no-new-func": "error",
"require-unicode-regexp": "warn",
},Bunday fayl uchun:
const formula = "35000 * 2";
console.log(eval(formula));
const multiply = new Function("a", "b", "return a * b");
setTimeout("console.log('salom')", 10);
const tag = /\p{L}+/g;
console.log(multiply(2, 3), tag);ESLint:
2:13 error `eval` can be harmful no-eval
3:18 error The Function constructor is eval no-new-func
4:1 error Implied eval. Consider passing a function instead of a string no-implied-eval
5:13 warning Use the 'u' flag require-unicode-regexpTarjimalar: "eval zararli bo'lishi mumkin"; "Function konstruktori — bu ham eval"; "Yashirin eval. Satr o'rniga funksiya bering"; "u flagini ishlating". Bu eval, new Function va with darsidagi regex bilan qidirishdan farqli. ESLint izoh ichidagi so'zni ham, massiv.with() metodini ham "topib" qo'ymaydi: u AST'ni o'qiydi.
Plagin (plugin) — ESLint'ga yangi qoidalar qo'shadigan alohida npm paket. Regex uchun chuqurroq tekshiruv — eslint-plugin-regexp plagini (Regex amaliyotda va ReDoS). Endi Microtask va macrotask darsidagi return await tuzog'i. Uni ESLint'ning o'zi emas, TypeScript uchun plagin ushlaydi: typescript-eslint, return-await qoidasi. Plaginlarni 16-qismda ulaymiz, hozir bilish shart emas.
4.5 Funksiya o'lchovi qoidalari
Toza kod: funksiyalar darsida to'rtta qoida nomini aytgan edik. Ular ham tavsiya to'plamida yo'q: "qancha ko'p — ko'p" degan chegarani jamoa o'zi tanlaydi.
| Qoida | Nimani sanaydi | Misol chegara |
|---|---|---|
max-params |
funksiya parametrlari | ["warn", 3] |
max-depth |
ichma-ich bloklar (if, for...) |
["warn", 2] |
max-lines-per-function |
funksiya qatorlari | ["warn", 20] |
no-magic-numbers |
nomsiz raqamlar | ["warn", { ignore: [0, 1] }] |
Shu to'rttasi rules da yoqilganda, bunday fayl uchun:
function createBooking(name, phone, date, time, guests) {
if (guests > 0) {
for (const seats of [2, 4, 6]) {
if (seats >= guests) {
return { name, phone, date, time, seats };
}
}
}
return null;
}
const phone = "+998 90 000 00 00";
console.log(createBooking("Ali", phone, "10-05", "19:00", 3));ESLint 10.12.0:
1:1 warning Function 'createBooking' has too many parameters (5). Maximum allowed is 3 max-params
3:26 warning No magic number: 2 no-magic-numbers
3:29 warning No magic number: 4 no-magic-numbers
3:32 warning No magic number: 6 no-magic-numbers
4:7 warning Blocks are nested too deeply (3). Maximum allowed is 2 max-depth
13:59 warning No magic number: 3 no-magic-numbers
✖ 6 problems (0 errors, 6 warnings)Tarjimalar: "createBooking da parametr juda ko'p (5), ko'pi bilan 3"; "sehrli raqam: 2"; "bloklar juda chuqur (3), ko'pi bilan 2". Funksiya 10 qator — max-lines-per-function jim. Tuzatish — funksiyalar darsidagidek: parametrlarni sozlama obyektiga yig'ish, ichki siklni alohida funksiyaga chiqarish, raqamlarga nom berish (TABLE_SIZES).
no-magic-numbers eng "shovqinli"si: sinovda files cheklanmaganida u sozlama faylining o'zidagi 3, 2, 20 ni ham sanab berdi. Shuning uchun ko'p jamoalar uni yoqmaydi yoki faqat ba'zi papkalarga yoqadi. vazifalar da bu to'rttasini yoqmaymiz: funksiyalar Toza kod: funksiyalar darsida qo'lda bo'lingan, sozlama esa tavsiya to'plamida qoladi.
Tekshirib ko'ring: Nega
--fixlet dishniconst dishga o'zgartirdi, lekin==ga tegmadi?
Javob
let → const kodning ishlashini o'zgartirmaydi: o'zgaruvchi baribir qayta tayinlanmayotgan edi. == → === esa natijani o'zgartirishi mumkin (65000 == "65000" — true, === bilan — false). ESLint ma'noni o'zgartiradigan tuzatishni o'zi qilmaydi — qaror dasturchida.
5. Prettier JavaScript uchun
5.1 Tanish vosita, yangi til
Prettier'ni HTML kod uslubi darsida sozlagansiz: .prettierrc, .prettierignore, prettier --check va --write. JavaScript uchun hammasi xuddi shunday. Faqat uni ham loyihaga aniq versiya bilan o'rnatamiz:
npm install --save-dev --save-exact prettier@3.9.9.prettierrc:
{
"printWidth": 72
}72 — kursdagi kod qatori 70 belgidan oshmasligi qoidasiga yaqin. Qolgan sozlamalar standart: qo'shtirnoq ", qator oxirida ;, ko'p qatorli ro'yxat oxirida vergul.
Mana tartibsiz yozilgan fayl (ishlaydi, lekin o'qish qiyin):
const menu=[{name:'Plov',price:35000},{name:'Manti',price:30000},
{name:"Ko'k choy",price:5000}]
function cheaperThan(limit){return menu.filter(d=>d.price<limit)
.map(d=>d.name)}
console.log( cheaperThan(31000) )Konsolda:
[ 'Manti', "Ko'k choy" ]npx prettier --write menu.js dan keyin:
const menu = [
{ name: "Plov", price: 35000 },
{ name: "Manti", price: 30000 },
{ name: "Ko'k choy", price: 5000 },
];
function cheaperThan(limit) {
return menu.filter((d) => d.price < limit).map((d) => d.name);
}
console.log(cheaperThan(31000));Konsolda:
[ 'Manti', "Ko'k choy" ]Natija bir xil — ma'no o'zgarmadi. O'zgargani: bo'sh joylar, qo'shtirnoqlar ('Plov' → "Plov"), arrow parametri qavsda ((d) =>), massiv qatorlarga bo'lindi, oxirida vergul.
5.2 Prettier nimani o'zgartirmaydi
Prettier deyarli hech narsani "sizga qoldirmaydi" — lekin ikkita istisnoni bilish foydali.
Izoh va satr bo'linmaydi. 90 belgilik izoh 90 belgiligicha qoladi: Prettier izoh ichidagi so'zlarni qayerdan bo'lishni bilmaydi. Uzun izohni o'zingiz bo'lasiz.
Obyekt qanday boshlanganini eslaydi. Bu ikki qator faqat bitta joyda farq qiladi — { dan keyin yangi qator bormi:
const a = {
price: 35000, quantity: 2 };
const b = { price: 35000,
quantity: 2 };Prettier natijasi:
const a = {
price: 35000,
quantity: 2,
};
const b = { price: 35000, quantity: 2 };{ dan keyin yangi qator bo'lsa, Prettier obyektni ko'p qatorli qoldiradi va har xususiyatni alohida qatorga qo'yadi. Bo'lmasa — sig'sa, bitta qatorga yig'adi. Obyektni yoyish yoki yig'ish uchun birinchi xususiyatni { qatoriga olib boring yoki keyingi qatorga tushiring — qolganini Prettier qiladi.
5.3 ESLint va Prettier birga
Ikki vosita bir-biriga xalaqit bermaydimi? Eski loyihalarda berardi: ESLint'da ham bo'sh joy, qo'shtirnoq haqida qoidalar (indent, quotes, semi) bor edi va Prettier bilan "tortishardi". ESLint jamoasi bu qoidalarni 8.53 versiyadan eskirgan deb belgiladi, ular tavsiya to'plamida yo'q. Shuning uchun bizning sozlamada to'qnashuv yo'q: ko'rinish — Prettier'da, mazmun — ESLint'da.
Internetda eslint-config-prettier paketiga duch kelasiz. U ESLint'ning ko'rinish qoidalarini o'chirib qo'yadi. Bu faqat boshqa birov tayyorlagan, bunday qoidalarni yoqib qo'ygan to'plamni ishlatganda kerak.
6. VS Code bilan
Ikkala kengaytma Kengaytmalar darsidan beri o'rnatilgan: Prettier (esbenp.prettier-vscode) va ESLint (dbaeumer.vscode-eslint). Loyihaga .vscode/settings.json qo'shamiz:
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}- Birinchi ikki qator tanish: saqlaganda Prettier formatlaydi.
codeActionsOnSave— saqlaganda yana bir ish: ESLint'ning--fixi."explicit"— faqatCtrl + Sni o'zingiz bosganda (avtomatik saqlashda emas).
Kengaytmalar loyihadagi node_modules dagi ESLint va Prettier'ni ishlatadi va eslint.config.js, .prettierrc ni o'qiydi. Shuning uchun muharrirda ko'rganingiz terminaldagi npm run lint bilan bir xil.
.vscode/extensions.json ga ikkala ID ni yozsangiz, loyihani ochgan hamkasbga VS Code ularni o'rnatishni taklif qiladi (Kengaytmalar darsidagi recommendations).
7. Tekshiruv qayerda ishlaydi
Vosita qancha erta ishlasa, xato shuncha arzon tuzatiladi:
flowchart LR
A["Yozasiz"] --> B["Saqlaysiz:<br/>Prettier + ESLint --fix"]
B --> C["Commit:<br/>pre-commit tekshiruvi"]
C --> D["Pull request:<br/>CI tekshiruvi"]
D --> E["main"]- Muharrirda — yozayotganingizda, darhol.
- Commitdan oldin (pre-commit) — Git har commitdan oldin skript ishga tushira oladi (hook — "ilmoq"). Unga
npm run lintqo'yilsa, xatoli kod commitga tushmaydi. Buni qulay qiladigan Husky va lint-staged vositalarini 16-qismda o'rnatamiz, hozir bilish shart emas. - Pull request'da — GitHub Actions darsidagi kabi workflow'da
npm run lintvanpm run format:check. Muharrirni sozlamagan hamkasb ham bu tekshiruvdan o'tmay qololmaydi.
Uchala qavat ham bir xil buyruqlarni ishlatadi — package.json dagi skriptlarni. Shuning uchun skriptlar loyihaning "yagona haqiqat manbai".
Tekshirib ko'ring: Muharrirda ESLint bor ekan, CI'da yana tekshirish nega kerak?
Javob
Muharrir sozlamasi har kimning kompyuterida: kimdir kengaytmani o'rnatmagan, kimdir boshqa muharrir ishlatadi, kimdir ogohlantirishga e'tibor bermagan. CI esa hamma uchun bir xil va uni chetlab o'tib bo'lmaydi: tekshiruvdan o'tmagan PR'ni birlashtirish mumkin emasligini sozlash mumkin.
8. Ko'p uchraydigan xatolar
8.1 Eski qo'llanma bo'yicha .eslintrc.json
Internetdagi ko'p maqolalar eski sozlama faylini ko'rsatadi. ESLint 10 uni o'qimaydi:
Oops! Something went wrong! :(
ESLint: 10.12.0
ESLint couldn't find an eslint.config.* file.
From ESLint v9.0.0, the default configuration file is now eslint.config.*.Tarjimasi: "ESLint eslint.config.* faylini topa olmadi. ESLint 9.0.0 dan boshlab standart sozlama fayli — eslint.config.*". Chiqish kodi — 2. Tuzatish: eslint.config.js yozing; maqola sanasiga qarang — 2024-yildan oldingi ESLint maqolalari eski formatda bo'lishi mumkin.
8.2 Brauzer kodi uchun globals unutildi
1:16 error 'document' is not defined no-undef
2:40 error 'localStorage' is not defined no-undefESLint qaysi muhitda ishlayotganingizni bilmaydi. Tuzatish: brauzer fayllari uchun blokda languageOptions: { globals: globals.browser }.
8.3 "type": "module" yo'q
package.json da "type" bo'lmasa, ESLint ishlaydi, lekin Node ogohlantiradi:
[MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///…/eslint.config.js is not specified and it doesn't parse as CommonJS.Tarjimasi: "eslint.config.js ning modul turi ko'rsatilmagan va u CommonJS sifatida o'qilmaydi". Tuzatish: package.json ga "type": "module".
8.4 --fix ni ko'r-ko'rona ishlatish
--fix dan keyin git diff bilan o'zgarishni ko'rmasdan commit qilish. Tuzatishlar xavfsiz bo'lishi kerak, lekin plaginlar ham tuzatish qo'shadi. Tuzatish: --fix → git diff → testlar → commit.
8.5 Butun faylni o'chirish
Fayl boshida /* eslint-disable */ — butun fayl tekshiruvsiz qoladi va yangi xatolar ham ko'rinmaydi. Tuzatish: faqat kerakli qatorda, qoida nomi va sababi bilan: // eslint-disable-next-line eqeqeq -- sabab.
9. Mashqlar
1-mashq (oson): Chiqishni o'qing
Quyidagi chiqishda nechta muammo bor, qaysilari faqat ogohlantirish va qaysi qatorda e'lon qilinmagan nom ishlatilgan?
...\booking.js
3:9 error 'time' is assigned a value but never used no-unused-vars
8:10 error 'guestCont' is not defined no-undef
11:35 warning Expected '===' and instead saw '==' eqeqeq
✖ 3 problems (2 errors, 1 warning)Yechim
Uchta muammo: ikkita error, bitta warning (eqeqeq, 11-qator). E'lon qilinmagan nom — 8-qatorda (guestCont, ehtimol guestCount ning xato yozilishi). Chiqish kodi — 1, chunki xato bor.
2-mashq (o'rta): Skriptlar
Sardorning bahor-hisob loyihasiga package.json skriptlarini qo'shing: lint (tekshirish), lint:fix (tuzatish), format (Prettier yozadi), format:check (Prettier faqat tekshiradi). Oxirida yana bitta skript — check: ikkala tekshiruv, hech narsani o'zgartirmasdan. U HTML kod uslubi darsidagi check ga o'xshaydi.
Yechim
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"format": "prettier --write .",
"format:check": "prettier --check .",
"check": "npm run format:check && npm run lint"
}
}check — && bilan (Exit code): Prettier tekshiruvi o'tmasa, ESLint ishga tushmaydi. Ikkala tekshiruv ham faylga tegmaydi — CI va pre-commit uchun aynan shu kerak.
3-mashq (qiyin): Ikki muhit, bitta sozlama
Loyihada ikki xil fayl bor: assets/js/ — brauzer kodi, scripts/ — Node'da ishlaydigan yordamchi skriptlar. Shu loyiha uchun eslint.config.js yozing: tavsiya to'plami hammaga, brauzer globallari faqat assets/js ga, Node globallari faqat scripts/ va sozlama faylining o'ziga, eqeqeq va no-var hammaga error.
Yechim
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
import globals from "globals";
export default defineConfig([
js.configs.recommended,
{
files: ["assets/js/**/*.js"],
languageOptions: { globals: globals.browser },
},
{
files: ["scripts/**/*.js", "*.config.js"],
languageOptions: { globals: globals.node },
},
{
rules: { eqeqeq: "error", "no-var": "error" },
},
]);Oxirgi blokda files yo'q — u hamma faylga qo'llanadi. Bloklar tartib bilan birlashadi: assets/js/page.js uchun tavsiya qoidalari + brauzer globallari + ikki qoida. scripts/ dagi faylda document yozilsa — no-undef, chunki u yerda faqat Node globallari bor.
4-mashq: Vazifalar qadami — ESLint va Prettier
vazifalar ga ikkala vositani ulaymiz va butun kodni bir marta formatlaymiz. Ilova xulqi o'zgarmaydi.
- Branch:
chore/eslint-prettier - Commit:
chore: ESLint (flat config) va Prettier qo'shildi, kod formatlandi
1. O'rnatish:
npm install --save-dev --save-exact \
eslint@10.12.0 @eslint/js@10.0.1 globals@17.13.0 prettier@3.9.92. eslint.config.js — ikki muhit: ilova brauzerda, testlar Node'da.
// eslint.config.js — "flat config": bloklar tartib bilan qo'llanadi
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
import globals from "globals";
export default defineConfig([
// ESLint tavsiya qilgan qoidalar: aniq xatolar (e'lon qilinmagan
// o'zgaruvchi, ishlatilmagan import, yetib bo'lmaydigan kod...)
js.configs.recommended,
{
// Ilova brauzerda ishlaydi: document, localStorage, fetch...
files: ["assets/js/**/*.js"],
languageOptions: { globals: globals.browser },
},
{
// Testlar va sozlamalar Node'da ishlaydi: process, console...
files: ["tekshiruv/**/*.js", "*.config.js"],
languageOptions: { globals: globals.node },
},
]);3. Prettier. .prettierrc: { "printWidth": 72 } (qolgani standart: qo'sh tirnoq, ;, trailingComma: "all" — kod allaqachon shunday edi). .prettierignore:
# Prettier faqat JavaScript'ni formatlaydi.
# HTML va CSS — kurs uslubida (masalan, <meta> "/>" siz): Prettier
# ularni o'z uslubiga o'tkazadi, buni sozlab bo'lmaydi.
*.html
*.css
# Markdown jadvallari hizalanib, qatorlar juda uzayadi
*.md
package-lock.jsonPrettier HTML'ni o'z uslubiga o'tkazadi (<meta charset="utf-8" />, <!doctype html>, har atribut alohida qatorda) — kurs HTML/CSS uslubi (04–08) saqlansin. Bu HTML kod uslubi darsidagi qoidaga mos: ikkala uslub ham to'g'ri, faqat bitta loyihada aralashmasin.
4. Skriptlar (package.json): "lint": "eslint .", "format": "prettier --write .", "format:check": "prettier --check .".
Ishga tushiring: npm run lint va npm run format:check. Nimani ko'rasiz?
Yechim
ESLint — oldin (haqiqiy chiqish; birinchi qatorda sizda to'liq yo'l bo'ladi):
tekshiruv\marshrut.test.js
31:7 error 'location' is not defined no-undef
43:5 error 'location' is not defined no-undef
50:5 error 'location' is not defined no-undef
✖ 3 problems (3 errors, 0 warnings)Ilova kodi (assets/js) — 0 muammo. Topilgan muammo testda. Node'da location yo'q: test uni globalThis.location = { href: sayt } qilib o'zi yaratadi, lekin keyin yalang location deb o'qiydi.
Test baribir o'tayotgan edi — globalThis ga yozilgan xususiyatni yalang nom bilan ham o'qish mumkin (Global obyekt va globalThis). Lekin ESLint kodni ishga tushirmaydi: Node globallari ro'yxatida location yo'q, demak uning nazarida bu e'lon qilinmagan nom. Kodni o'qigan odam ham "bu brauzerning location imi?" deb adashadi. Tuzatish — uch joyda globalThis.location.href:
globalThis.location.href = String(url);Endi o'rinbosar ekani kodning o'zidan ko'rinadi.
Prettier — oldin: prettier --check . — 11 fayl: assets/js/{api,asosiy,marshrut,paket,render}.js, tekshiruv/{api.tarmoq,api.test,holat.test,paket.test,royxat.test,saqlash.test}.js ("Code style issues found in 11 files"). .prettierignore siz birinchi urinishda — 15 fayl: yana index.html, vazifalar.css, ssenariy.md, TEXNIK-QARZ.md.
npm run format → ilova kodida 126 qator o'zgarish (+79 −47):
- asosiy.js63 qator
- api.js29 qator
- paket.js19 qator
- render.js9 qator
- marshrut.js6 qator
Manba: O'lchandi: git diff --stat, vazifalar #37 holati → npm run format (Prettier 3.9.9, printWidth 72), Node 24.21, 2026-10-05
Uch xil o'zgarish: bir qatordagi bir nechta xususiyat har biri alohida qatorga, serverdaBajar(() => {…}, () => …) argumentlari alohida qatorlarga, uzun && zanjiri qavsga. Masalan api.js da — Oldin:
return new ApiXatosi("Server javob bermadi.", {
kod: "VAQT", cause: xato,
});Keyin (Prettier):
return new ApiXatosi("Server javob bermadi.", {
kod: "VAQT",
cause: xato,
});Sabab — «Prettier nimani o'zgartirmaydi» bo'limidagi qoida: { dan keyin yangi qator bor edi, shuning uchun obyekt ko'p qatorli qoldi va har xususiyat o'z qatoriga tushdi.
Keyin: npm run lint — chiqishsiz, exit 0; npm run format:check — "All matched files use Prettier code style!"; npm test — 59/59; brauzer ssenariysi 45/45.
git switch -c chore/eslint-prettier
npm install --save-dev --save-exact \
eslint@10.12.0 @eslint/js@10.0.1 globals@17.13.0 prettier@3.9.9
# eslint.config.js, .prettierrc, .prettierignore, skriptlar
npm run lint
# marshrut.test.js: location → globalThis.location (3 joy)
npm run format
npm run lint && npm run format:check && npm test
git add .
git commit -m "chore: ESLint (flat config) va Prettier qo'shildi, \
kod formatlandi"
git push -u origin chore/eslint-prettier
gh pr create --fill
gh pr merge --mergegit add . dan oldin git status ga qarang: node_modules/ commitga tushmasin. Agar u ro'yxatda bo'lsa — .gitignore ga node_modules/ qatorini qo'shing (.gitignore). package-lock.json esa commitga kiradi: hamma aynan bir xil paketlarni oladi.
Formatlash commiti katta (126 qator), lekin ma'nosi nol. Shuning uchun u alohida commit — boshqa o'zgarish bilan aralashmaydi. Keyinchalik git blame da bu commit "shovqin" bo'lib ko'rinsa, uni .git-blame-ignore-revs fayliga yozish mumkin (Kod arxeologiyasi).
10. Real ishda
- Deyarli har bir JavaScript loyihasida
eslint.config.jsva.prettierrcbor. Jamoaga qo'shilganda birinchi ish —npm install, keyinnpm run lint: loyiha toza holatdami. - Uslub haqida bahs yo'q. "Ikki bo'sh joy yoki to'rt?", "Nuqta-vergul kerakmi?" — Prettier sozlamasida bir marta hal qilinadi. Code review'da odamlar mazmun haqida gaplashadi.
- Freymvorklar o'z qoidalarini qo'shadi. React loyihasida hook qoidalari, TypeScript'da tur qoidalari — plaginlar orqali (ESLint II: plaginlar). Sozlamani chuqur o'rganish — ESLint I: flat config anatomiyasi.
- Tezroq muqobillar paydo bo'lmoqda: Biome (formatlagich va linter birga), Oxlint — Rust'da yozilgan (Biome va Oxlint). G'oyalari xuddi shu: qoidalar, darajalar, avtomatik tuzatish.
- Intervyu: "Linter va formatlagich farqi?", "ESLint qanday xatolarni topadi?", "Jamoada kod uslubini qanday bir xil qilasiz?" — junior intervyularida ko'p so'raladi.
Xulosa
- Linter (ESLint) kodni ishga tushirmasdan o'qib, xatoga o'xshash joylarni topadi; formatlagich (Prettier) faqat ko'rinishni tekislaydi. Ikkalasi bir-birini to'ldiradi.
- ESLint sozlamasi —
eslint.config.js: bloklar massivi (flat config),files,languageOptions.globals,rules. Daraja:off,warn,error. --fixfaqat ma'noni saqlaydigan tuzatishni qiladi (let→const),==→===ni siz hal qilasiz. Istisno — bitta qatorda, sababi bilan.- Prettier izohni bo'lmaydi va obyekt
{dan keyin qanday boshlanganini eslaydi. Ko'rinish — Prettier'da, mazmun — ESLint'da. - Tekshiruv uch joyda: muharrirda (saqlaganda), commitdan oldin, pull request'da (CI). Hammasi
package.jsonskriptlari orqali.
Keyingi dars: JSDoc va // @ts-check — ESLint ko'rmaydigan xatolarni, ya'ni noto'g'ri turdagi qiymatlarni izohlar orqali topishni o'rganamiz.
Manbalar
- ESLint hujjatlari: "Configuration Files", "Rules Reference", "Command Line Interface" — eslint.org/docs
- ESLint blogi: "Deprecation of formatting rules" (2023-10) — eslint.org/blog
- Prettier hujjatlari: "Options", "Rationale" (obyektlar haqida) — prettier.io/docs
- VS Code ESLint kengaytmasi — marketplace.visualstudio.com (
dbaeumer.vscode-eslint)
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!