Asılılıq cəhənnəmi — paket menecerinin layihədəki kitabxanaların versiya konfliktlərini həll edə bilməməsi vəziyyətidir. Mobil inkişafda Dependency Hell xüsusilə ağrılıdır: Android-də Gradle və iOS-da CocoaPods/SPM tez-tez tranzitiv konfliktlərlə qarşılaşır. Sonatype (2024) hesabatına görə, mobil layihədə birbaşa asılılıqların orta sayı 80-i, tranzitiv asılılıqların sayı isə 400+-ı keçir, hər biri versiya uyğunluğu tələb edir.
Əsas məqamlar
Dependency Hell — asılılıqların idarə edilməsi sisteminin kitabxana versiyalarının konfliktini həll edə bilmədiyi vəziyyəti təsvir edən termin. Layihə kitabxana A-nın 1.x versiyasını və kitabxana B-nin 2.x versiyasını tələb edir, lakin A C-nin 1.0 versiyasından, B isə C-nin 2.0 versiyasından asılıdır və C:1.0 ilə C:2.0 uyğun deyil.
Problem paket menecerləri olan bütün ekosistemlər üçün xarakterikdir. Android — Gradle support library ilə AndroidX arasında konfliktlər. iOS — CocoaPods müxtəlif Alamofire versiyaları arasında konfliktlər. Node.js — npm peer dependency konfliktləri. Python — pip həll uğursuzluqları.
Müasir asılılıq menecerləri (npm v7+, Gradle 7+, SwiftPM) həll alqoritmlərini təkmilləşdirib, lakin yüzlərlə tranzitiv asılılıq olduqda konfliktlərin tam aradan qaldırılması mümkün deyil. Dependency Hell "qurğu xətası" kateqoriyasından "risk idarəçiliyi" kateqoriyasına keçib.
Diamond dependency — janrın klassikası. Kitabxana A D:1.0-dan, kitabxana B D:2.0-dan asılıdır. A və B birlikdə istifadə olunarsa, paket meneceri D-nin hansı versiyasını quracağına qərar verməlidir. Əksər hallarda maksimum versiya (2.0) seçilir, lakin A D:2.0 ilə uyğun deyilsə — konflikt həll olunmazdır.
Versiya konflikti — tələblərin açıq uyğunsuzluğu. A Logging >=2.0 tələb edir, B Logging <2.0 tələb edir. Menecer hər iki şərti ödəyə bilmir. Peer dependency konflikti — plagin A React 17 tələb edir, lakin layihə React 18-dən breaking changes ilə istifadə edir. npm xəbərdarlıq göstərir, lakin quraşdırma keçir — davranış gözlənilməz olur.
Tranzitiv asılılıq cəhənnəmi — asılılıq birbaşa deyil, dolayı olduqda. Tərtibatçı kitabxana A-nın B-dən, B-nin isə C-dən asılı olduğunu bilmir. Gradle Dependency Tree — bütün asılılıq zəncirini vizuallaşdırmaq, konflikt edən kitabxananın haradan gəldiyini göstərmək üçün alət.
Dövri asılılıq — A B-dən, B isə A-dan asılıdır. Müasir menecerlər (Gradle, npm) dövri asılılıqları qurğu mərhələsində bloklayır. Həll — həm A, həm də B-nin asılı olduğu ümumi C modulunun ayrılması, dövrü qırmaq.
Kitabxanaların sayının artması — əsas ilkin şərt. Hər modul birbaşa və tranzitiv asılılıqlar əlavə edir. Jetpack Compose, Firebase, Retrofit və Coil ilə Android layihəsində tranzitiv asılılıqların sayı asanlıqla 500-ü keçir. Hər yeni kitabxana potensial konfliktdir.
Sinxronizasiya olunmayan yeniləmələr — komandalar kitabxanaları müxtəlif vaxtlarda yeniləyir. Backend komandası Jackson-u 2.15-ə yeniləyir, Analitika komandası 2.12 istifadə edir. Modulların inteqrasiyası zamanı konflikt yaranır. Həll — mərkəzləşdirilmiş versiyalar (Bill of Materials) Gradle BOM faylında və ya versiya kataloqunda.
Eyni kitabxananın müxtəlif versiyaları — klassik vəziyyət: modul A OkHttp 3.12 istifadə edir, modul B — OkHttp 4.0. 4.0-a yeniləmə modul A-nı pozarsa, layihə iki versiyada qalır, bu da Java-da classpath konfliktlərinə və ya iOS-da təkrarlanan simvollara səbəb ola bilər.
Gradle Dependency Tree — `gradle dependencies` əmri konfliktləri göstərən tam asılılıq ağacını çıxarır. Resolved version Gradle-in hansı versiyanı seçdiyini göstərir, konflikt versiyaları isə oxlarla qeyd olunur. Nümunə: `com.squareup.okhttp3:okhttp -> 4.9.3 (*)` — versiya həll olunub, (*) — təkrarlanma.
npm ls — Node.js üçün analoji əmr. `--all` bayrağı tam ağacı göstərir. Peer dependency konfliktləri xəbərdarlıqlarla çıxarılır. SwiftPM Graph — `swift package show-dependencies` iOS layihələri üçün asılılıq qrafikini, o cümlədən filiallar və reviziyaları göstərir.
Dependency Analysis Plugin — Autonomy-dən Gradle plaginidir, istifadə olunmayan asılılıqları və konfliktləri tapır. Ben Manes Versions Plugin — hansı asılılıqların köhnəldiyini yoxlayır və mövcud yeniləmələri göstərir. Hər iki alət rutin uyğunluq yoxlamasını avtomatlaşdırır.
// Konflikt: modul A okhttp 3.x tələb edir, modul B okhttp 4.x tələb edir
dependencies {
implementation("com.example:module-a:1.0") // → okhttp 3.12
implementation("com.example:module-b:2.0") // → okhttp 4.0
}
// Həll: konkret versiyanı məcbur et
configurations.all {
resolutionStrategy {
force "com.squareup.okhttp3:okhttp:4.9.3"
}
}
Version Catalog (Gradle 7+) — TOML faylında versiyaların mərkəzləşdirilmiş elanı. Bütün modullar eyni kitabxana versiyalarından istifadə edir. Nümunə: `libs.versions.toml` faylı `okhttp = "4.9.3"` ehtiva edir və bütün modullar bu kataloqa istinad edir. Modullar arasında versiya konflikti istisna olunur.
Bill of Materials (Spring BOM) — kitabxanaların uyğun versiyalarının təyin olunduğu Maven konsepsiyası. Google-un Android komandası Jetpack kitabxanaları üçün Compose BOM istifadə edir. BOM-u qoşmaqla bütün Compose versiyalarının bir-biri ilə uyğun olmasına zəmanət alırsınız.
Renovate və Dependabot — asılılıq yeniləmələri üçün avtomatik PR yaradıcıları. Renovate uyğun yeniləmələri qruplaşdırır, Docker obrazları vasitəsilə breaking changes yoxlayır. Dependabot — GitHub-ın daxili həlli, asılılıqları yeniləyir və CI vasitəsilə uyğunluğu yoxlayır.
Semantic Versioning — patch/minor yeniləmələri üçün caret `^1.2.3` və yalnız patch üçün tilde `~1.2.3` istifadə edin. Lakin hətta semver də uyğunluğa zəmanət vermir — real semver pozuntuları 15% hallarda baş verir (University of Luxembourg, 2024 araşdırmasına görə). Lock faylları testdən keçmiş dəqiq versiyanı təsbit edir.
Asılılıqların minimuma endirilməsi — hər kitabxana əsaslandırılmalıdır. Əgər funksionallığı öz kodunuzun 20 sətri ilə həyata keçirə bilirsinizsə — kitabxana əlavə etməyin. Nümunə: tarix formatlaşdırma kitabxanası (4 tranzitiv asılılıq) əvəzinə platformanın daxili vasitələrindən istifadə edin. "Asılılıq büdcəsi" qaydası — layihədə 50-dən çox olmayan birbaşa asılılıq.
Müntəzəm yeniləmələr — asılılıqları kiçik addımlarla yeniləyin, ildə bir dəfə yox. Dependabot hər yeniləmə üçün PR yaradır. CI tam test dəstini işə salmalıdır. DevContainer — asılılıq versiyalarının istehsala uyğun olduğu vahid inkişaf mühiti, mühitlər arasında konfliktləri aradan qaldırır.
Tez-tez verilən suallar
İlk olaraq `gradle dependencies` (Gradle), `npm ls` (Node.js) və ya `swift package show-dependencies` (SwiftPM) işə salın. Konflikt edən kitabxananı tapın. Üç həll variantı: resolutionStrategy vasitəsilə məcburi versiya, tranzitiv asılılığın istisna edilməsi (`exclude group:`) və ya konflikt edən kitabxanalardan birinin uyğun versiyaya yenilənməsi.
Version Catalog (libs.versions.toml) — bütün kitabxanaların versiyaları üçün vahid həqiqət mənbəyidir. Layihənin bütün modulları bir kataloqa istinad edir. Kitabxana yeniləndikdə versiya bir yerdə dəyişir. Bu, iki modulun eyni kitabxananın müxtəlif versiyalarını istifadə etməsi vəziyyətini istisna edir.
Tranzitiv asılılıqlar birbaşa asılılığın özü ilə gətirdiyi kitabxanalardır. Tərtibatçı çox vaxt onlar haqqında bilmir. Təhlükə: tranzitiv asılılıq digər birbaşa asılılıqla ziddiyyət təşkil edə bilər. Həll — müntəzəm olaraq asılılıq ağacını yoxlayın və minimal sayda tranzitiv asılılığı olan kitabxanaları qoşun.
Mütləq hər sprintdə yox, lakin müntəzəm olaraq — bəli. Tövsiyə: ayda bir dəfə PR yaratmaq üçün Dependabot və ya Renovate işə salın. Kritik təhlükəsizlik yamalarını bir həftə ərzində yeniləyin. Minor yeniləmələri — adı sprint çərçivəsində. Major yeniləmələr breaking changes-in ayrıca qiymətləndirilməsini tələb edir.
Dəstəklənməyən kitabxana təhlükəsizlik və uyğunluq riskidir. Strategiya: aktiv icması olan alternativ tapın (GitHub ulduzları, son commit tarixi), abstraksiya (Interface/Protocol) vasitəsilə miqrasiyanı planlaşdırın, kitabxananı 2-3 sprint ərzində dəyişdirin. Alternativ yoxdursa — depozitoriyanı fork edin və versiyanı komanda daxilində dəstəkləyin.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun