प्लग इन के लिए npm में सहकर्मी निर्भरता का उपयोग क्यों करें?


218

उदाहरण के लिए, एक ग्रन्ट प्लगइन ग्रन्ट पर अपनी निर्भरता को " सहकर्मी निर्भरता " के रूप में क्यों परिभाषित करता है ?

प्लग- इन ग्रन्ट-प्लग / नोड_मॉड्यूल्स में अपनी निर्भरता के रूप में सिर्फ ग्रन्ट क्यों नहीं हो सकता है ?

सहकर्मी निर्भरताएं यहां वर्णित हैं: https://nodejs.org/en/blog/npm/peer-d dependencies /

लेकिन मैं वास्तव में यह नहीं मिलता है।

उदाहरण

मैं इस समय AppGyver स्टेरॉयड के साथ काम कर रहा हूं जो एक स्थानीय डिवाइस पर सेवा के लिए मेरे स्रोत फ़ाइलों को / dist / फ़ोल्डर में बनाने के लिए Grunt कार्यों का उपयोग करता है। मैं npm और ग्रंट पर काफी नया हूं इसलिए मैं पूरी तरह से समझना चाहता हूं कि क्या चल रहा है।

अब तक मुझे यही मिलता है:

[rootfolder] /package.json npm को बताता है कि यह grunt-steroidsविकास के लिए npm पैकेज पर निर्भर करता है :

  "devDependencies": {
    "grunt-steroids": "0.x"
  },

ठीक है। [रूटफोलर] में एनपीएम इंस्टालिंग चलाना निर्भरता का पता लगाता है और [रूटफोलर] / नोड_मॉड्यूल्स / ग्रंट -स्टेरॉयड में ग्रंट -स्टेरॉयड स्थापित करता है ।

Npm तब पढ़ता है [rootfolder] /node_modules/grunt-steroids/package.json ताकि यह grunt-steroidsखुद पर निर्भरता स्थापित कर सके :

"devDependencies": {
    "grunt-contrib-nodeunit": "0.3.0",
    "grunt": "0.4.4"
  },
"dependencies": {
    "wrench": "1.5.4",
    "chalk": "0.3.0",
    "xml2js": "0.4.1",
    "lodash": "2.4.1"
  },
"peerDependencies": {
    "grunt": "0.4.4",
    "grunt-contrib-copy": "0.5.0",
    "grunt-contrib-clean": "0.5.0",
    "grunt-contrib-concat": "0.4.0",
    "grunt-contrib-coffee": "0.10.1",
    "grunt-contrib-sass": "0.7.3",
    "grunt-extend-config": "0.9.2"
  },

" निर्भरता " पैकेज को [रूटफ़ोल्डर] / नोड_मॉड्यूल / ग्रंट-स्टेरॉयड / नोड_मॉड्यूल्स में स्थापित किया जाता है जो मेरे लिए तर्कसंगत है।

" DevD डिपेंडेंसीज़ " स्थापित नहीं हैं, जो मुझे यकीन है कि npm द्वारा नियंत्रित किया जाता है यह पता लगाने के लिए कि मैं बस उपयोग करने की कोशिश कर रहा हूं grunt-steroids, और उस पर विकसित नहीं हूं ।

लेकिन फिर हमारे पास " सहकर्मी निर्भरता " है।

ये [rootfolder] / node_modules में स्थापित हैं , और मुझे समझ नहीं आ रहा है कि क्यों और इसमें [rootfolder] / node_modules / grunt-steroids / node_modules इसलिए नहीं हैं ताकि अन्य स्टंट प्लग (या जो भी) से बचा जाए?

जवाबों:


421

टीएल; डीआर: [1] peerDependencies निर्भरता के लिए हैं, जो कि "निजी" निर्भरता के विरोध में उपभोग कोड के रूप में (और इसका उपयोग किए जाने की उम्मीद है) उजागर नहीं हैं, और केवल एक कार्यान्वयन विवरण हैं।

समस्या सहकर्मी निर्भरताएँ हल करते हैं

एनपीएम का मॉड्यूल सिस्टम पदानुक्रमित है। सरल परिदृश्यों के लिए एक बड़ा फायदा यह है कि जब आप एक npm पैकेज स्थापित करते हैं, तो यह पैकेज इसके साथ अपनी निर्भरता लाता है इसलिए यह बॉक्स से बाहर काम करेगा।

लेकिन जब समस्याएं आती हैं:

  • आपकी परियोजना और आपके द्वारा उपयोग किए जा रहे कुछ मॉड्यूल, दूसरे मॉड्यूल पर निर्भर हैं।
  • तीनों मॉड्यूल को एक-दूसरे से बात करनी होगी।

उदाहरण में

मान लें कि आप निर्माण कर रहे हैं YourCoolProjectऔर आप दोनों का उपयोग कर रहे हैं JacksModule 1.0और JillsModule 2.0। और मान लें कि JacksModuleयह भी निर्भर करता है JillsModule, लेकिन एक अलग संस्करण पर, कहते हैं 1.0। जब तक वे 2 संस्करण नहीं मिलते, कोई समस्या नहीं है। तथ्य यह JacksModuleहै कि JillsModuleसतह के नीचे उपयोग कर रहा है सिर्फ एक कार्यान्वयन विस्तार है। हम JillsModuleदो बार बंडल कर रहे हैं , लेकिन जब हम बॉक्स से बाहर स्थिर सॉफ़्टवेयर प्राप्त करते हैं, तो भुगतान करने की एक छोटी सी कीमत होती है।

लेकिन अब क्या होगा अगर किसी तरह से JacksModuleइसकी निर्भरता को उजागर किया जाए JillsModule। यह उदाहरण के JillsClassलिए एक उदाहरण को स्वीकार करता है ... क्या होता है जब हम पुस्तकालय का new JillsClassउपयोग कर संस्करण बनाते हैं 2.0और इसके साथ गुजरते हैं jacksFunction? सब नर्क टूट जाएगा! जैसी साधारण चीजें jillsObject instanceof JillsClassअचानक वापस आ जाएंगी falseक्योंकि jillsObjectवास्तव में दूसरे का उदाहरण है JillsClass, 2.0संस्करण।

कैसे सहकर्मी निर्भरता इसे हल करते हैं

वे एन.पी.एम.

मुझे इस पैकेज की आवश्यकता है, लेकिन मुझे उस संस्करण की आवश्यकता है जो परियोजना का हिस्सा है, न कि कुछ संस्करण मेरे मॉड्यूल के लिए निजी।

जब एनपीएम देखता है कि आपका पैकेज एक ऐसी परियोजना में स्थापित किया जा रहा है जिसमें उस निर्भरता नहीं है, या इसका कोई असंगत संस्करण है, तो यह उपयोगकर्ता को स्थापना प्रक्रिया के दौरान चेतावनी देगा।

आपको पीयर निर्भरता का उपयोग कब करना चाहिए?

  • जब आप अन्य परियोजनाओं द्वारा उपयोग किए जाने के लिए एक पुस्तकालय का निर्माण कर रहे हैं, और
  • यह लाइब्रेरी कुछ अन्य लाइब्रेरी का उपयोग कर रही है, और
  • आप उपयोगकर्ता से उस अन्य पुस्तकालय के साथ भी काम करने की अपेक्षा / अपेक्षा करते हैं

सामान्य परिदृश्य बड़े चौखटे के लिए प्लगइन्स हैं। गुल, ग्रंट, बैबेल, मोचा, आदि जैसी चीजों के बारे में सोचें। यदि आप एक गुल प्लगइन लिखते हैं, तो आप चाहते हैं कि वह प्लगइन उसी गुल के साथ काम करे जो उपयोगकर्ता प्रोजेक्ट का उपयोग कर रहा है, न कि अपने स्वयं के निजी संस्करण के साथ।


एनोटेशन

  1. बहुत लंबा; नहीं पढ़ा। एक पाठ के लिए एक छोटे सारांश को इंगित करने के लिए उपयोग किया जाता है जिसे किसी ने बहुत लंबा समझा है।

2
एक महत्वपूर्ण बात जो मैंने देखी और कहीं भी नहीं कही, जब हम एक प्लगइन का निर्माण कर रहे हैं, तो क्या हमें सहकर्मी निर्भरता के लिए पैकेज निर्भरता का डुप्लिकेट होना चाहिए? ओपी उदाहरण में, हम देख सकते हैं कि "grunt": "0.4.4"दोनों निर्भरता और सहकर्मी निर्भरता में हैं, और यह मेरे लिए समझ में आता है कि वहां एक डुप्लिकेट है, क्योंकि इसका मतलब है कि दोनों gruntको मेरे अपने उपयोग के लिए उस पैकेज की आवश्यकता है , लेकिन यह भी कि मेरे उपयोगकर्ता पुस्तकालय अपने स्वयं के संस्करण का उपयोग कर सकते हैं, जब तक कि यह सहकर्मी निर्भरता संस्करण लॉक का सम्मान करता है। क्या वो सही है? या ओपी उदाहरण बहुत बुरा है?

4
मैं कल्पना कर सकता हूं कि लोग ग्रंट प्लग इन ग्रंट के प्रशंसक बन रहे हैं :) जैसे कि उनके लिए ग्रंट का उपयोग करना स्वाभाविक लगता है अपने प्लगइन की निर्माण प्रक्रिया के लिए .... लेकिन वे ग्रंट वर्जन को लॉक क्यों करना चाहते हैं, उनके प्लगइन काम करता है निर्माण प्रक्रिया के साथ वे इसे बनाने के लिए उपयोग करते हैं? एक देव निर्भरता के रूप में इसे जोड़ने से उन्हें इस को कम करने की अनुमति मिलती है। मूल रूप से 2 चरण होते हैं: समय बनाएँ और समय चलाएँ। निर्माण समय के दौरान देव निर्भरता की आवश्यकता होती है। नियमित और सहकर्मी निर्भरता की जरूरत है। निश्चित रूप से निर्भरता की निर्भरता के साथ सब कुछ तेजी से भ्रामक हो जाता है :)
Stijn de Witt

1
इस उत्तर के लिए धन्यवाद! बस स्पष्ट करने के लिए, आपके उदाहरण में, अगर एक सहकर्मी निर्भरता होने के साथ JacksModuleनिर्भर करता है और उपयोग कर रहा है और , हम एनपीएम द्वारा सहकर्मी निर्भरता चेतावनी प्राप्त करेंगे, जो हमें भी स्थापित करने की सलाह देगा । लेकिन तब क्या होता है? अब आयात के दो संस्करण होंगे ? और मुझे कैसे याद है कि जब मैं उपयोग करता हूं तो मुझे इसका एक उदाहरण पारित करने की आवश्यकता होती है ? JillsModule ^1.0.0JillsModuleJacksModuleYourCoolProjectJacksModuleJillsModule ^2.0.0JillsModule ^1.0.0YourCoolProjectJillsModuleimport jillsModule from "..."JacksModuleJillsModule v1.0.0
टोनिक्स

1
@tonix खैर, यह वास्तव में एक समस्या होगी कि आपके पास एक संस्करण असंगति है। सहकर्मी निर्भरता से हल नहीं होता है। लेकिन यह समस्या को स्पष्ट करने में मदद करता है। क्योंकि यह दो संस्करणों को चुपचाप उपयोग करने के बजाय स्पष्ट रूप से संस्करण बेमेल दिखाएगा। पुस्तकालयों का चयन करने वाले ऐप डेवलपर को इसका समाधान खोजना होगा।
स्टिजेन डे विट

2
@tonix या तीसरा विकल्प: JacksModuleरेपो का क्लोन , इस पर निर्भर करने के लिए इसे अपग्रेड करें JillsModule ^2.0.0और प्रोजेक्ट अनुरक्षक को एक पीआर प्रदान करें। यह कहते हुए कि यह निर्भरता पुरानी है, पहले एक बग सबमिट करने में मदद मिल सकती है और आप इसे अपडेट करने में मदद करना चाहेंगे। यदि आप एक अच्छा पीआर बनाते हैं, तो अधिकांश लाइब्रेरी मेंटेनर इसे मर्ज करेंगे और इसके लिए आपको धन्यवाद देंगे। यदि अनुरक्षक अनुत्तरदायी हैं, तो आप अपने कांटे को अपने नाम के तहत NPM नामस्थान पर प्रकाशित कर सकते हैं और इसके बजाय अपने कांटे का उपयोग कर सकते हैं। किसी भी तरह से, वहाँ समाधान कर रहे हैं, लेकिन peerDependenciesइसे खुद ही हल नहीं करता है।
स्टिजन डे विट

26

मैं आपको पहले लेख को फिर से पढ़ने की सलाह दूंगा। यह थोड़ा भ्रमित करने वाला है लेकिन विनस्टन-मेल के साथ उदाहरण आपको इसका उत्तर दिखाता है कि:

उदाहरण के लिए, आइए इसे उस वस्तु में winston-mail@0.2.3निर्दिष्ट होने का ढोंग करें क्योंकि यह नवीनतम संस्करण है, जिसके विरुद्ध परीक्षण किया गया था। डेवलपर के रूप में, आप नवीनतम और सबसे बड़ी सामान चाहते हैं, तो आप के नवीनतम संस्करण को देखने और की और उन्हें के रूप में अपने package.json में डाल"winston": "0.5.x""dependencies"winstonwinston-mail

{
  "dependencies": {  
    "winston": "0.6.2",  
    "winston-mail": "0.2.3"  
  }  
}

लेकिन अब, एनपीएम चलने से अप्रत्याशित निर्भरता के ग्राफ में परिणाम मिलते हैं

├── winston@0.6.2  
└─┬ winston-mail@0.2.3                
  └── winston@0.5.11

इस मामले में, पैकेज के कई संस्करण होना संभव है जो कुछ मुद्दों का कारण होगा। सहकर्मी निर्भरताएं npm डेवलपर्स को यह सुनिश्चित करने की अनुमति देती हैं कि उपयोगकर्ता के पास विशिष्ट मॉड्यूल (रूट फ़ोल्डर में) है। लेकिन आप इस बिंदु के साथ सही हैं कि पैकेज के एक विशिष्ट संस्करण का वर्णन करने से अन्य संस्करणों के उपयोग से अन्य पैकेज के साथ समस्याएँ पैदा होंगी। यह समस्या npm डेवलपर्स के साथ है, जैसा कि लेख बताता है

सलाह का एक टुकड़ा : सहकर्मी निर्भरता आवश्यकताओं, नियमित निर्भरता के लिए उन लोगों के विपरीत, उदार होना चाहिए । आपको अपने सहकर्मी निर्भरता को विशिष्ट पैच संस्करणों में बंद नहीं करना चाहिए।

इसलिए डेवलपर्स को सहकर्मी निर्भरता को परिभाषित करने के लिए सेवर का पालन करना चाहिए । आपको GitHub पर ग्रंट-स्टेरॉयड पैकेज के लिए एक समस्या खोलनी चाहिए ...


1
आप कहते हैं कि multiple versions of a package which would cause some issuesलेकिन यह पैकेज मैनेजर की पूरी बात नहीं है? वे आगे भी इसी लेख में चर्चा करते हैं जहां परियोजना में एक ही पैकेज के 2 संस्करण हैं: एक डेवलपर द्वारा प्रदान किया गया और दूसरा 3 पार्टी लाइब्रेरी द्वारा आपूर्ति किया गया।
एडम बेक

1
मुझे लगता है कि मैं सहकर्मी की निर्भरता की बात समझता हूं, लेकिन winstonउदाहरण में क्या मैं अभी winston-mailपुस्तकालय का उपयोग करने में असमर्थ हूं क्योंकि मेरा संस्करण सहकर्मी की निर्भरता से मेल नहीं खाता है? मैं बहुत अधिक है कि 1 पुस्तकालय के लिए नवीनतम और सबसे बड़ी से अस्थायी डाउनग्रेड की तुलना में इसका उपयोग करने में सक्षम नहीं होना चाहिए।
एडम बेक

1
आपकी पहली टिप्पणी के लिए, जहां तक ​​मैं समझता हूं और इसका उपयोग करता हूं, यह परीक्षण के साथ करना है, उदाहरण के लिए यदि आपके पास एक पैकेज है जिसे आपके द्वारा विशिष्ट 3 पार्टी पैकेज के लिए परीक्षण किया गया है, तो आप सुनिश्चित नहीं हो सकते कि यदि कोई है आपकी निर्भरताएं बदल जाती हैं (बग फिक्स, प्रमुख सुविधा अद्यतन) जो आपका पैकेज काम करेगा। इसलिए, आप एक विशिष्ट प्लगइन संस्करण निर्दिष्ट कर सकते हैं और अपने परीक्षणों से बचा सकते हैं।
फेर टू

1
आपकी दूसरी टिप्पणी पर: यही कारण है कि वे डॉक्स में कहते हैं कि डेवलपर्स को अपने पैकेज निर्भरता के साथ उदार होना चाहिए और "0.2.1", "~ 0.2.1" के बजाय वीर्य का उपयोग करना चाहिए -> "0.2.x" की अनुमति देता है लेकिन "0.3.x" नहीं, या "> = 0.2.1" -> "0.2.x" से "1.x" या "x.2.2" सब कुछ। .. (लेकिन npm पैकेज के लिए वास्तव में बेहतर नहीं होगा ~
Fer To

15

peerDependencies सबसे सरल उदाहरण के साथ समझाया गया है:

{
  "name": "myPackage",
  "dependencies": {
    "foo": "^4.0.0",
    "react": "^15.0.0"
  }
}


{
  "name": "foo"
  "peerDependencies": {
    "react": "^16.0.0"
  }
}

myPackage में npm इंस्टॉल चलाने से कोई त्रुटि आएगी क्योंकि यह रिएक्ट संस्करण को स्थापित करने की कोशिश कर रहा है ^15.0.0और fooजो केवल रिएक्ट के अनुकूल है ^16.0.0

सहकर्मी निर्भरता स्थापित नहीं हैं।


क्यों नहीं सिर्फ 16 फू के अंदर एक dep के रूप में प्रतिक्रिया 16 डाल दिया? इस तरह से दोनों 15 और 16 avaiable होगा और foo 16 का उपयोग कर सकते हैं और mypackage 15 का उपयोग कर सकते हैं?
नाइटिंस 99

React एक ऐसा ढांचा है जिसे रनटाइम में बूटस्ट्रैप किया जाता है, इसके लिए दोनों React 15 और React 16 को एक ही पृष्ठ पर मौजूद करने के लिए आपको दोनों को एक साथ बढ़ावा देने की आवश्यकता होगी जो अंतिम उपयोगकर्ता के लिए बहुत भारी और समस्याग्रस्त होगा। यदि fooReact 15 और React 16 दोनों के साथ काम करता है तो यह अपनी सहकर्मी क्षमता को सूचीबद्ध कर सकता है>=15 < 17
जेन्स बोडल

nitinsh99 मेरा जवाब संभव उदाहरण के साथ सहकर्मी के उद्देश्य को स्पष्ट करना था, न कि कैसे सहकर्मी द्वारा फेंकी गई त्रुटि से छुटकारा पाया जाए
क्रिस्टोफर टोकर

पैकेज निर्भरता के अंदर @ nitinsh99 रिएक्शन जोड़ने से हुक की तरह मुद्दा मिलेगा - एक पैकेज में कई प्रतिक्रियाएं
मसूद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.