Takip et

Kullanılmayan Bağımlılıkları Bulma ve Düzeltme Rehberi

Yazılım projelerinizde biriken ve performansı düşüren kullanılmayan bağımlılıkları tespit etmenin ve temizlemenin en etkili yollarını keşfedin. Projenizi hafifletin, güvenliği artırın ve geliştirme süreçlerinizi hızlandırın. Bu rehber ile gereksiz yüklerden kurtulun!

Her geliştirici bilir ki, modern yazılım projeleri tek başına yazılmaz. Genellikle, projemize yeni özellikler katmak, tekrarlayan görevleri otomatikleştirmek veya karmaşık problemleri çözmek için üçüncü taraf kütüphanelerden ve paketlerden yararlanırız. Bu bağımlılıklar, geliştirme sürecimizi hızlandırır ve bizi tekerleği yeniden icat etmekten kurtarır. Ancak, zamanla projeler geliştikçe, mimariler değişir, özellikler eklenir ve çıkarılır. Bu dinamik süreçte, bir zamanlar kritik olan bazı bağımlılıklar artık kullanılmayabilir hale gelir.

Peki, bu “kullanılmayan bağımlılıklar” ne gibi sorunlara yol açar? İlk olarak, projenizin disk üzerindeki boyutunu ve dolayısıyla derleme veya dağıtım paketinizin boyutunu gereksiz yere artırır. Küçük bir proje için bu fark edilmeyebilirken, büyük ölçekli uygulamalarda bu durum, dağıtım sürelerini uzatabilir, sunucu depolama maliyetlerini artırabilir ve kullanıcıların indirme sürelerini uzatarak kötü bir deneyim sunabilir.

İkinci olarak, güvenlik açısından ciddi riskler barındırırlar. Kullanılmayan bir bağımlılık, projenizin kod tabanında pasif bir tehdit gibi durur. Bu kütüphanenin bilinen bir güvenlik açığı (CVE) varsa ve siz onu güncel tutmuyorsanız, potansiyel bir saldırı vektörü oluşturmuş olursunuz. Aktif olarak kullanılmayan bir kütüphanenin güvenlik yamalarını takip etmek veya güncellemek genellikle akla gelmez, bu da riskin fark edilmeden kalmasına neden olabilir. Böylece, projenizin genel güvenlik duruşu zayıflamış olur.

Üçüncü olarak, bakım zorluğunu artırırlar. Gereksiz bağımlılıklar, package.json, requirements.txt veya pom.xml gibi yapılandırma dosyalarını kalabalıklaştırır. Bu durum, yeni geliştiricilerin projeye adaptasyonunu zorlaştırabilir, hangi kütüphanelerin gerçekten gerekli olduğunu anlamalarını güçleştirebilir. Ayrıca, bağımlılık çakışmaları veya versiyon uyuşmazlıkları gibi sorunlar ortaya çıktığında, sorunun kaynağını bulmak daha karmaşık hale gelir çünkü gereksiz bağımlılıklar da potansiyel suçlu listesinde yer alır.

Son olarak, gereksiz bağımlılıklar uygulamanın başlangıç süresini ve çalışma zamanı performansını etkileyebilir. Özellikle dinamik yüklenen veya çalışma zamanında derlenen dillerde, her bir bağımlılık belirli bir miktar kaynak tüketir. Bu ek yük, uygulamanın genel yanıt süresini ve verimliliğini düşürebilir. Özetle, kullanılmayan bağımlılıklar sadece bir “temizlik” meselesi değil, aynı zamanda projenizin sağlığı, güvenliği ve performansını doğrudan etkileyen kritik bir konudur. Bu rehberde, bu görünmez yüklerden nasıl kurtulacağımızı adım adım inceleyeceğiz.

Bağımlılık Yönetimi 101: Temel Kavramları Anlayalım mı?

Yazılım dünyasında “bağımlılık” kavramı, bir projenin düzgün çalışabilmesi için ihtiyaç duyduğu harici kod parçacıklarını ifade eder. Bu parçacıklar, genellikle kütüphaneler, modüller, paketler veya framework’ler şeklinde karşımıza çıkar. Örneğin, bir web uygulamasında HTTP isteklerini daha kolay yapmak için Axios (JavaScript), veri tabanı etkileşimleri için SQLAlchemy (Python) veya kullanıcı arayüzü bileşenleri için React (JavaScript) gibi kütüphaneleri bağımlılık olarak ekleyebiliriz. Temelde, bu bağımlılıklar, biz geliştiricilerin “tekerleği yeniden icat etme” yükünden kurtarır, DRY (Don’t Repeat Yourself) prensibini uygulamamızı sağlar ve projelerimizin daha hızlı ilerlemesine olanak tanır.

Bağımlılıklar genellikle iki ana kategoriye ayrılır: Doğrudan (Direct) Bağımlılıklar ve Geçişli (Transitive) Bağımlılıklar. Doğrudan bağımlılıklar, projenizin doğrudan kullandığı ve yapılandırma dosyanızda (package.json, requirements.txt, composer.json vb.) açıkça belirttiğiniz kütüphanelerdir. Örneğin, bir Node.js projesinde Express.js kullanıyorsanız, bu doğrudan bir bağımlılıktır. Geçişli bağımlılıklar ise, doğrudan bağımlılıklarınızın ihtiyaç duyduğu diğer kütüphanelerdir. Siz bunları doğrudan belirtmezsiniz, ancak paket yöneticisi (npm, pip, composer vb.) bunları otomatik olarak indirir ve kurar. Örneğin, Express.js’in altında çalışan bir başka kütüphane, sizin projeniz için geçişli bir bağımlılıktır.

Ayrıca, bağımlılıklar genellikle Üretim Bağımlılıkları (Production Dependencies) ve Geliştirme Bağımlılıkları (Development Dependencies) olarak da ayrılır. Üretim bağımlılıkları, uygulamanızın canlı ortamda çalışabilmesi için kesinlikle gerekli olanlardır. Geliştirme bağımlılıkları ise, sadece geliştirme, test, derleme veya linting gibi süreçlerde kullanılan ve canlı ortamda ihtiyaç duyulmayan kütüphanelerdir (örn. test framework’leri, kod formatlayıcılar, derleyiciler). Bu ayrım, genellikle paket yöneticisi yapılandırma dosyalarında belirtilir ve dağıtım boyutunu optimize etmek için önemlidir.

Peki, bu bağımlılıklar neden “kullanılmayan” hale gelir? Birincisi, bir özelliğin veya modülün projeden kaldırılması ancak o özelliğin bağımlılığının unutulmasıyla olabilir. İkincisi, bir kütüphaneden başka bir kütüphaneye geçiş yapıldığında, eski kütüphane kaldırılmayı atlanabilir. Üçüncüsü, geliştirme sırasında deneme amaçlı eklenen ancak sonradan kullanılmayan paketler listede kalabilir. Dördüncüsü, büyük ve karmaşık projelerde, farklı ekiplerin farklı bağımlılık setleri kullanması ve bu setlerin zamanla üst üste binmesi mümkündür. Son olarak, bazen bir kütüphane sadece kısaca kullanılır ve daha sonra projenin başka bir yerinde benzer işlevi gören kendi kodunuz yazılır, ancak eski kütüphane unutulur. Tüm bu senaryolar, projelerimizde gereksiz bir yük oluşmasına neden olur ve bu yükü düzenli olarak temizlemek, projemizin sağlığı için hayati öneme sahiptir.

Kullanılmayan Bağımlılıkları Tespit Etmenin Temel Yöntemleri Nelerdir?

Kullanılmayan bağımlılıkları bulmak, bazen dedektiflik yapmayı gerektirir. Neyse ki, bu süreçte bize yardımcı olabilecek hem manuel hem de otomatik yöntemler mevcut. Her iki yaklaşım da kendi içinde avantajlara ve dezavantajlara sahiptir ve genellikle en iyi sonuçlar için birlikte kullanılmaları önerilir.

Manuel İnceleme: Gözden Kaçanları Yakalama Sanatı Nasıl Geliştirilir?

Manuel inceleme, özellikle daha küçük projeler için veya otomatik araçların yetersiz kaldığı durumlarda oldukça değerli bir yöntemdir. Bu yaklaşım, temelde projenizin bağımlılık yapılandırma dosyasını ve kod tabanını elle gözden geçirmeyi içerir. İşte adım adım nasıl yapılacağı:

  1. Bağımlılık Yapılandırma Dosyalarını İnceleyin:
    • Node.js: package.json dosyasındaki dependencies ve devDependencies bölümlerini kontrol edin.
    • Python: requirements.txt veya pyproject.toml (Poetry, PDM) dosyalarını gözden geçirin.
    • PHP: composer.json dosyasındaki require ve require-dev bölümlerine bakın.
    • Java (Maven): pom.xml dosyasındaki bloğunu inceleyin.
    • Ruby: Gemfile dosyasını kontrol edin.

    Bu dosyalarda listelenen her bir paketin adını not alın.

  2. Kod Tabanında Arama Yapın: Not aldığınız her bir paket adını, projenizin tüm kod tabanında (kaynak kod dosyaları) arayın. Neredeyse tüm modern IDE’ler (VS Code, IntelliJ, PyCharm vb.) veya komut satırı araçları (grep) bu tür aramaları kolayca yapmanıza olanak tanır.
    • JavaScript/TypeScript: import React from 'react'; veya require('lodash'); gibi ifadeler arayın.
    • Python: import requests veya from flask import Flask gibi ifadeler arayın.
    • PHP: use Symfony\Component\Console\Command\Command; gibi ifadeler arayın.
    • Java: import org.springframework.boot.SpringApplication; gibi ifadeler arayın.
  3. Dolaylı Kullanımları Dikkate Alın: Bazen bir paket doğrudan import edilmez ancak bir konfigürasyon dosyası (örneğin, Webpack config, Babel config) tarafından kullanılır. Bu durumları da göz önünde bulundurmalısınız. Bir paket doğrudan çağrılmasa bile, bir framework veya başka bir bağımlılık tarafından dahili olarak kullanılıyor olabilir.

Manuel incelemenin zorlukları, özellikle büyük projelerde zaman alıcı ve hataya açık olmasıdır. İnsan gözünden kaçabilecek detaylar olabilir ve her zaman doğru kararı vermek kolay değildir. Ancak, projenizin iç yapısını derinlemesine anlamanıza yardımcı olur.

Otomatik Araçlar: Paket Yöneticilerinin Gücünden Nasıl Yararlanılır?

Otomatik araçlar, manuel incelemenin eksikliklerini gidererek, bağımlılık tespitini çok daha hızlı ve güvenilir hale getirir. Her programlama ekosisteminin kendine özgü güçlü araçları vardır:

  • Node.js/JavaScript Ekosistemi:
    • depcheck: Bu araç, package.json dosyanızdaki bağımlılıkları analiz eder ve kod tabanınızda kullanılmayanları veya eksik olanları bildirir.
    • npm-check: Bağımlılıklarınızın güncel olup olmadığını, kullanılmayanları ve hatalı olanları interaktif bir şekilde kontrol etmenizi sağlar.

    Örnek Kullanım (depcheck):

    
    npm install -g depcheck
    depcheck
            

    Bu komut, projenizin kök dizininde çalıştırıldığında kullanılmayan bağımlılıkların bir listesini verecektir.

  • Python Ekosistemi:
    • pip-autoremove: Bu araç, bir paketi kaldırdığınızda onunla birlikte gelen geçişli bağımlılıkları da otomatik olarak kaldırır. Ancak tespit için doğrudan bir araç değildir.
    • pigar: Python projenizdeki import ifadelerinden requirements.txt dosyasını otomatik olarak oluşturmaya çalışır. Mevcut requirements.txt ile karşılaştırılarak kullanılmayanlar bulunabilir.
    • vulture: Kullanılmayan Python kodunu bulan bir araçtır, bağımlılıkları doğrudan listelemez ancak kodunuzdaki ölü bağımlılık kullanımlarını bulmaya yardımcı olabilir.

    Örnek Kullanım (pip-autoremove):

    
    pip install pip-autoremove
    pip-autoremove 
            

    Bu komut, belirtilen paketi ve onun kullanılmayan bağımlılıklarını kaldırır.

  • PHP Ekosistemi:
    • php-tui/composer-unused: Composer tabanlı projelerde kullanılmayan bağımlılıkları tespit etmek için tasarlanmış özel bir araçtır.

    Örnek Kullanım (composer-unused):

    
    composer global require 'php-tui/composer-unused'
    composer unused
            

    Bu komut, projenizdeki composer.json'ı ve kod tabanınızı analiz ederek kullanılmayan paketleri listeler.

  • Java (Maven) Ekosistemi:
    • mvn dependency:analyze: Maven'ın kendi bağımlılık analizi aracıdır. Projenizdeki pom.xml dosyasını inceler ve kullanılmayan doğrudan bağımlılıkları veya eksik olanları tespit etmeye çalışır.

    Örnek Kullanım (Maven):

    
    mvn dependency:analyze
            

    Bu komut, çıktı olarak "Used undeclared dependencies" (kullanılan ama tanımlanmamış) ve "Unused declared dependencies" (tanımlanmış ama kullanılmayan) gibi bilgiler sunar.

Otomatik araçlar, genellikle manuel incelemeden çok daha hızlı ve verimli sonuçlar verir. Ancak, bazen "false positive" (yanlış pozitif) sonuçlar verebilirler. Örneğin, bir kütüphane kodda doğrudan çağrılmayabilir ancak bir konfigürasyon dosyası aracılığıyla veya dinamik olarak yüklenebilir. Bu gibi durumlarda, otomatik araçların çıktısını manuel olarak doğrulamak önemlidir. En iyi yaklaşım, bu araçları bir başlangıç noktası olarak kullanmak ve ardından tespit edilen bağımlılıkları dikkatlice inceleyerek nihai kararı vermektir.

Pratik Uygulama: Node.js Projesinde Kullanılmayan Bağımlılık Temizliği (Vaka Analizi)

Şimdi, öğrendiklerimizi gerçek bir senaryo üzerinde uygulayalım. Orta ölçekli bir Node.js tabanlı web uygulamasını (örneğin, eski bir Express.js projesi) ele alalım. Zamanla, bu projede çeşitli özellikler eklenip çıkarılmış, bazı bağımlılıklar güncellenmiş ancak eskileri unutulmuş durumda. Amacımız, projeyi gereksiz yüklerden arındırmak ve daha temiz bir kod tabanı elde etmek.

Adım 1: Projeyi Hazırlama ve Mevcut Durumu Gözden Geçirme

Öncelikle, projenizin bulunduğu dizine gidin ve mevcut bağımlılıklarınızı listeleyin. Bu, projenizin başlangıç durumu hakkında bir fikir edinmenizi sağlayacaktır.


cd /yol/to/your/node-project
ls -l node_modules/ # veya doğrudan package.json dosyasını açın

package.json dosyanızı açtığınızda, dependencies ve devDependencies bölümlerinde bir dizi paketin listelendiğini göreceksiniz. Örneğin:


{
  "name": "my-old-web-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.17.1",
    "mongoose": "^5.12.3",
    "body-parser": "^1.19.0",
    "lodash": "^4.17.21",
    "axios": "^0.21.1",
    "moment": "^2.29.1",
    "debug": "^4.3.1",
    "unused-package-example": "^1.0.0" // Bu paket sadece deneme amaçlı eklenmişti
  },
  "devDependencies": {
    "nodemon": "^2.0.7",
    "eslint": "^7.23.0",
    "mocha": "^8.3.2",
    "chai": "^4.3.4",
    "unnecessary-dev-tool": "^1.0.0" // Bu da deneme amaçlı eklendi
  }
}

Bu listeye bakarak, projemizde unused-package-example ve unnecessary-dev-tool adında iki şüpheli bağımlılık olduğunu varsayalım.

Adım 2: depcheck Kurulumu ve Kullanımı

Şimdi, otomatik bir araç olan depcheck'i kullanarak bu şüpheli bağımlılıkları tespit edelim. depcheck'i global olarak veya projenizin devDependencies'ına ekleyerek kullanabilirsiniz.


npm install -g depcheck # Global kurulum (tercih edilir)
# veya
npm install depcheck --save-dev # Proje bazında kurulum

Kurulum tamamlandıktan sonra, projenizin kök dizininde depcheck komutunu çalıştırın:


depcheck

Komutun çıktısı şöyle bir şey olabilir:


Unused dependencies
* unused-package-example
* moment (Moment.js, projede artık tarih işlemleri için native Date objeleri kullanılıyor olabilir.)

Unused devDependencies
* unnecessary-dev-tool

Missing dependencies
(Hiçbir eksik bağımlılık bulunamadı.)

Bu çıktı bize, unused-package-example ve moment'in üretim bağımlılıkları arasında, unnecessary-dev-tool'un ise geliştirme bağımlılıkları arasında kullanılmadığını gösteriyor.

Adım 3: Tespit Edilen Bağımlılıkları Analiz Etme (False Positives)

depcheck gibi araçlar oldukça etkilidir, ancak bazen "yanlış pozitif" (false positive) sonuçlar verebilirler. Örneğin:

  • Bir bağımlılık, kodunuzda doğrudan import edilmese de, bir konfigürasyon dosyası (örn. Webpack, Babel) tarafından dinamik olarak yükleniyor olabilir.
  • Bir kütüphane, sadece CLI komutları aracılığıyla kullanılıyor olabilir (örn. express-generator gibi bir iskelet oluşturucu).
  • Küresel olarak tanımlanmış veya HTML'de

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.