Npm package.json dosyasındaki bağımlılıklar, devDependencies ve peerDependencies arasındaki fark nedir?


2028

Bu belge sorumu çok kötü yanıtlıyor. Bu açıklamaları anlamadım. Birisi daha basit kelimelerle söyleyebilir mi? Belki basit kelimeler seçmek zorsa örneklerle?

EDIT ayrıca peerDependenciesyakından ilişkilidir ve karışıklığa neden olabilir.



118
@AidanFeldman "isteğe bağlı Bağımlılıklar" günün benim oksimoron
Nick Bull

1
npm dokümantasyonu diyor ki: "bağımlılıklar": Uygulamanızın üretimde gerektirdiği paketler. "devDependencies": Yalnızca yerel geliştirme ve test için gerekli paketler. bağlantıya bakınız: docs.npmjs.com/…
Deke

Yanıtlar:


2365

Önemli davranış farklılıklarının özeti:

  • dependencies her ikisine de yüklenir:

    • npm install içeren bir dizinden package.json
    • npm install $package başka bir dizinde
  • devDependencies şunlardır:

    • Ayrıca , bayrağı geçmezseniz npm install, içeren bir dizine yüklenir ( Gayan Charith'in cevabını yükseltin ).package.json--production
    • seçeneği belirtmedikçe npm install "$package"başka bir dizine yüklenmez --dev.
    • geçici olarak yüklenmez.
  • peerDependencies:

    • 3.0'dan önce: eksikse her zaman yüklenir ve bağımlılığın birden fazla uyumsuz sürümü farklı bağımlılıklar tarafından kullanılacaksa bir hata oluşturur.
    • 3.0'da başlaması bekleniyor (denenmemiş): eksikse bir uyarı verin npm installve bağımlılığı kendiniz manuel olarak çözmeniz gerekir. Çalışırken, bağımlılık eksikse, bir hata alırsınız ( @nextgentech tarafından belirtilen )
  • Geçişlilik ( Ben Hutchison tarafından bahsedilen ):

    • dependencies geçişli olarak kurulur: A için B gerekiyorsa ve B için C gerekiyorsa, C kurulur, aksi takdirde B çalışmaz ve hiçbiri A olmaz.

    • devDependenciesgeçici olarak yüklenmedi. A test etmek için B testine ihtiyacımız yok, bu yüzden B'nin test bağımlılıkları dışarıda bırakılabilir.

Burada tartışılmayan ilgili seçenekler:

devDependencies

dependenciesçalıştırmak için gereklidir devDependencies, örneğin: birim testleri, CoffeeScript'ten JavaScript'e çeviri, küçültme, ...

Bir paket geliştirecekseniz, paketi indirirsiniz (örn. Yoluyla git clone), içeren kök dizinine gidersiniz package.jsonve şunları çalıştırırsınız:

npm install

Gerçek kaynağa sahip olduğunuz için, onu geliştirmek istediğiniz açıktır, bu nedenle varsayılan olarak, hem dependencies(elbette geliştirmek için çalıştırmanız gerekir) hem de devDependencybağımlılıklar da yüklenir.

Ancak, yalnızca kullanmak için bir paket yüklemek isteyen son kullanıcıysanız, herhangi bir dizinden yapacaksınız:

npm install "$package"

Sadece paketi kullanmak üzere gerekli olanı almak böylece durumda, normalde, geliştirme bağımlılıkları istemiyoruz: dependencies.

Bu durumda geliştirme paketlerini gerçekten yüklemek istiyorsanız, devyapılandırma seçeneğini truemuhtemelen komut satırından şu şekilde ayarlayabilirsiniz :

npm install "$package" --dev

Bu seçenek falsevarsayılan olarak, çünkü bu çok daha az yaygın bir durumdur.

peerDependencies

(3.0'dan önce test edilmiştir)

Kaynak: https://nodejs.org/en/blog/npm/peer-dependencies/

Düzenli bağımlılıklarla, bağımlılığın birden fazla sürümüne sahip olabilirsiniz: basitçe node_modulesbağımlılığın içine yüklenir .

Örneğin , proje ağacının farklı sürümlere bağlı olması dependency1ve dependency2her ikisinin birden olması durumunda dependency3:

root/node_modules/
                 |
                 +- dependency1/node_modules/
                 |                          |
                 |                          +- dependency3 v1.0/
                 |
                 |
                 +- dependency2/node_modules/
                                            |
                                            +- dependency3 v2.0/

Ancak eklentiler, normalde bu bağlamda ana bilgisayar olarak adlandırılan diğer paketi gerektirmeyen paketlerdir . Yerine:

  • ana bilgisayar tarafından eklentiler gerekli
  • eklentiler, ana bilgisayarın bulmayı beklediği standart bir arayüz sunar
  • yalnızca ana bilgisayar doğrudan kullanıcı tarafından çağrılır, bu nedenle tek bir sürümü olmalıdır.

Eğer Örn dependency1ve dependency2bağlı akran dependency3, proje ağaç gibi görünecektir:

root/node_modules/
                 |
                 +- dependency1/
                 |
                 +- dependency2/
                 |
                 +- dependency3 v1.0/

Eğer söz asla olsa bile gerçekleşir dependency3sizin de package.jsondosyaya.

Bence bu, Tersine Çevirme kontrol deseninin bir örneği.

Eş bağımlılıklarının prototip bir örneği Grunt, ana bilgisayar ve eklentileridir.

Örneğin, https://github.com/gruntjs/grunt-contrib-uglify gibi bir Grunt eklentisinde şunları göreceksiniz:

  • grunt bir peer-dependency
  • sadece require('grunt')altında tests/: aslında program tarafından kullanılmaz.

Daha sonra, kullanıcı bir eklenti kullanacaksa, Gruntfilebir grunt.loadNpmTasks('grunt-contrib-uglify')satır ekleyerek dolaylı olarak eklentiyi gerektirecektir , ancak gruntkullanıcı doğrudan arayacaktır.

Her eklenti farklı bir Grunt sürümü gerektiriyorsa bu işe yaramaz.

Manuel

Belgelerin soruyu oldukça iyi yanıtladığını düşünüyorum, belki sadece düğüm / diğer paket yöneticilerine yeterince aşina değilsiniz. Muhtemelen anlıyorum çünkü Ruby bundler hakkında biraz bilgim var.

Anahtar hat:

Bu şeyler, bir paketin kökünden npm bağlantısı veya npm kurulumu yapılırken yüklenir ve diğer herhangi bir npm yapılandırma parametresi gibi yönetilebilir. Konu hakkında daha fazla bilgi için bkz. Npm-config (7).

Ve sonra npm-config (7) altında şunları bulun dev:

Default: false
Type: Boolean

Install dev-dependencies along with packages.

5
Ah. Anladım yanlış anladım. Cevabınız npm install package, şimdi demek istediğini düşündüğümden ziyade, dev paket bağımlılığı olmayan tüm paketleri yüklemek için kullanacağınız bir komut gibi okunuyor. bunu okumadan önce. Ben olsaydım, [paket-adı] demek için düzenlerdim, bu da demek istediğin şeyin 'insert-name-here' olduğunu açıkça gösterir.
Tom W

184
Bu harika! Hiç fark etmedim, ancak bu cevap bana bağımlılıklara karşı devDependencies farkının yalnızca bir npm paketi yayınlayacaksanız uygulanabilir olduğunu öğretti. Sadece bir uygulama veya site üzerinde çalışıyorsanız, bunun çok fazla önemi yoktur. Teşekkürler!
jedd.ahyoung

3
Bu gönderi peerDependencies, yaklaşan npm @ 3'teki değişen davranışı yansıtacak şekilde güncellenmelidir . Gönderen blog.npmjs.org/post/110924823920/npm-weekly-5 . Akran bağımlılık zaten yüklü değilse otomatik olarak artık akran bağımlılığını indirirken olmayacak" Bunun yerine, sizi uyarabilir edeceğiz Bu gerektirir. peerDependency, kendinizle manuel olarak çakışıyor, ancak uzun vadede bu, paketlerinizin bağımlılıklarıyla ilgili zor bir noktaya gelme olasılığınızı azaltacaktır. "
nextgentech

8
Ayrıca, devDependencies bağımlı paketler tarafından geçici olarak yüklenmez. Örnek: A paketi B paketine bağlıdır. B paketi C paketine ve B de dev paketine bağlıdır. npm installA paketinden çalıştırırsanız , B ve C alırsınız, ancak D alırsınız.
Ben Hutchison

9
Olarak ayarlandığında devDependenciesyüklenmemiş olduğunu belirtmek önemlidir . NODE_ENVproduction
Augusto Franzoia

491

DevDependencies yüklemek istemiyorsanız kullanabilirsiniz npm install --production


1
npm install --save yazılım bağımlılığı içindir?
Vamsi Pavan Mahesh

19
npm install tüm bağımlılıkları kuracaktır. --save flag, ilgili modülü package.json'a eklemek istediğinizde de kullanılır. örnek: - npm install uglify --save uglify'yi proje klasörünüze kuracak ve uglify'yi project, package.json dosyasına ekleyecektir.
Gayan Charith

6
Ve devDependencies hakkında konuştuğumuz için, yeni modülü devDependency olarak kaydetmek için --save-dev komutunu kullanabilirsiniz. Örnek: npm install uglify --save-dev
Mykaelos

9
5: 00'dan itibaren, --saveseçenek artık gerekli değildir. "Npm paketimi kur" seçeneğini kullanırsanız, paketimi package.jsondosyanıza bağımlılık olarak ekler.
Martin Carel

sadece npm yükleyin
sultan aslam

116

Örnek olarak, mocha normalde bir devDependency olur, çünkü üretimde test gerekli değildir, ancak ifade bir bağımlılık olur.


4
Üretim sunucusunu başlatmadan önce kendi kendine testler yapmak isteyebileceğinizden, testi bağımlılık olarak koymaya eğilimliydim

47
Bunun yerine, testlerinizi yürüten ve daha sonra geçtikleri takdirde üretime dağıtan Hudson veya CircleCI gibi sürekli bir entegrasyon hizmeti kullanmanızı öneririm.
Dan Kohn

1
CI sunucusu prod sunucusundan bir şekilde farklı olabileceğinden gerçek sunucuyu test etmek yine de önemli olabilir ve bu fark örneğin uygulamanın başlatılmasını engelleyebilir ...
Nicole

2
@Nicole hazırlama sunucunuzu ürününüzün yapılandırmasında neden aynı değil?
Lucas

1
Daha sonra, düzenli bağımlılıklar olarak test bağımlılıkları eklemek, her biri bir şekilde başarısız olabilecek bir sürü ek kitaplık getirir. Onları mümkün olduğunca az kod ile hafif üretim sunucularına doğru eğilirdim. Unutmayın, en iyi kod kod değildir!
Stijn de Witt

69

bağımlılıklar
Kodunuzdan çağırdığınız işlevleri sağlayan bir kütüphane gibi projenizin çalışması gereken bağımlılıklar .
Geçişli olarak kurulurlar (A, B'ye bağlı ise C'ye bağlıysa, A'ya npm kurulumu B ve C'yi kuracaktır).
Örnek: lodash: projeniz bazı lodash işlevlerini çağırıyor.

devBağımlılıklar
Kodunuzu alıp javascript, test çerçeveleri veya belge oluşturucularına derleyen derleyiciler gibi yalnızca geliştirme veya serbest bırakma sırasında ihtiyacınız olan bağımlılıklar.
Geçici olarak kurulmazlar (A, B devine bağlıysa C'ye bağlıysa, A'ya npm yüklemesi yalnızca B'yi yükleyecektir).
Örnek: grunt: projeniz kendini inşa etmek için grunt kullanıyor.

peerDependencies
Projenizin üst projede yer aldığı veya değiştirdiği bağımlılıklar, genellikle başka bir kütüphane veya araç için bir eklenti. Üst proje (projenize bağlı olacak proje), bağlandığınız projeye bağımlı olduğundan emin olmak için bir kontrol olması amaçlanmıştır. Bu nedenle, B kütüphanesine işlevsellik katan bir C eklentisi yaparsanız, A projesini yapan birinin C'ye bağımlı olması durumunda B'ye bağımlı olması gerekir.
Yüklü değiller (npm <3 olmadığı sürece) için kontrol edildi.
Örnek: homurdanma: projeniz homurdanmaya işlevsellik katar ve sadece homurdanma kullanan projelerde kullanılabilir.

Bu belgeler akran bağımlılıklarını gerçekten iyi açıklamaktadır: https://nodejs.org/en/blog/npm/peer-dependencies/

Ayrıca, npm belgeleri zaman içinde geliştirildi ve şimdi farklı bağımlılık türleri hakkında daha iyi açıklamalar var: https://github.com/npm/cli/blob/latest/doc/files/package.json.md#devdependencies


63

Bir paketi package.json'a dev bağımlılıkları olarak kaydetmek için :

npm install "$package" --save-dev

Çalıştırdığınızda npm installhem devDependenciesve hem de yükleyecektir dependencies. Yükleme devDependenciesçalıştırmasını önlemek için :

npm install --production

3
ayrıca şunları da kullanabilirsiniz: npm i -S
Maysara Alhindi

36

Üretimde ihtiyaç duyulmayan, sadece geliştirme için gerekli olan bazı modüller ve paketler vardır. Belgelerde söylediği gibi :

Birisi modülünüzü programında indirmeyi ve kullanmayı planlıyorsa, muhtemelen kullandığınız harici test veya dokümantasyon çerçevesini indirip kurmak istemez veya gerekmez. Bu durumda, bu ek öğeleri bir devDependencies karma değerinde listelemek en iyisidir.


Üretimde yalnızca bundle.js dosyası çalıştırıyorsanız? bu bağımlılıklara gerçekten ihtiyacın var mı?
RegarBoy

Sunucuda bundle.js çalıştırıyorsanız, sunucu tarafı web paketi veya başka bir şey yapıyorsunuz ... Lütfen durumun böyle olup olmadığını kontrol edin, çünkü genellikle böyle değildir ve aslında düzgün çalışmasını sağlamak için çok fazla iş gerektirir (I biliyorum çünkü bunu yaptım). Bundle.js'nizin tarayıcılara sunulduğundan ve istemci tarafı kodunu içerdiğinden şüpheleniyorum.
Stijn de Witt

16

Benim için daha açık hale getiren basit bir açıklama:

Uygulamanızı dağıtırken, bağımlılıktaki modüllerin yüklenmesi gerekir; aksi takdirde uygulamanız çalışmaz. DevDependencies içindeki modüllerin, o makinede geliştirmediğiniz için üretim sunucusuna kurulması gerekmez. bağlantı


2
Yani, eğer web sitesi yapıyor ve prod sürümünde tüm kütüphaneler vendor.jsinline olacak, derlenmiş kod repo taahhüt edilirse tüm deps devler olmalıdır? Ve başka bir deyişle, sadece derlemek değil, modülü derlemeniz garip olduğu için (ve alt modüllerde herhangi bir değişikliğin gerilemeye yol açabileceği için test burada da bir yerde) garip olduğu için ...
Qwertiy

Müthiş bir cevap, ama bir soru mu var? Olası Webpack bozuk bir paket oluşturuyor mu? Sanırım devDependencies paketleri ürün sürümünde çalışmayacak webpack -p. lütfen soruma cevap ver.
AmerllicA

Üretim oluştururken herhangi bir sorun varsa, dağıtım işleminiz derleme zamanında hata gösterecek ve bozuk kodu üretime zorlamayacak şekilde tasarlanmalıdır (örn. Jenkins'i deneyebilirsiniz). Yine de bağımlılıkların üretim sunucusuna kurulması gerekmez.
Jyoti Duhan

ve akran bağımlılıkları ne olacak?
dev27

13

Bu bağımlılık açıklamaları hakkındaki görüşüme yanıtı eklemek istiyorum

  • dependencies kod tabanınızda doğrudan kullanım, genellikle üretim kodunda yer alan şeyler veya kod parçaları için kullanılır
  • devDependencies oluşturma işlemi, uç kodun nasıl biteceğini yönetmenize yardımcı olan araçlar, üçüncü taraf test modülleri, (örn. webpack şeyler) için kullanılır

CSS varlıkları ne olacak?
Brian Zelip

8

Kısacası

  1. Bağımlılıklar - npm install <package> --save-produygulamanızın gerektirdiği paketleri üretim ortamına yükler.

  2. DevDependencies - npm install <package> --save-devyalnızca yerel geliştirme ve test için gerekli paketleri kurar

  3. Sadece yazmak npm installpakette belirtilen tüm paketleri yükler. Json

yerel bilgisayarınızda çalışıyorsanız yazın npm installve devam edin :)


6

peerDependenciesBen bu kod parçasını okumak kadar oldukça benim için mantıklı gelmedi bir blog yazısı konu üzerine Ciro yukarıda belirtilen :

[ Eklentiler ] 'in ihtiyacı olan, eklentiler ve ana bilgisayar paketleri arasındaki bu “bağımlılıkları” ifade etmenin bir yoludur. “Yalnızca ana bilgisayar paketimin 1.2.x sürümüne bağlıyken çalışıyorum, bu yüzden beni kurarsanız, uyumlu bir ana bilgisayarın yanında olduğundan emin olun.” Bu ilişkiye akran bağımlılığı diyoruz.

Eklenti ana bilgisayarın belirli bir sürümünü bekliyor ...

peerDependencieseklentiler içindir, işlevlerini yerine getirmek için "ana bilgisayar" kitaplığı gerektiren, ancak ana bilgisayarın en son sürümü yayınlanmadan önce yazılmış bir kitaplık olabilir .

Ben yazarsam, olduğu PluginX v1için HostLibraryX v3ve yürüyüp, garantisi yok PluginX v1olduğunda çalışacaktır HostLibraryX v4(hatta HostLibraryX v3.0.1serbest bırakılır).

... ancak eklenti ana bilgisayara bağlı değil ...

Eklentinin bakış açısından, yalnızca ana bilgisayar kitaplığına işlevler ekler . Gerçekten bir eklentiye bağımlılık eklemek için ana bilgisayar "gerekmez" ve eklentiler genellikle tam anlamıyla kendi ana bilgisayar bağlı değildir . Ana makineniz yoksa, eklenti zararsız bir şekilde hiçbir şey yapmaz.

Bu dependencies, eklentiler için gerçekten doğru kavram olmadığı anlamına gelir .

Daha da kötüsü, ev sahibime bir bağımlılık gibi davranılırsa , aynı blog gönderisinden bahsettiğimizde (bu cevabın oluşturulmuş ana bilgisayar ve eklentisini kullanmak için biraz düzenlenmiş) sonuçlanırız:

Ama şimdi, [HostLibraryX'in çağdaş sürümünü PluginX'e bağımlılık olarak ele alırsak,] çalıştırılması npm installbeklenmedik bağımlılık grafiğiyle sonuçlanır.

├── HostLibraryX@4.0.0
└─┬ PluginX@1.0.0
  └── HostLibraryX@3.0.0

Eklentiden gelen ince hataları hayal gücünüze ana uygulamadan farklı bir [HostLibraryX] API kullanarak bırakacağım.

... ve ev sahibi açıkçası eklentiye bağlı değil ...

... eklentilerin bütün noktası bu. Ev sahibi, tüm eklentileri için bağımlılık bilgilerini içerecek kadar güzel olsaydı, bu sorunu çözecekti, ancak bu da büyük bir yeni kültürel sorun getirecektir : eklenti yönetimi!

Eklentilerin asıl amacı anonim olarak eşleşebilmeleridir. Mükemmel bir dünyada, ev sahibinin hepsini yönetmesi temiz ve düzenli olurdu, ancak kütüphaneleri sürü kedilere ihtiyacımız olmayacak.

Hiyerarşik olarak bağımlı değiliz, belki de birbirine bağımlı akranlarız ...

Bunun yerine, akran olma kavramımız var. Ne ana bilgisayar ne de eklenti diğerinin bağımlılık grubunda yer almaz. Her ikisi de bağımlılık grafiğinin aynı düzeyinde yaşıyor.


... ama bu otomatikleştirilebilir bir ilişki değil. <<< Moneyball !!!

Ben isem PluginX v1ve beklemek bir Peer'a (olduğunu, bir peerDependency var ) HostLibraryX v3, öyle söylerim. En son Otomatik geçiş için ettiyseniz HostLibraryX v4( 's versiyonu o notta 4 ) VE gelmiş Plugin v1yüklü, doğru, bilmek gerekir?

npm bu durumu benim için yönetemiyorum -

"Hey, kullandığını görüyorum PluginX v1! Otomatik olarak v4'ten HostLibraryXv3'e geçiyorum, kk?"

... ya da ...

"Hey kullandığınızı görüyorum PluginX v1. Bu HostLibraryX v3, son güncellemeniz sırasında toz içinde kalmanızı bekliyor . Güvende olmak için otomatik olarak kaldırıyorum Plugin v1!! 1!

Hayýr, npm ?!

Yani npm yapmaz. Durum hakkında sizi uyarır ve HostLibraryX v4uygun bir eş olup olmadığını anlamanıza izin verir Plugin v1.


Koda

peerDependencyEklentilerde iyi yönetim, bu kavramın pratikte daha sezgisel çalışmasını sağlayacaktır. Gönderen blog post , yine ...

Tek bir tavsiye: düzenli bağımlılıklardan farklı olarak, akran bağımlılığı gereklilikleri yumuşak olmalıdır. Eş bağımlılıklarınızı belirli yama sürümlerine kilitlememelisiniz. Bir Chai eklentisinin Chai 1.4.1'e akranına bağlı olması gerçekten sinir bozucu olurken, diğeri Chai 1.5.0'a bağımlıysa, sadece yazarlar tembel olduğu ve Chai'nin asgari sürümünü anlamak için zaman harcamadıkları için gerçekten can sıkıcı olurdu. ile uyumlu.


4

Bağımlılıklar ve geliştirici bağımlılıklar

Geliştirici bağımlılıkları, yalnızca geliştirme sırasında gerekli olan modüllerdir, oysa çalışma zamanında bağımlılıklar gerekir. Uygulamanızı dağıtıyorsanız, bağımlılıkların yüklenmesi gerekir, aksi takdirde uygulamanız çalışmaz. Kodunuzdan programın çalışmasını sağlayan kitaplıklar bağımlılık olarak kabul edilebilir.

Örneğin, Tepki, Tepki - dom

Bu makinede geliştirmeyeceğiniz için geliştirme bağımlılığı modüllerinin üretim sunucusuna kurulması gerekmez. Kodunuzu javascript, test çerçeveleri ve belge oluşturuculara dönüştüren derleyiciler, yalnızca geliştirme sırasında gerekli oldukları için geliştirici bağımlılık olarak kabul edilebilir.

Ör- ESLint, Babel, web paketi

@FYI,

mod-a
  dev-dependents:
    - mod-b
  dependents:
    - mod-c

mod-d
  dev-dependents:
    - mod-e
  dependents:
    - mod-a

----

npm install mod-d

installed modules:
  - mod-d
  - mod-a
  - mod-c

----

checkout the mod-d code repository

npm install

installed modules:
  - mod-a
  - mod-c
  - mod-e

Npm'de yayınlıyorsanız, doğru modüller için doğru bayrağı kullanmanız önemlidir. Npm modülünüzün çalışması gereken bir şeyse, modülü bağımlılık olarak kaydetmek için "--save" işaretini kullanın. Modülünüzün çalışması gerekmeyen bir şeyse ancak test için gerekliyse, "--save-dev" bayrağını kullanın.

# For dependent modules
npm install dependent-module --save

# For dev-dependent modules
npm install development-module --save-dev

1

Bir npm paketi dağıtmaya çalışırken kullanmaktan kaçınmalısınız dependencies. Bunun yerine, içine eklemeyi peerDependenciesveya kaldırmayı düşünmeniz gerekir dependencies.


1

Basit bir açıklama buldum.

Kısa cevap:

bağımlılıkları "... projenizin gerçekten üretimde çalışabilmesi için ihtiyaç duydukları."

devDependencies "... geliştirme sırasında ihtiyacınız olanlardır."

peerDependencies "kendi kitaplığınızı bağımlılık olarak kullanılabilmesi için oluşturmak ve yayınlamak istiyorsanız"

Bu yayında daha fazla ayrıntı: https://code-trotter.com/web/dependencies-vs-devdependencies-vs-peerdependencies

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.