Static Testlash: Linting va Formatting
Tags: javascript, testing, webdev, programming
Published: 2023-03-28 13:04:04


### Bismillah!

> _Taxminiy o'qish vaqti: ~5 daqiqa_

Assalom Alaykum!

Dasturchi sifatida yozgan har bir kodimiz iloji boricha `clean`, `consistent` va `simple` bo'lishi kerak. Shunday bo'lsinki, 3-4 oy yoki hatto 3-4 yildan keyin ham bu kodni kim yozgan o'zi deb jig'i biyron bo'lishmasin. Bundan tashqari jamoaga yangi qo'shilgan dasturchilar uchun kodning muayyan qoida va qonuniyatlar bo'yicha yozilgani ularning tezda dastur kodiga ortiqcha qiyinchiliklarsiz hissa qo'shishlariga yordam beradi. Bu esa o'z navbatida dasturning kodiga (`codebase`) ortiqcha zo'riqishlarsiz o'sish, kengayish va unga yangi imkoniyatlarning qo'sha olishlik xususiyatlarini beradi. Har qanday muvaffaqiyatli dasturiy ta'minot (`software product or service`) bu xususiyatga ega bo'lishi shart. Bu ham aslida bir san'atdir ya'ni dasturlash sa'nati. Bu narsaga erishishda bizga katta yordam beradigan amaliyotlardan biri bu [code style](https://en.wikipedia.org/wiki/Programming_style)lardir.

> _**Code style** bu kod yozishning muayyan qoidalari/usullari bo'lib uzoq muddat davomida biron dasturlash tilida ishlash jarayonida orttirilgan tajribalar asosida tajribali dasturchilar tomonida yig'ilgan qoidalar majmuasidir._

Quyida JavaScript uchun ushbu qoidalardan namunalar keltirilgan [cheatsheet](https://javascript.info/coding-style):

![cheat sheet with some suggested rules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3xw07xnb4vwxa8d3qhpw.png)
 
Sifatli dasturiy ta'minotlarni ishlab chiqarishda bu amaliyotlarning o'rni kattadir. Quyida ushbu amaliyotlarni amalga oshirishda **frontend**da ishlatiladigan eng ommabop vositalar bilan tanishib chiqamiz. [ESLint](https://eslint.org) dastur kodini statik analiz qilish vositasi bo'lib, to'g'ri va izchil kod yozishda muayyan qoidalariga amal qilinishini ta'minlaydi. [Prettier](https://prettier.io) esa dastur kodini to'g'ri va chiroyli formatga keltirishga yordam beradi. Unit testlar haqida esa pastroqda, umumiy testlash bo'limida, bafurja gaplashamiz.

> - `Eslint & Prettier -> Clean & Consistent Code`
> - `Unit Testing -> Correct Code`

Linting va formattingni proyektimizga qo'shganimizda biz butun jamoa a'zolarini o'zaro belgilangan muayyan `coding style`ga (e.g. [airbnb](https://github.com/airbnb/javascript)) amal qilgan holda kod yozishini kutamiz. Lekin bazida gitga `push` qilayotganimizda bu qoidalar esimizdan chiqib qoladi yoki erinchoqlik qilib yoki uzoq muddat kod yozib charchab bunga amal qilmaymiz. Ba'zi jamoalarda esa bu qoidalarga deyarli amal qilinmasligini guvohi bo'lishi mumkin (ESLint o'rnatishni unda nima keragi bor?). Demak, buning oldini olish uchun har doimgidek bu amaliyotlarni avtomatlashtirish kerak. Bunga esa gitdagi `hook`lar yordamida osongina erishish mumkin, `commit` yoki `push` eventlaridan oldin o'zimiz belgilab olgan scriptlarni run qilamiz (ishga tushuramiz). Yuqoridagi amaliyotlarni avtomatlashtirish uchun bizga quyidagi vositalar kerak bo'ladi:

- [**lint-staged**](https://github.com/okonet/lint-staged)
- [**husky**](https://typicode.github.io/husky)

`lint-staged` aynan "staged" fayllar bilan ishlashga mo'ljallangan bo'lib (ya'ni proyektimizni lokal reposiga yangi qo'shilgan yoki o'zgartirilgan lekin hali `commit` qilib ulgurmagan fayllar) `linting` qilinishi kerak bo'lgan fayllarni sonini cheklaydi, bu esa ishlash jarayonini ancha tezlashtiradi (5-6 tagina o'zgartirilgan fayllar uchun minglagan fayllar ustida `linting` qilish vaqtni zoe qilishdir). `husky` esa `git`ning [hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) mexanizmi bilan ishlashni osonlashtiradi. Bizni qiziqtirgan asosiy git hook bu `pre-commit` bo'lib, kodga kiritgan o'zgartirishlarimizni lokal repoimizga `commit` qilishdan oldin, bajarilishi kerak bo'lgan amaliyotlarni (linting, testing...) `run` qilib olishimiz uchun imkon beradi.

#### Oddiy setup 
Keling ushbu vositalarni kompyuterimizga o'rnatib ko'ramiz:

```
npx mrm lint-staged
```
[mrm](https://mrm.js.org) `open source` proyektlarni konfiguratsiyalarini avtomatlashtiruvchi vosita. mrm bilan `lint-staged` va `husky` ni osongina setup qila olamiz. 
Yuqoridagi kommandani `run` qilganimizdan so'ng `.husky` degan folder proyektimizni `root` qismida hosil bo'ladi va `package.json` fayliga quyidagi qatorlar qo'shib qo'yiladi:

```json
{
  "scripts": {
    "prepare": "husky install"
  },
  "devDependencies": {
    "husky": "^6.0.0",
    "lint-staged": "^11.0.0",
  },
  "lint-staged": {
    "*.js": "eslint --cache --fix"
  }
}
```
Odatda, `mrm` o'rnatgan oddiy konfiguratsiya ko'p use caselar uchun yetarli.

![secret husky folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rth8bxpwajg821ew3et7.png)
 
`.husky` degan folderdagi `pre-commit` degan faylga qarasak, quyidagi `setup`ni ko'ramiz:

```bash
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
```
Endi esa `lint-staged`: u birozgina qo'shimcha setup talab qiladi, har bir jamoa o'zi ishlatadigan vositalarni shu buyruq orqali `run` qilishi mumkin, quyida bizni jamoa ishlatadigan konfiguratsiya misol sifatida berilgan:
```json
  "lint-staged": {
    "./src/**/*.{ts,tsx}": [
      "yarn depcheck:validate",
      "prettier --write",
      "yarn lint --fix --max-warnings 0",
      "yarn test"
    ]
  },
```
Endi esa sinab ko'ramiz:

```bash
git add .
git commit -m "JIRA-777 ushbu commitga qisqacha sharh"
```
`Commit` komandasini `run` qilishingiz bilan terminalingizda  eslint, prettier va unit testlarni ishlayotganini ko'rasiz.

![running lint-staged commands after commit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9n4iiz0wbwsfwmz27jzm.png)
 
So'ngra esa yo muvaffaqiyatli `commit` yoki biron `linting` bilan bog'liq xatolar yoki muvaffaqiyatsiz testlarni guvohi bo'lasiz (xuddi yuqoridagi skrinshotdagidek). Muvaffaqiyatli `commit`dan so'ng esa bemalol `remote repo`imizga yangi qo'shilgan o'zgarishlarni `push` qilamiz!


#### ESlint vs Prettier ziddiyati

Agar ESLintni Prettier bilan ishlatishni xohlasak (ishlatishimiz kerak ham) albatta bu ziddiyatga duch kelishimiz muqarrar ya'ni ESLintning formatlash qoidalari bilan Prettierni formatlash qoidalari albatta bir biri bilan kelishmay qoladi. 

Buning yechimi esa juda oddiy, shunchaki ESLintning formatlash bilan bog'liq qoidalarini o'chirib qo'yamiz, Prettierga o'zini ishini qilishga halaqit bermasligi uchun. Hamma o'zini ishini qilgani maqul (bu bilan Linux targ'ib qilgan dasturlash falsafasiga: [Write programs that do one thing and do it well] (https://en.wikipedia.org/wiki/Unix_philosophy) ham amal qilgan bo'lamiz). Bu maqolada buni amaliyotda qanday qilishga to'xtalib o'tirmadim, chunki bu narsa haqida allaqachon 10 lagan yaxshi maqolalar mavjud, quyida ulardan ba'zilarini keltirib o'tdim.  

- https://www.robinwieruch.de/prettier-eslint/
- https://dev.to/studio_m_song/how-to-make-eslint-work-with-prettier-avoiding-conflicts-and-problems-57pi


#### Boshqa muhim amaliyotlar

Har qanday proyektda agar unda ko'plab dasturchilar birgalikda ishlashar ekan, `code style`lardan tashqari dasturlash uchun muhim bo'lgan boshqa umumiy konvensiyalar va jarayonlarni (`semantic commits`, `git branching strategy`, `pull requests`, ...) ham kelishib olish ya'ni ish jarayonining bir qismiga aylantirish yaxshi ROI olib keladi. Muayyan proyekt ustida qancha ko'p dasturchi ishlayotgan bo'lsa, yuqorida sanab o'tilgan konvensiyalar va jarayonlarning ahamiyati shuncha ko'p bilinadi chunki ular ishtirokchilarning samarali muloqot qilishlari uchun umumiy asos yaratib beradi. Bundan tashqari, ularni sifatli qo'llash hozirgi kunda har qanday zamonaviy dasturiy ta'minot yaratishning asosi bo'lgan **CI/CD pipeline** (DevOps) o'rnatish jarayoniga katta yordam beradi. Quyidagi linklar yordamida ushbu mavzular haqida kengroq ma'lumot olsangiz bo'ladi

- https://www.conventionalcommits.org/en/v1.0.0/
- https://hungvu.tech/conventions-for-semantics-in-software-development
- https://www.flagship.io/git-branching-strategies/
- https://developer.nvidia.com/blog/benefits-of-using-pull-requests-for-collaboration-and-code-review/

#### Last but not least
> _Bu qismdagi yana eng muhim bo'lgan narsalardan biri bu `static type checking system`, [TypeScript](https://www.typescriptlang.org/) yoki [Flow](https://flow.org/) kabi, bu mavzuni o'zi ancha katta bo'lgani uchun boshqa maqolada alohida to'xtalib o'tamiz. Bunday [vositalar](https://ageek.dev/js-static-type-checkers) dasturchiga `type safety` xususiyatini ya'ni dastur kodini iloji boricha xatolardan holi va barqaror bo'lishini (`stable`) ta'minlab beradi. Bundan tashqari, ushbu vositalar `IDE`lar bilan birgalikda_
- **_error highlighting_**
- _**autocomplete**_
- _**automated refactoring**_
- _**auto-documentation**_

> _kabi **DX** (`developer experience`) ni oshiradigan qulayliklarni ham taqdim etadi._