Herkese merhaba!
Eminim farklı paket yöneticileri kullanan Node.js projelerini görmüşsünüzdür, örneğin:
Bunu kendim gördüm ve yukarıdakilerin hepsiyle çalıştım, ancak aklımda her zaman bir soru vardı: İnsanları/ekipleri npm yerine iplik veya pnpm kullanmaya iten şey nedir? Artıları nelerdir? Eksileri var mı?
Peki… Haydi öğrenelim!
Performans Karşılaştırma Kuralları
Npm , iplik ve pnpm'yi “hızları” açısından karşılaştırmaya karar verdim…
Aşağıda 3 önlem göreceksiniz:
Önbellek olmadan bir kilit dosyası oluşturun.
Mevcut kilit dosyalarından bağımlılıkları önbellek olmadan yükleyin.
Bağımlılıkları genel önbellek ile mevcut kilit dosyalarından yükleyin.
İki tür önbellek vardır:
Küresel.
Genellikle kullanıcının ana dizininde saklanır (fe,
~/.yarn/berry/cache
).
Yerel.
Proje dizininde saklanır (fe,
<project-dir>/.yarn
).
Deneyimlerime göre # 2 ve # 3 en yaygın kullanım durumları olsa da, her ihtimale karşı # 1'i de aldım (gerçi bu çok nadir bir durum).
Karşılaştırmalar için örnek olarak create-react-app'ten örnek bir proje kullandım.
npm
Node.js ekosistemi için varsayılan bir paket yöneticisidir; başka ne söylenebilir ki? Kurulum paketiyle birlikte gelir, yani Node.js'yi makinenize (veya Node.js'yi orada kurduysanız herhangi bir CI sağlayıcısına) yüklediğinizde temel olarak kullanıma hazır olur.
Bu bence çok büyük bir "profesyonel"; ayrıca yüklemenize gerek yok!
Orada olağanüstü bir şey yok - sadece… işe yarıyor! Ve yıllar boyunca herhangi bir büyük hata görmedim; oldukça kararlı görünüyor ve işi hallediyor.
Şu ana kadar kullandığım npm'nin özellikleri:
- Bağımlılıkları yönetin (kurun, kaldırın, güncelleyin)
- Paketleri yayınlama (özel, genel)
- Yerel paketlere bağlantı
- Çalışma alanlarını yönetin.
Bağımlılıkları Yönet
npm, bağımlılıkları proje kökünüzün node_modules
klasöründe saklar. Oldukça basit.
ℹ️ package-lock.json
listelenen paketler için kayıt defterleri hakkındaki bilgileri saklar - tek bir kapsamdan paketleriniz varsa, yani farklı kayıtlardaki @example-company
paketleriniz varsa ÇOK kullanışlı olur (örneğin - npm ve GitHub Paketleri ):
Şimdi gelin kurulum hızı açısından nasıl performans gösterdiğine bakalım…
Herhangi bir Önbellek Olmadan package-lock.json Oluştur
Aldıpackage-lock.json
oluşturması ve bağımlılıkları önbellek olmadan kurması için.
Kullanılan komut:
npm i
Bağımlılıkları package-lock.json'dan Önbellek Olmadan Yükleyin
Aldıpackage-lock.json
bağımlılıkları yüklemesi için.
Kullanılan komut:
npm ci
Bağımlılıkları package-lock.json'dan Global Önbellek ile Kurun
Aldıpackage-lock.json
bağımlılıkları yüklemesi için.
Kullanılan komut:
npm ci
Çalışma Alanlarını Yönet
Bir çalışma alanı oluşturup tüm çalışma alanı için aynı anda ve belirli projeler için bağımlılıkları ayrı ayrı yönetebildim.
Başka bir deyişle, işi herhangi bir hata/sorun olmadan halleder ve resmi belgeler oldukça basittir.
Şu ana kadar kullandığım çalışma alanı özellikleri:
- Çalışma alanındaki tüm projeler için bağımlılıkları yükleyin.
- Tek bir spesifik proje için bağımlılıkları yükleyin.
- Tüm projeler için tek bir komut dosyasını aynı anda yinelemeli olarak çalıştırın.
iplik
Açıkçası bazı iplik özelliklerini pek denemedim. Yani bazı projeler üzerinde çalışırken “bağımlılık kurma” anlamında bunu çok kullandım, o kadar.
iplik bir Node.js yükleyicisiyle birlikte gelmez, dolayısıyla onu ayrı olarak yüklemeniz gerekir. Bu, CI işlem hatlarınızda ek bir adım olacağı anlamına gelir; proje bağımlılıklarınızı kurmadan önce ipliği ayarlamanız gerekir.
Bağımlılıkları Yönet
iplik bağımlılıkları kurmak için iki yaklaşıma sahiptir:
“ Sıfır Kurulum ” (varsayılan) -
.yarn
klasörü oluşturur veyarn.lock
ve.pnp.cjs
dosyalarındaki paketleri listeler.
Normal bir tane - npm'ye benzer, bağımlılıkları
node_modules
saklar ve bunlarıyarn.lock
dosyasında listeler.
ℹ️ iplik kilit dosyaları, YALNIZCA eski (normal) kurulum yaklaşımını kullanıyorsanız listelenen tüm paketler için kayıtlarla ilgili bilgileri saklar.
⚠️ " Sıfır Kurulumun " paketleri yerel önbellekte depoladığını ve kilit dosyalarınıza bağlantılar sağladığını unutmayın:
Bağımlılıkları temiz bir ortama yüklediğiniz ve ardından bunu başka bir ortama taşımak istediğiniz bir Dockerfile veya CI işlem hattınız varsa, bu sizin için önemli olabilir (hem .yarn
klasörünü hem de yerel önbelleği kopyalamanız gerekir).
İplik için varsayılan yaklaşım artık “ Sıfır Kurulum ” olduğundan ve eski yaklaşıma göre daha iyi performansa sahip olduğundan, kıyaslamaları yalnızca bu yaklaşımla kaydedeceğiz.
Önbellek Olmadan Kilit Dosyaları Oluşturun
Aldıyarn.lock
dosyası oluşturması ve bağımlılıkları önbellek olmadan yüklemesi için.
Kullanılan komut:
yarn install
Mevcut Kilit Dosyalarından Bağımlılıkları Önbellek Olmadan Yükleme
Aldı
Kullanılan komut:
yarn install --frozen-lockfile
Bağımlılıkları Global Önbellekle Mevcut Kilit Dosyalarından Yükleme
Aldı
Kullanılan komut:
yarn install --frozen-lockfile
Çalışma Alanlarını Yönet
Tüm projeler için aynı anda ve belirli projeler için ayrı ayrı bir çalışma alanı oluşturup bağımlılıkları yönetebildim.
Şu ana kadar kullandığım çalışma alanı özellikleri:
- Çalışma alanındaki tüm projeler için bağımlılıkları yükleyin.
- Tek bir spesifik proje için bağımlılıkları yükleyin.
- Tüm projeler için tek bir komut dosyasını aynı anda yinelemeli olarak çalıştırın.
Belgeler gayet iyi ancak komut adları ve bayraklar biraz kafa karıştırıcı.
Örneğin, root ( . ) ve iç içe geçmiş b2b
projesinde test
betiğini çalıştırmak için bunu yürütmem gerekiyor:
yarn workspaces foreach -A --include '{.,b2b}' run test
Npm ile karşılaştırıldığında:
npm run test --workspace=b2b --include-workspace-root
ppmpm
pnpm şu sıralar ilgi görüyor; pek çok şirket ve açık kaynaklı proje bunu kullanıyor .
Tıpkı iplik gibi - pnpm de Node.js yükleyicisiyle birlikte gelmez, dolayısıyla onu ayrıca yüklemeniz gerekir. Bu, CI işlem hatlarınızda ek bir adım olacağı anlamına gelir; proje bağımlılıklarınızı kurmadan önce pnpm'yi ayarlamanız gerekir.
Bağımlılıkları Yönet
pnpm “ Hızlı, disk alanından tasarruf sağlayan paket yöneticisi ” olarak kabul edilir…
Aslında bağımlılıkların yerel olarak yönetilmesi açısından “disk alanının verimli olması” ifadesine katılıyorum.
Varsayılan olarak, pnpm paylaşılan bağımlılıkların kopyalarını kaldırır. pnpm, birden çok bağımlılıkta kullanılan paketler için sembolik bağlantılar oluşturur. yani, a
ve b
paketleri bağımlılık olarak c
paketini kullanıyorsa - pnpm, c
paketini tek bir kopya olarak saklayacak ve a
ve b
paketleri için sembolik bağlantılar oluşturacaktır. Bu şekilde paket yöneticisi basılı kopyalar oluşturmaz ve SSD/HDD'nizde bellek tasarrufu sağlar.
ℹ️ pnpm-lock.yaml
listelenen paketler için kayıtlarla ilgili bilgileri saklamaz.
⚠️ Pnpm'nin bazen bağımlılıkları bir proje olarak tutmak yerine global önbellekte sakladığını unutmayın.
pnpm-lock.yaml'yi Önbellek Olmadan Oluşturun
Aldıpnpm-lock.yaml
oluşturması ve bağımlılıkları önbellek olmadan yüklemesi için.
Kullanılan komut:
pnpm install
Bağımlılıkları pnpm-lock.yaml'den Global Önbellek Olmadan Yükleyin
Aldıpnpm-lock.yaml
dosyasındaki bağımlılıkları önbellek olmadan yüklemesi için.
Kullanılan komut:
pnpm i --frozen-lockfile
Bağımlılıkları Global Önbellekle Mevcut Kilit Dosyasından Yükleme
Aldıpnpm-lock.yaml
dosyasındaki bağımlılıkları yüklemesi için.
Kullanılan komut:
pnpm i --frozen-lockfile
Çalışma Alanlarını Yönet
İşte işlerin gerçekten ilginç hale geldiği yer burası…
pnpm'de çok sayıda yapılandırma seçeneği var, ancak bazı temel işlevler çalışmıyor!
Karşılaştığım birkaç hatayı gözden geçirelim:
pnpm kurulumu --filtre
Yalnızca belirli projeler için bağımlılıklar kurabilmek önemlidir; çalışma alanındaki belirli projelerle ilgili işlem hatları oluşturduğunuzda monorepos için oldukça faydalıdır.
yani, çalışma alanınızda olduğunuzu hayal edin:
- bir web uygulaması,
- arka uç sunucusu,
- test projesi (uçtan uca testler).
Bunların hepsi ayrı npm projeleri ama aynı reponun parçaları ☝️
Artık bir işlem hattının yalnızca uçtan uca testler yürütmesini istiyorsunuz. Yani yalnızca uçtan uca test bağımlılıklarına ihtiyacınız var, değil mi?
Bunu yapamazsınız - pnpm sizi tüm çalışma alanı için bağımlılıklar kurmaya zorluyor!
pnpm install --filter <project-name>
yalnızca seçilen projeler için bağımlılıkları yüklemesi gerekiyordu, ancak çalışmıyor.
Bir yıllık bir hata var ve yakın zamanda çalışmayan bir düzeltmeyle kapatıldı.
özyinelemeli kurulum=yanlış
pnpm, pnpm install
çalıştırdığınızda varsayılan olarak tüm çalışma alanı (tüm projeler) için bağımlılıkları yükler
Çalışma alanı kökünüzdeki .npmrc
dosyasında recursive-install=false
ayarını yaparsanız bu davranışı değiştirebilirsiniz.
AMA neredeyse 2 yaşında olan başka bir hatayı tanıtıyor .
paylaşılan-çalışma alanı-kilit dosyası=yanlış
pnpm varsayılan olarak bağımlılıklar listesini tek bir kilit dosyasında saklar ( npm ve iplik ile aynı).
Çalışma alanı kökünüzdeki .npmrc
dosyasında shared-workspace-lockfile=false
ayarını yaparsanız bu davranışı da değiştirebilirsiniz.
Bu, çalışma alanı özelliğini korumamıza ve belirli bir projeye yönelik bağımlılıkları yüklemek için --ignore-workspace
işaretini kullanmamıza olanak tanır.
Her neyse, bu ayar birkaç sorunu daha beraberinde getiriyor:
eslint
vetsc --noEmit
GitHub Eylemleri işlem hatlarımda "JavaScript Yığını Yetersiz" hatası veriyor.
Bağımlılıklardan bazıları genel önbellekte saklanır ve
node_modules/.pnpm
dosyasında sembolik bağlantı oluşturulur.
Performans Karşılaştırma Sonuçları
# | npm | iplik | ppmpm |
---|---|---|---|
Bir kilit dosyası oluştur | 60 saniye | 16,5 saniye | 31 saniye |
Bağımlılıkları önbellek olmadan yükleyin | 18 saniye | 11 saniye | 8 saniye |
Bağımlılıkları genel önbellekle yükleyin | 8 saniye | 8 saniye | 5 saniye |
Yukarıdaki karşılaştırmaya göre npm en yavaş paket yöneticisidir ☝️
Neyse bu sonuçları yorumlayalım…
Kilit Dosyası Oluştur
Bu nadir bir durumdur. Genellikle proje başlatıldığında bir kilit dosyası oluşturulur ve paketleri yüklediğinizde/güncellediğinizde genişler.
Bunu akılda tutarak, bir paket yöneticisi seçtiğinizde güvenebileceğiniz çok önemli bir şey gibi görünmüyor.
Bağımlılıkları Yükle
Çoğu durumda, projeleriniz belirli bir bağımlılık listesi tutar ve nadiren bir şey ekler/kaldırırsınız.
Büyük olasılıkla, zaman zaman paketlerinizin sürümlerini değiştireceksiniz; bu değişiklikler küçüktür ve geri kalan paketleri önbellekten yeniden kullanacaksınız.
Başka bir deyişle, yaygın kullanım durumu şudur: Paket kayıt defterinden yeni paketler alın ve geri kalanını önbellekten alın.
pnpm (5-8 sn), ortada iplik (8-11 sn) ile npm'den (8-18 sn) neredeyse iki kat daha hızlıdır.
Çözüm
Gerçekler
- pnpm gerçekten de "hızlı ve diski verimli kullanan" bir paket yöneticisidir - mevcut incelemede bu oldukça açık!
- pnpm çalışma alanı özelliğinde hata var ve bazı hatalar yıllardır çözülmedi.
- hem pnpm hem de iplik, CI boru hatlarında ek bir kurulum gerektirirken, npm gerektirmez.
- hem pnpm hem de iplik, paket kayıt defteri bilgilerini kilit dosyalarında saklamazken, npm bunu yapar.
Yazarın Düşünceleri
Paket yöneticisine olan gereksiniminiz "yalnızca bağımlılıkları yüklemek" kadar basitse, pnpm'nin en iyi işi yapacağını düşünüyorum.
Pnpm, kutudan çıkan bir Node.js yükleyicisiyle birlikte gelmese de, corepack veya mevcut action ile CI ardışık düzenlerinde kurulumu kolaydır.
npm'yi tercih ediyorum çünkü:
- kararlıdır (özellikle çalışma alanları),
- Node.js ile birlikte gelir ve CI hattında ek bir kurulum gerektirmez,
- paket kayıtlarını
package-lock.json
dosyasında saklar, böylece farklı kayıtlardan tek bir kapsamda bağımlılıklar yükleyebilirsiniz.
Bu artılar, iplik veya pnpm ile tasarruf edeceğim saniyelik hız ve disk alanından daha ağır basıyor.
Paket yöneticisi seçerken kriterleriniz nelerdir? Utanmayın ve aşağıdaki yorumlar bölümünde düşüncelerinizi bana bildirin! 👇😊