“Npm install” neden package-lock.json dosyasını yeniden yazıyor?


613

Yakın zamanda npm @ 5'e geçtim . Şimdi package.json'dan her şeyi içeren bir package-lock.json dosyası var . Çalıştırdığımda , bağımlılık sürümlerinin kilit dosyamdan node_modules dizinime ne yüklenmesi gerektiğini belirlemek için çekileceğini tahmin ediyorum . Garip olan şey aslında package-lock.json dosyamı değiştirip yeniden yazması .npm install

Örneğin, kilit dosyasının 2.1.6 sürümünde belirtilmiş bir dakikası vardı . Ardından, npm installkomuttan sonra sürüm 2.4.1 olarak değiştirildi . Bu bir kilit dosyasının tüm amacını yendi gibi görünüyor.

Neyi kaçırıyorum? Npm'nin kilit dosyama gerçekten saygı duymasını nasıl sağlayabilirim?


4
Bu, sorunuza cevap vermiyor, umarım bir yorum tamamdır, ancak İpliğe bir göz atın. Geçiş bizim için bir saatten az sürdü.
KayakinKoder

4
Aynı sorun ama iplik kullanımı github.com/yarnpkg/yarn/issues/570 (çok öğretici)
Yves M.

2
Aynı sorunu yaşıyorum. Ben package-lock.jsonkoştuğumda benim yenilenir npm install. Bu bir npm böcek gibi kokuyor. Kendi kayıt defterinizi kullanıyor musunuz?
HaNdTriX


@YvesM. --no-savekilit dosyasının değiştirilmesini engeller, ancak OP'nin bahsettiği aptal birinci düzey bağımlılık yükseltmesini etkilemez.
Ross Allen

Yanıtlar:


423

Güncelleme 3: Diğer cevapların da işaret ettiği gibi, npm cikomut CI bağlamında hızlı ve tekrarlanabilir yapılar elde etmenin ek yolu olarak npm 5.7.0'da eklenmiştir. Daha fazla bilgi için dokümantasyon ve npm bloguna bakın.


Güncelleme 2: Belgeleri güncelleme ve netleştirme sorunu GitHub sorunu # 18103'tür .


Güncelleştirme 1: Aşağıda açıklanan davranış npm 5.4.2'de düzeltildi: Şu anda amaçlanan davranış GitHub sayısı # 17979'da özetlenmiştir .


Orijinal cevap: # 16866package-lock.json numaralı makalede tartışıldığı gibi npm 5.1.0'daki davranışı değiştirildi . Gözlemlediğiniz davranış, görünüşte 5.1.0 sürümünden itibaren npm tarafından tasarlanmıştır.

Bu , bağımlılık için daha yeni bir sürüm bulunduğunda package.jsongeçersiz package-lock.jsonkılınabileceği anlamına gelir package.json. Bağımlılıklarınızı etkili bir şekilde sabitlemek istiyorsanız, şimdi sürümleri önek olmadan belirtmeniz gerekir; örneğin, veya 1.2.0yerine yazmanız gerekir . Daha sonra tekrarlanabilir yapıların kombinasyonu ve verimi olacaktır. Açık olmak gerekirse: artık tek başına kök seviyesi bağımlılıklarını kilitlemez!~1.2.0^1.2.0package.jsonpackage-lock.jsonpackage-lock.json

Bu tasarım kararının iyi olup olmadığı tartışmalıdır, # 17979 numaralı sorundaki GitHub'daki bu karışıklıktan kaynaklanan sürekli bir tartışma vardır . (Benim gözümde tartışmalı bir karardır; en azından isim lockartık geçerli değil.)

Bir yan not daha: değişmez paketleri desteklemeyen kayıtlar için bir kısıtlama var, örneğin paketleri npmjs.org yerine doğrudan GitHub'dan çektiğinizde. Daha fazla açıklama için paket kilitlerinin bu belgelerine bakın .


43
O zaman saldırı ne npm updateiçin? : o npm installGüncellenen deps hissettim , ama inanmak istemiyorum .. ama ne yazık ki gerçek gibi görünüyor .. Yine de npm shrinkwrapdeps kilitlemek için kullanmak için hala bir seçenek var , ama kesinlikle isim-paket kilidi yanlış
donmadığı

266
Ne dağınıklık! Dünyanın en büyük paket yöneticisi olmasına rağmen, nasıl çalışması gerektiğine dair belgeleri yok. Herkes ne yapması gerektiğini tahmin ediyor ve bu bir fikir savaşına dönüşüyor. Tartışma iyidir ancak vahşi doğaya bırakılmadan önce gerçekleşmelidir. Bir noktada birinin son çağrıyı yapması gerekir ve daha sonra uygulamaya konabilir, belgelenebilir ve serbest bırakılabilir. PHP komite tarafından tasarlandı ve bir araya getirildi ve nasıl sonuçlandığına bakın. Aynı şeyin bu kritik ve yaygın olarak kullanılan bir araçta olmasını sevmiyorum.
Landon Poch

85
Peki, paket kilidini kullanmanın anlamı nedir? Farklı çalışma alanlarında aynı ortamı yaratacağını düşündüm, ancak hiçbir şey yapmadığı ortaya çıktı
laltin

17
"Daha sonra package.json ve package-lock.json kombinasyonu yeniden üretilebilir yapılar oluşturur." Burada "package-lock.json" rolü nedir? Hiçbir sürüm öneki kullanılmazsa "package.json" tek başına yeniden üretilebilir derlemeler sağlamaz mı?
Jānis Elmeris

12
@ JānisElmeris Sanırım package.json derin bağımlılıkları kilitleyemez ...
Juan Mendes

165

Ben NPM yeni bir sürümü olacağı bulduk 5.7.1 yeni komut ile npm cigelen kuracak, package-lock.jsonsadece

Yeni npm ci komutu SADECE kilit dosyanızdan yüklenir. Package.json ve kilit dosyanız senkronize değilse, bir hata bildirir.

Düğüm_modüllerinizi atarak ve sıfırdan yeniden yaratarak çalışır.

Sadece bir kilit_modülünüzle başlamadığınızda, kilit dosyanızdaki içeriği sadece npm kurulumundan daha hızlı (2x-10x!) Alacağınızı garanti etmenin ötesinde.

Adından da anlaşılacağı gibi, sürekli entegrasyon ortamları için büyük bir nimet olmasını bekliyoruz. Ayrıca git etiketlerinden üretim dağıtımı yapan kişilerin büyük kazançlar elde etmesini bekliyoruz.


133
Bir kilit dosyası varsa, bu varsayılan davranış olmalıdır.
nullabilite

13
Yani npm nasıl çalıştığını değiştirdiler, sadece aylar sonra npm ci olarak geri getirmek için?
Scott Flack

1
Hala kafam karıştı. Belgeler , bu projede komutu çalıştırmadan önce " Paket kilidinizin ve güncel bir yüklemenizin olduğundan emin olunnpm install : " yazıyor npm ci. Does not npm installpaket-lock.json dosyanın üzerine?
adiga

1
AFAIK: @adiga - 5.4 sürümünden başlayarak, npm yalnızca gerekli olması durumunda kilit dosyasını değiştirir . Bu yüzden, eskiden kullanılan paketler thatpackage: 1ve kilit diyorsa ..: 1.0.4, geliştirici demek için düzenleyebilir thatpackage: 2- ve bu 1.0.4, yeni belirtilen aralıkla uyumlu olmadığı için kilit dosyasını değiştirmeye zorlar . Değiştirmezseniz packages.json, silme kilit dosyası kadar kesin sürümü de kilitli kalır. [Kilitli kalmazsa ve Packages.json dosyasını değiştirmediyse, hata raporu
gönderin

1
@George Okuduğum bilgilerden (npm'in son sürümleri için) ve sınırlı testimden: her ikisine de evet.
Venryx

95

Yeni tanıtılanları kullanın

npm ci

npm ci büyük takımlara en fazla faydayı vaat ediyor. Geliştiricilere bir paket kilidinde "çıkış yapma" olanağı vermek, büyük ekipler arasında daha verimli işbirliğini teşvik eder ve bir kilit dosyasında tam olarak ne olduğunu yükleme yeteneğinin ayda yüzlerce geliştirici saati olmasa bile onlarca tasarruf etme potansiyeli vardır. harika şeyler oluşturmak ve göndermek için daha fazla zaman harcamak.

Tanıtımı npm cidaha güvenilir kurar, daha hızlı


3
bu benim için doğru mu? başka biri onaylayabilir mi?
phouse512

6
@ phouse512 Bu doğru. Biz hemen hemen sadece kullanmak npm cive sadece kullanmak npm installgüncelleme veya yeni paketlerin yüklenmesi durumunda.
Jacob Sievers

1
Son yorumlar, vb. Bu cevap vereceğim. Çok kötü onlar korkunç snafu düzeltmek coudln't, ama yeni müjde "npm ci", o zaman iyi. Uyum sağlayabilirim.
Svend

Çok kötü, her zaman var olan bir node_modulesdizini siler ve aksi halde boş ama önemli bir sembolik bile olsa yerel olarak yeniden oluşturulur. :(
Joe Atzberger

2
@ToolmakerSteve Nefesini tutmayın! Bir dizinin içeriğini silmek sadece dizini silmekten daha yavaş olacağını düşünüyorum. İçeriği numaralandırmanız ve daha sonra O / S'ye tek bir delete komutu yerine bir dizi silme komutu vermeniz gerekir. Performans sorunları daha önce npm'de seviyelendirilmiş ve kullanımı ile npm ciben oldukça nadir bir kullanım durumu için performansı düşürebilir bir şey tanıtmak için çok isteksiz olacağını umuyoruz. Disk kullanımını azaltmak için sabit bağlantılar kullanıyor olsa da pnpm.js.org dosyasını kontrol etmek isteyebilirsiniz .
Caltor

64

Kısa cevap:

  • npm install package-lock.json'u yalnızca package.json gereksinimlerini karşılarsa onurlandırır.
  • Bu gereksinimleri karşılamıyorsa, paketler güncellenir ve paket kilidinin üzerine yazılır.
  • Derlemede başarısız olursanız, bu durumda paket kilidini yeniden yazmak yerine kullanın npm ci.

İşte olayları açıklayabilecek bir senaryo (NPM 6.3.0 ile doğrulandı)

Package.json içinde bir bağımlılık beyan ediyorsunuz:

"depA": "^1.0.0"

Sonra, npm installbir package-lock.json oluşturacak olan:

"depA": "1.0.0"

Birkaç gün sonra, "1.1.0" deyince "depA" nın daha yeni bir küçük sürümü yayınlandı.

npm ci       # respects only package-lock.json and installs 1.0.0

npm install  # also, respects the package-lock version and keeps 1.0.0 installed 
             # (i.e. when package-lock.json exists, it overrules package.json)

Ardından, package.json'unuzu manuel olarak şu şekilde güncellersiniz:

"depA": "^1.1.0"

Sonra tekrar çalıştırın:

npm ci      # will try to honor package-lock which says 1.0.0
            # but that does not satisfy package.json requirement of "^1.1.0" 
            # so it would throw an error 

npm install # installs "1.1.0" (as required by the updated package.json)
            # also rewrites package-lock.json version to "1.1.0"
            # (i.e. when package.json is modified, it overrules the package-lock.json)

4
Bu aslında bir "kilit" dosyasının amaçlanan davranışıdır. Görünüşe göre, NPM'nin eski sürümlerinde durum böyle değildi.
Blockost

1
Peki npm paket.json'daki son güncellemeyi nasıl izler? Package.json ve package-lock.json dosyanızı başka bir bilgisayara taşıdığınızda ne olur? Yeni bilgisayardaki npm, package-lock.json dosyasını güncellemesinin gerekip gerekmediğine karar vermek için package.lock dosyasının orijinal olup olmadığını veya güncellenip güncellenmediğini nasıl biliyor?
Lahiru Chandima

3
@LahiruChandima Güncellemeleri gerçekten izlemiyor. npm installkilitli sürümlerini kullanır package-lock.jsono tatmin etmiyor sürece package.jsono package.json yükler ve buna göre paket-lock.json yeniden oluşturur ve bu durumda. Eğer package.jsonmevcut paket kilidi hala güncellenmiş tatmin edecek şekilde değiştirdiyseniz, package.jsonbunu kullanmaya devam edecektirpackage-lock
Ahmad Abdelghany

1
Node_modules içinde package.json gereksinimlerini karşılayan bir modülünüz varsa npm install, package-lock.json'dan bağımsız olarak hiçbir şey yapmaz. Package.json içinde belirtilen semver ile eşleşen güncellemeler olsa bile paketleri açıkça güncellemeliyiz. En azından yıllardır benim deneyimim oldu.
carlin.scott

1
@ToolmakerSteve Ayrıca @ carlin.scott'un bildirdiği davranıştan şüpheliydim, ama sadece test ettim ve aslında doğru. İçindeki sürüm node_modulesiçeriğin aralığını karşılıyorsa package.jsonve package-lock.jsondosya yoksa , npm çalışırken modülü güncellemez npm install. Bağımlılıkları güncellemek için npm update(veya npm-checken son için) kullanabileceğinizden eminim ve bu davranış, birinin sadece bir giriş eklediği package.jsonve ilgisiz paketlerin kendilerini sem-ver'i tatmin eden en son sürümlere güncellemesini istemediği durumlarda daha hızlıdır. Aralık.
Venryx

19

Kullanım npm ciyerine komutu npm install.

"ci", "sürekli entegrasyon" anlamına gelir.

Proje bağımlılıklarını lenient package.json dosya bağımlılıkları yerine package-lock.json dosyasına göre kurar.

Takım arkadaşlarınıza özdeş yapılar üretecek ve aynı zamanda çok daha hızlı.

Bu blog yayınında daha fazla bilgi bulabilirsiniz: https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable


2
ci"Sürekli entegrasyon" ifadesi, komutu açıklayan dokümanlar ve blog gönderisinde belirtildiği gibi: blog.npmjs.org/post/171556855892/…
Joe Atzberger

Teşekkürler Joe. Cevabımı doğru adla güncelledim ve blog gönderisine bağlandım. 😊 (bunu okuyanlar için, daha önce "temiz kurulum" anlamına geldiğini söyledim)
Daniel Tonon

"Ve ayrıca çok daha hızlı" - node_modulesklasörü siler ve sıfırdan yeniden oluşturur. Gerçekten çok daha hızlı mı? Does npm installsilme node_modulesklasör de?
izogfif

Hız npm indirmek için hangi paketleri hesaplamaya gerek yok geliyor düşünüyorum. npm installÇalıştırırken tüm paket bağımlılıklarını çözmesi gerektiğini düşünün . npm ci"tam olarak bu modülleri al" ın bir alışveriş listesidir.
Daniel Tonon

8

Gelecekte, bir kullanmak mümkün olacak --from-lock-fileyüklemek için (veya benzeri) bayrağı sadece dan package-lock.jsondeğiştirmeden.

Bu, tekrarlanabilir yapıların önemli olduğu CI, vb. Ortamlar için faydalı olacaktır.

Özelliğin izlenmesi için bkz. Https://github.com/npm/npm/issues/18286 .


Şüpheliyim. Farklı işletim sistemleri için bağımlılıklar farklıysa, çalışmayan bir şeyi yüklemeye nasıl zorlayabilirsiniz?
Yevgeniy Afanasyev

4
@YevgeniyAfanasyev Bu bayrak yerine, npm cisorunuzu da ele aldığı şekilde uygulandı .
spex

8

Bu sorun npm v5.4.2'de giderilmiş gibi görünüyor

https://github.com/npm/npm/issues/17979

(İleti dizisindeki son yoruma gidin)

Güncelleme

Aslında 5.6.0'da düzeltildi. 5.4.2'de sorunun hala oluşmasına neden olan bir çapraz platform hatası vardı.

https://github.com/npm/npm/issues/18712

Güncelleme 2

Cevabımı buraya bakın: https://stackoverflow.com/a/53680257/1611058

npm ci şu anda mevcut projeleri kurarken kullanmanız gereken komuttur.


5
5.4.2 kullanıyorum ve hala ne zaman benim lock-lock.json değişiklik ile sonuçlanır npm i. Örneğin, desteklemeyen bir makinede fseventsolduğumda modül kaldırılır ve daha sonra bir makinede bir kez daha modül eklenir . npm ifseventsnpm i
hrdwdmrbl

Sonra npm GitHub repo'da bunu açıklayan yeni bir sorun ortaya çıkarmalısınız. Çalışmaları gerektiğini söylediklerinde işe yaramazsa, acil olarak düzeltilmesi gereken yüksek öncelikli bir hata olarak görürler.
Daniel Tonon

@hrdwdmrbl aynı görüyorum fseventsskinTenimde damla package-lock.jsonile npm@5.5Mac OS X katkıda işbirliği yaparken. Eğer bir sorun açmadıysanız, ben söylerim.
AL the X

@hrdwdmrbl Yorumumu bıraktıktan ve yorumumu güncellemek için SO'ya geri dönmeyi unuttuktan sonra (ve ilişkili sorunların uzun bir parçasını) buldum. Sırtımı aldığınız için teşekkürler. Herşey yolunda.
AL the X

4

Muhtemelen şöyle bir şey var:

"typescript":"~2.1.6"

senin içinde package.jsonhangi durumda varlık içinde, son alt sürümüne güncellemelerini NPM2.4.1

Düzenleme: OP'den soru

Ancak bu "npm install" in neden kilit dosyasını değiştireceğini açıklamaz. Kilit dosyası yeniden oluşturulabilir bir yapı oluşturmak anlamına gelmiyor mu? Öyleyse, semver değerinden bağımsız olarak, yine de aynı 2.1.6 sürümünü kullanmalıdır.

Cevap:

Bu, tam bağımlılık ağacınızı kilitlemek için tasarlanmıştır. Diyelim ki typescript v2.4.1gerektirir widget ~v1.0.0. Ne zaman npm yüklemek zaman kapmak widget v1.0.0. Daha sonra geliştirici (veya CI derlemesi) npm kurulumu yapar ve alır typescript v2.4.1ancak widgetgüncellendi widget v1.0.1. Artık düğüm modülünüz senkronize değil. Bunu package-lock.jsonengelleyen budur.

Veya daha genel olarak:

Örnek olarak,

paket A:

{"name": "A", "version": "0.1.0", "bağımlılıklar": {"B": "<0.1.0"}}

paket B:

{"name": "B", "version": "0.0.1", "bağımlılıklar": {"C": "<0.1.0"}}

ve paket C:

{"ad": "C", "sürüm": "0.0.1"}

Bunlar kayıt defterinde bulunan A, B ve C'nin yalnızca sürümleri ise, normal bir npm yükleme A yüklenir:

A@0.1.0 - B@0.0.1 - C@0.0.1

Ancak, B@0.0.2 yayınlanmışsa, yeni bir npm kurulumu A yüklenecektir:

A@0.1.0 - B@0.0.2 - C@0.0.1 yeni versiyonun B'nin bağımlılıklarını değiştirmediğini varsayarsak. Elbette, B'nin yeni sürümü C'nin yeni bir sürümünü ve herhangi bir sayıda yeni bağımlılığı içerebilir. Bu tür değişiklikler istenmezse, A'nın yazarı B@0.0.1'e bir bağımlılık belirtebilir. Ancak, A'nın yazarı ve B'nin yazarı aynı kişi değilse, A'nın yazarının, B hiç değişmediği zaman C'nin yeni yayınlanan sürümlerini çekmek istemediğini söylemesinin bir yolu yoktur.


OP Soru 2: Doğru anladığımı göreyim. Söylediğiniz şey, kilit dosyasının ikincil bağımlılıkların sürümlerini belirtmesidir, ancak yine de üst düzey bağımlılıkları belirlemek için package.json'un bulanık eşleşmesine dayanır. Bu doğru mu?

Cevap: Hayır. Package-lock, tanımlanan kök paketleri de dahil olmak üzere tüm paket ağacını kilitler package.json. Eğer typescriptkilitli 2.4.1Gözlerinde farklı package-lock.jsono değiştirilene kadar, bu şekilde kalmalıdır. Ve diyelim yarın typescriptsürüm yayınlanacak 2.4.2. npm installŞubenizi kontrol edip çalıştırırsam , npm kilit dosyasına saygı duyar ve yükler 2.4.1.

Daha fazlası package-lock.json:

package-lock.json, npm'nin node_modules ağacını veya package.json dosyasını değiştirdiği tüm işlemler için otomatik olarak oluşturulur. Oluşturulan tam ağacı açıklar, böylece sonraki yüklemeler ara bağımlılık güncellemelerinden bağımsız olarak aynı ağaçları üretebilir.

Bu dosya kaynak depolarına ayrılmak üzere tasarlanmıştır ve çeşitli amaçlara hizmet eder:

Bir bağımlılık ağacının tek bir temsilini açıklayın, böylece takım arkadaşları, konuşlandırmalar ve sürekli entegrasyon tam olarak aynı bağımlılıkları kuracak.

Kullanıcılara, dizinin kendisini işlemek zorunda kalmadan önceki node_modules durumlarına "zaman yolculuğu" yapma olanağı sağlayın.

Okunabilir kaynak kontrol farkları ile ağaç değişikliklerinin daha iyi görünmesini kolaylaştırmak için.

Ve npm'in önceden yüklenmiş paketler için tekrarlanan meta veri çözünürlüklerini atlamasına izin vererek kurulum işlemini optimize edin.

https://docs.npmjs.com/files/package-lock.json


29
Ancak bu "npm install" in neden kilit dosyasını değiştireceğini açıklamaz. Kilit dosyası yeniden oluşturulabilir bir yapı oluşturmak anlamına gelmiyor mu? Öyleyse, semver değerinden bağımsız olarak, yine de aynı 2.1.6 sürümünü kullanmalıdır.
Viper Bailey

3
Ve bunu söylüyorum. Paket kilit dosyamda typescript@2.1.6 yazıyor ancak npm install komutunu çalıştırdığımda, girdi typescript@2.4.1 ile değiştiriliyor.
Viper Bailey

5
Aynı sorunu yaşadım. CI / CD'mizde, package-lock.jsonaşağı çekilir ve daha sonra çalışırız npm install, ancak package-lock.jsondosya değiştirilir ve sonraki değişiklikleri çekmeden önce bir sıfırlama yapmamız gerekir.
BayssMekanique

15
Anlamıyorum. Sonraki yüklemeler yine de yükseltme yapabilirse, bu nasıl bir "kilit" dosyasıdır ?!
Ross Allen

5
Bence onlar bu bilgi "bilgi" ve "kilit" olarak sahip olma fikri ile başladı ve daha sonra, sadece bir "bilgi" dosyası olacağına karar verdi. Daha iyi isim "paket-info.json" olurdu. "Package-lock.json" 'dan kurulacak ve "package.json"' u görmezden gelecek bir "npm install -lock" olmasını isterim
Jeremy Chone

2

Muhtemelen böyle bir şey kullanmalısın

npm ci

npm install Paketinizin sürümünü değiştirmek istemiyorsanız kullanmak yerine .

Resmi belgelere göre her iki npm installve npm ciproje için gerekli olan bağımlılıklarını yükleyin.

Temel fark, referans olarak npm installpaketleri kurmasıdır packge.json. Bu durumda, her bir paketin tam olarak kurulduğundan emin olarak, referans npm cialarak paketleri kurar package-lock.json.



0

EDIT: "kilit" adı zor bir, NPM İplik yakalamaya çalışıyor. Kilitli bir dosya değil. package.json"sabitlendiğinde" node_modules klasör ağacı oluşturacak ve daha sonra bu ağaç yazılacaktır package-lock.json. Görüyorsunuz, bu tam tersi - bağımlılık sürümleri package.jsonher zamanki gibi package-lock.jsonçekilecek ve çağrılmalıdırpackage-tree.json

(umarım bu benim cevabımı daha açık yorumlardan sonra netleştirmiştir)


Basit bir cevap: package.jsonher zamanki gibi bağımlılıklarınız olsun package-lock.json, "kesin ve daha da önemlisi tekrarlanabilir bir düğüm_modüller ağacı" dır ( npm belgelerinin kendisinden alınır ).

Zor adı gelince, NPM İplik yakalamaya çalışıyor.


1
Çünkü npm kurulumunu çalıştırırsanız, paket kilidi güncellenir.
Jean-Baptiste
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.