paint-brush
Neden PNPM ve İPLİK'e İhtiyacınız Yokby@bormando

Neden PNPM ve İPLİK'e İhtiyacınız Yok

Dmitrii Bormotov9m2024/07/23
Read on Terminal Reader

npm, **Node.js** ekosistemi için varsayılan bir paket yöneticisidir. 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 hale gelir. Kararlıdır ve hızı diğer paket yöneticileriyle karşılaştırılabilir.
featured image - Neden PNPM ve İPLİK'e İhtiyacınız Yok
Dmitrii Bormotov HackerNoon profile picture
0-item

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:


  1. Önbellek olmadan bir kilit dosyası oluşturun.


  2. Mevcut kilit dosyalarından bağımlılıkları önbellek olmadan yükleyin.


  3. Bağımlılıkları genel önbellek ile mevcut kilit dosyalarından yükleyin.


İki tür önbellek vardır:


  1. Küresel.

    Genellikle kullanıcının ana dizininde saklanır (fe, ~/.yarn/berry/cache ).


  2. 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:


  1. Bağımlılıkları yönetin (kurun, kaldırın, güncelleyin)
  2. Paketleri yayınlama (özel, genel)
  3. Yerel paketlere bağlantı
  4. Ç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 ):


package-lock.json girişi


Ş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

package-lock.json oluşturun ve bağımlılıkları önbellek olmadan yükleyin


Aldı 1 dakika npm'nin bir 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

Bağımlılıkları package-lock.json'dan önbellek olmadan yükleyin


Aldı 18 saniye npm'nin herhangi bir önbellek olmadan 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

Bağımlılıkları global önbellekle package-lock.json dosyasından yükleyin


Aldı 8 saniye npm'nin global önbellek ile 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:


  1. Çalışma alanındaki tüm projeler için bağımlılıkları yükleyin.
  2. Tek bir spesifik proje için bağımlılıkları yükleyin.
  3. 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:


  1. Sıfır Kurulum ” (varsayılan) - .yarn klasörü oluşturur ve yarn.lock ve .pnp.cjs dosyalarındaki paketleri listeler.


  2. 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:


Paket bağlantıları

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

İplik ile kilit dosyaları oluşturun ve bağımlılıkları yükleyin


Aldı 16,5 saniye İpliğin bir 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

Bağımlılıkları "Sıfır Kurulum" yaklaşımıyla ve önbellek olmadan yükleyin


Aldı 11 saniye İpliğin "Sıfır Kurulum" yaklaşımıyla ve herhangi bir önbellek olmadan bağımlılıkları kurması için.


Kullanılan komut:

 yarn install --frozen-lockfile

Bağımlılıkları Global Önbellekle Mevcut Kilit Dosyalarından Yükleme


Bağımlılıkları "Sıfır Kurulum" yaklaşımı ve genel önbellek ile yükleyin


Aldı 8 saniye İpliğin “Sıfır Kurulum” yaklaşımı ve global önbellek ile bağımlılıkları kurması için.


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:


  1. Çalışma alanındaki tüm projeler için bağımlılıkları yükleyin.
  2. Tek bir spesifik proje için bağımlılıkları yükleyin.
  3. 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

pnpm-lock.yaml oluştur


Aldı 31 saniye pnpm'nin bir 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

Bağımlılıkları pnpm-lock.yaml dosyasından genel önbellek olmadan yükleyin


Aldı 16 saniye pnpm'nin 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

Bağımlılıkları pnpm-lock-yaml'dan önbellekle yükleyin


Aldı 5 saniye pnpm'nin genel önbellek ile 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:


  1. eslint ve tsc --noEmit GitHub Eylemleri işlem hatlarımda "JavaScript Yığını Yetersiz" hatası veriyor.


  2. 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! 👇😊