github icontwitter icon

Kuralları Yıkmayın: ESLint (1) - Temel

Author imageEnes Başpınar /15 Nis 2022
13 min read •––– views

Trendyol'da Mweb ekibi olarak kullandığımız ESLint kuralları, isterlerimizin tamamını kapsamıyordu ve düzensizdi. Bu kuralları derli toplu hale getirmek, kullandığımız kütüphanelere özgü pluginleri dahil etmek ve ileride özel kurallar tanımlayabilmek adına takıma özel bir plugin oluşturmaya karar verdik. Bu süreçte edindiğim deneyimleri bir yazıya dökmek istedim. İşte bu sebeple burdayız :)

Dikkat Tanım Var! Az sonra kitabi olmasa da bir tanımla karşılaşacaksınız. Tanımları hiç sevmem o yüzden çok üzerinde durmayacağım. Çok üzerinde durmadan arkalara doğru ilerleyelim. Bizim işimiz tanım ezberlemek değil, işin özüne dair fikir edinmek.

ESLint Nedir?

ESLint, Javascript kodlarımızın yazılış şeklini belirli kurallara göre analiz eden ve hatta düzelten bir garip araçtır. Kodlarımızı belirlediğimiz standarda göre otomatik formatlayabilir. Bu sayede takım projelerinde her satır ayrı telden çalmaz, okunması ve debug edilmesi kolaylaşır.

Bunun yanı sıra kod çalıştırmadan önce belirli bugları tespit edebilir. Örneğin aşağıdaki gibi for içinde değişkeni deklare etmeyi unutursanız ya da 100'den geriye saymayı amaçladığınız bir kodda değişkenin her döngüde artmasını söylerseniz döngü yönünün yanlış olduğuna dair sizi uyarır:


_11
// The update clause in this loop moves the variable
_11
// in the wrong direction. (for-direction)
_11
for (i = 100; i >= 0; i++) {
_11
// 'i' is not defined. (no-undef)
_11
console.log(`Sayı: ${i}`);
_11
}
_11
_11
// Hatalardan arındırılmış kod
_11
for (let i = 100; i >= 0; i--) {
_11
console.log(`Sayı: ${i}`);
_11
}

İstenmeyen durumlara karşı da tavrı nettir. Bir gün taskınızı bitirmişsinizdir arkanıza yaslanıp commit atarsınız ancak o da ne ESLint karşınızda:

Kullanacağımız Ortamın Kurulması

Yazı boyunca örnekleri sizinle birlikte kodlamak istiyorum. Bu sebeple herkesin aynı sayfada olduğundan emin olmak için ortamımızı kuralım.


_13
# istediğimiz bir dizinde klasör oluşturalım
_13
mkdir example-eslint-project && cd example-eslint-project
_13
_13
# klasörümüzü npm projesine çevirelim.
_13
npm init -y
_13
_13
# eslint paketini sadece localde çalışacağı deployment'a
_13
# dahil edilmeyeceği için devDependency olarak ekleyelim
_13
npm i eslint -D
_13
_13
# eslint konfigürasyonu yapacağımız dosyayı oluşturmak
_13
# üzere hazırlanan programı kullanalım
_13
npm init @eslint/config

=== Output:

? How would you like to use ESLint?  ✔ To check syntax and find problems ? What type of modules does your project use?  ✔ JavaScript modules (import/export) ? Which framework does your project use?  ✔ None of these ? Does your project use TypeScript?  ✔ No ? Where does your code run? >  ✔ Node ? What format do you want your config file to be in?  ✔ JavaScript

Bu komutlar sonucunda .eslintrc.js dosyası oluşturulur. Bu dosya, ESLint'i konfigüre edeceğimiz yerdir. Kurallarımızı buraya ekleyeceğiz.

İçerisine göz gezdirdiğimizde bazı ayarların otomatik oluşturulduğunu görebiliriz. extends kısmı, kural setlerini oluşturan ekibin tavsiye ettiği değerleri kullanmamızı sağlar. ESLint ekibi de bize bazı değerler önerir. Her bir kurala tek tek değer atamakla zaman kaybetmeden konfigüre etmiş oluruz. Bu sayede sadece özelleştirmek istediğimiz kuralları rules altında belirtiriz. Ancak şuan için başka hatalarla uğraşmadan senaryomuza odaklanmak adına ilgili satırı silerek diğer tüm kuralları kapatacağız.

Blog yazısı içerisinde altı noktalı metinlere denk gelirseniz üzerinde durun. Belirttiğim kısımların kod bloğundaki yerini gösterir.

.eslintrc.js

_13
module.exports = {
_13
"env": {
_13
"es2021": true,
_13
"node": true
_13
},
_13
"parserOptions": {
_13
"ecmaVersion": "latest",
_13
"sourceType": "module"
_13
},
_13
"extends": "eslint:recommended",
_13
"rules": {
_13
}
_13
}

Bu arada özel dosyasını kullanmayı tercih edeceğiz ancak oluşturmak istemezseniz package.json içerisinde eslintConfig kullanarak da konfigürasyonumuzu yapabiliriz. Ancak daha derli toplu olacağı için .eslintrc.js ile ilerlemek sağlıklıdır.

package.json

_20
{
_20
"name": "example-eslint-project",
_20
"version": "1.0.0",
_20
...
_20
"eslintConfig": {
_20
"env": {
_20
"browser": true,
_20
"es2021": true,
_20
"node": true
_20
},
_20
"parserOptions": {
_20
"ecmaVersion": "latest",
_20
"sourceType": "module"
_20
},
_20
"rules": {
_20
"semi": "error",
_20
"no-var": "error"
_20
}
_20
}
_20
}

Kuralların Tanımlanması ve Kullanılması

Toplama fonksiyonumuzu yazarak basit bir senaryo çizelim.

src/sum.js

_3
var sum = (num1, num2) => {
_3
return num1 + num2
_3
}

Fonksiyonu incelediğimizde (ne var da neyini inceleyeceğiz acaba) farkedeceğimiz (etmiş gibi yapın burdan bana dönüş yok) ilk şey var kullanımı. "Bu devirde halla kullanan kaldı mı?" dediğinizi duyar gibiyim, olur mu olur. İkincisi ise noktalı virgül kullanılmaması. Bazı insanlar sever bazı insanlar sevmez ancak otomatik formatlama hatalarının önüne geçmek için kullanmamızın yararı var. Özetlersek, noktalı virgülün daima konulmasını ve var kullanılmamasını istiyoruz.

Kuralların tam olarak nasıl çalıştıklarına serinin diğer yazılarında değineceğiz. Önce uygulanışını görelim ki anlatırken kafamızda eşleşsin.

ESLint ekibi bize built-in kurallar sağlar. Yani plugin paketlerinden, diğer yazıda bahsedeceğiz, indirmemiz gerekmeden kullanabiliriz. Senaryomuza uygun iki kurala bakalım:

  • semi kuralı, statement sonlarında noktalı virgül konulmasını zorunlu kılar ya da kullanımını engeller.
  • no-var kuralı, var yerine let ya da const kullanılmasını zorunlu kılar ya da var keyword'üne izin verir.

ESLint`e bu senaryomuzda istemediğimiz bir durumla karşılaşırsan yazılımcıyı uyar diyeceğiz. Kurallarımızı bu doğrultuda ekleyelim:

.eslintrc.js

_7
module.exports = {
_7
// ...
_7
"rules": {
_7
"semi": "error",
_7
"no-var": "error"
_7
}
_7
}

ESLint kurallara verilen değerlere göre üç farklı şekilde davranır:

  • "off" ya da 0 - kuralı kapatır
  • "warn" ya da 1 - kuralı uyarı verecek biçimde aktifleştirir
  • "error" ya da 2 - kuralı hata verecek biçimde aktifleştirir

Bazı kurallar sadece bu değeri kabul eder, bazıları ise özelleştirebilmemize imkan sağlar. Farklı kullanımlara sahip bazı örnekleri inceleyelim.

.eslintrc.js

_17
module.exports = {
_17
// ...
_17
"rules": {
_17
"no-restricted-syntax": "off",
_17
// kuralların hata değil uyarı vermesini istiyorsak 'warn' geçebiliriz.
_17
// adından belli olduğu gibi "error" aksine "warn" olarak belirtilen
_17
// kuralları düzeltme zorunluluğumuz yok.
_17
"spaced-comment": "warn",
_17
// "semi": ["error", "always"] şeklinde de yazabilirdik ve her seferinde
_17
// hata ver manasına gelirdi tahmin edebileceğimiz gibi.
_17
// varsayılan değer 'always' olduğu için yazılmadan geçilebilir.
_17
"semi": "error", // ya da ["error"]
_17
"quotes": ["error", "double"],
_17
// bazı kuralları ise options ile özelleştirebiliriz.
_17
"camelcase": ["error", { "ignoreDestructuring": true }],
_17
}
_17
}

Neyse basit senaryomuza geri dönelim. Tanımladığımız kurallarla birlikte kodumuzu analiz ederek çıktımızı görelim.


_1
npx eslint src/sum.js

=== Output:

/Users/enes.baspinar/Projects/posts-codes/example-eslint-project/src/sum.js 1:1 error Unexpected var, use let or const instead no-var 2:21 error Missing semicolon semi 3:2 error Missing semicolon semi

✖ 3 problems (3 errors, 0 warnings) 3 errors and 0 warnings potentially fixable with the --fix option.

Üç tane hata fırlattı. Bunları elle düzeltebiliriz falan filan ama neden biz uğraşalım ki? Pekala ESLint'e yaptırabiliriz. Dökümantasyona bakarsak bazı kuralların yanlarında ingiliz anahtarı olduğunu görebilirsiniz. Bu "fixable" olduğunu yani otomatik düzeltilebildiği anlamına gelir. Kullandığımız iki kural da aslında bu şekildedir.

"Fixable" olarak belirtilen kurallar --fix bayrağı eklenerek düzeltilebilir. Öncesinde kodumuza son kez bakalım.

src/sum.js

_3
var sum = (num1, num2) => {
_3
return num1 + num2
_3
}

Şimdi otomatik düzeltilmesini istediğimizi belirterek kodumuzu çalıştıralım.


_1
npx eslint src/sum.js --fix

src/sum.js dosyasına yeniden baktığımızda değiştiğini görebiliriz.

src/sum.js

_3
let sum = (num1, num2) => {
_3
return num1 + num2;
_3
};

Artık let'imiz ve noktalı virgülümüz var. Muazzam bir şey değil mi?

VSCode ESLint Eklentisi

Eski blogumu yaparken birkaç yazı takip etmiştim ama aklımı karıştıran şeyler vardı. "ESLint paketi kurduktan sonra neden bir de VSCode extension kurmamız gerekiyor? Bize tam olarak ne sağlıyor?". Siz de de oluştuysa hemen bu soruları def edelim.

Halihazırda bahsetmiş olduğumuz ESLint paketi, terminalden çalıştırdığımız komutla kodumuzu analiz eden ve uymayanları konsoldan bize bildirir. VSCode ESLint eklentisi ise arkaplanda ESLint paketini kullanır ve hataları hiçbir komut çalıştırmadan, kodu yazarken editörde görmemizi sağlar.

Hemen indirip deneyelim.

İndirdikten sonra src/sum.js dosyamızı en baştaki hale getirelim ve eklentinin yaptığı sihre odaklanalım.

Bu menüyü fareyle açmak zorunda değilsiniz klavyeden CTRL/CMD + . kombinasyonunu kullanabilirsiniz.

Peki bizim için son bir şarkı çalıp CTRL/CMD + S ile kaydettiğimizde tüm düzeltmeleri otomatik yapsa? O halde hemen VSCode ayarlarına girip bir ekleme yapalım.

Her kaydedişte düzeltme yapmasını istemeyeceğimiz durumlar olabilir. Aşağıdaki değişikliği atlayıp VSCode'a sağ tıkladığımızda çıkan menüden 'Format Document' seçeneğini kullanabilirsiniz.

settings.json

_7
{
_7
...
_7
"editor.formatOnSave": true,
_7
"editor.codeActionsOnSave": {
_7
"source.fixAll": true
_7
}
_7
}

Artık dosyayı kaydettiğimizde otomatik düzelttiğini görebiliriz.

Düzeltmeleri hızlıca uygulayıp kod yazabilecek duruma geldik. Dosya kaydetmeyi çok sık kullanacağız buna alışmak güzel bir kazanım olur. Kendimden örnek verecek olursam neredeyse her kelimeden sonra otonom bir şekilde kendimi CTRL/CMD + S yaparken buluyorum.

Kuralları Dosya ve Satır Bazlı Kapatma

Pekala artık hatamızı kollayan iki tane kuralımız. Ama bu kadar baskı(!) bazılarına çok fazla gelebilir. Hayatta hepimizin tamamen özgür hissettiği alanlar vardır. Projemizde neden olmasın? Hemen freedom.js isimli bir dosya oluşturalım ve bu dosya, özgür dünyanın(!!) projemizdeki temsili olsun, isteyen istediği kuralı göz ardı edebilsin ve istediği gibi geliştirme yapabilsin. Bunun için birkaç farklı yol kullanabiliriz:

  • dosya genelinde göz ardı etmek istiyorsak;
src/freedom.js

_5
/* eslint-disable */
_5
_5
var sum = (num1, num2) => {
_5
return num1 + num2
_5
}

  • dosyanın bir kısmında göz ardı etmek istiyorsak;
src/freedom.js

_12
/* eslint-disable */
_12
_12
var sum = (num1, num2) => {
_12
return num1 + num2
_12
}
_12
_12
/* eslint-enable */
_12
_12
// give error
_12
var sqr = (num1) => {
_12
return num1 ** 2
_12
}

  • satır bazlı göz ardı etmek istiyorsak;
src/freedom.js

_4
// eslint-disable-next-line
_4
var sqr = (num1) => {
_4
return num1 ** 2 // eslint-disable-line
_4
} // eslint-disable-line

Örnek kullanımlarda ilgili blok için tüm kuralları kapatır. Hepsini değil de bazılarını kapatmak istersek ismini belirtebiliriz.


_4
// eslint-disable-next-line no-var
_4
var sqr = (num1) => {
_4
return num1 ** 2 // eslint-disable-line semi
_4
} // give 'semi' error

Özetle..

ESLint, spesifik kurallar dahilinde kodu analiz eder ve kod stilini belirli kalıplarda tutar. Böylece çok fazla kişinin çalıştığı projelerin her satırı ayrı telden çalmaz. Aynı zamanda noktalı virgül, boşluk gibi çok fazla kullandığınız stillendirmeleri otomatik formatlamak için de faydalıdır.

Her kurallarını .eslintrc.js dosyasından ya da eslintConfig alanından yönetir. Kodu ESLint'in doğru parse etmesi için ayarlamalar yapabilir ve kural tanımlayabiliriz.

.eslintrc.js

_14
module.exports = {
_14
"env": {
_14
"es2021": true,
_14
"node": true
_14
},
_14
"parserOptions": {
_14
"ecmaVersion": "latest",
_14
"sourceType": "module"
_14
},
_14
"rules": {
_14
"semi": "error",
_14
"no-var": "error"
_14
}
_14
}

VSCode ESLint eklentisiyle birlikte kurallara uymayan bölümleri editörde canlı canlı görebiliriz. Aynı zamanda otomatik formatlamayı her kaydedişte ve ya belirli tuş kombinasyonlarıyla tetikleyebiliriz.

İlk yazımız burada biter benden bu kadar. Serinin devamında çok daha fazla şaşıracağınıza taahhüt ediyorum (git commit -m "Çok daha fazla şaşıracaksınız").

Sağlıcakla kalın.

2022 © No rights are reserved.Inspired by Lee Robinson's blog.