it-swarm.asia

ما هو الفرق بين التبعيات و devDependencies و peerDependencies في ملف npm package.json؟

هذه الوثائق إجابات سؤالي سيئة للغاية. لم أفهم تلك التفسيرات. يمكن للشخص أن يقول بكلمات أبسط؟ ربما مع أمثلة إذا كان من الصعب اختيار كلمات بسيطة؟

EDITأضاف أيضًا peerDependencies ، والذي يرتبط ارتباطًا وثيقًا وقد يسبب التشويش.

1728
Vitalii Korsakov

ملخص الاختلافات السلوك الهامة:

  • dependenciesNAME_ مثبت على الاثنين:

    • npm install من دليل يحتوي على package.json
    • npm install $package في أي دليل آخر
  • devDependenciesNAME_ هي:

    • تم تثبيته أيضًا على npm install في دليل يحتوي على package.json ، إلا إذا قمت بتمرير علامة --production (انتقل إلى التصويت على التصويت إجابة Gayan Charith ].
    • لم يتم تثبيته على npm install "$package" في أي دليل آخر ، إلا إذا أعطيته الخيار --dev.
    • لم يتم تثبيتها بشكل مؤقت.
  • peerDependenciesNAME_ :

    • قبل الإصدار 3.0: يتم تثبيته دائمًا في حالة فقده ، ويرفع خطأ إذا كان سيتم استخدام إصدارات متعددة غير متوافقة من التبعية بواسطة تبعيات مختلفة.
    • من المتوقع أن تبدأ في 3.0 (لم يتم اختباره): أعط تحذيرًا في حالة فقده في npm install ، وعليك حل التبعية بنفسك يدويًا. عند التشغيل ، إذا كانت التبعية مفقودة ، فستحصل على خطأ (ذكر بواسطة nextgentech )
  • انتقالية (ذكرها بن هوتشيسون ):

    • dependenciesمثبتة بشكل عابر: إذا تطلبت A B ، و B تتطلب C ، ثم C تحصل على تثبيت ، وإلا ، B لا يمكن أن تعمل ، ولن أ.

    • لم يتم تثبيت devDependenciesبشكل عابر. مثلا لا نحتاج إلى اختبار B لاختبار A ، لذلك يمكن استبعاد تبعيات اختبار B.

خيارات ذات صلة لم تناقش هنا:

devDependencies

dependenciesمطلوبة للتشغيل ، devDependenciesفقط للتطوير ، على سبيل المثال: اختبارات الوحدة ، CoffeeScript to JavaScript transpilation ، minification ، ...

إذا كنت ترغب في تطوير حزمة ، فقم بتنزيلها (على سبيل المثال عبر git clone) ، انتقل إلى جذرها الذي يحتوي على package.json ، وقم بتشغيل:

npm install

نظرًا لأن لديك المصدر الفعلي ، فمن الواضح أنك ترغب في تطويره ، لذلك بشكل افتراضي ، يتم أيضًا تثبيت كل من dependencies(بما أنه يجب عليك بالطبع تطوير) وتبعات devDependencyأيضًا.

إذا كنت ومع ذلك ، فأنت فقط مستخدم نهائي يريد فقط تثبيت حزمة لاستخدامها ، فستفعل من أي دليل:

npm install "$package"

في هذه الحالة ، لا تريد عادة تبعية التطوير ، لذلك يمكنك الحصول على ما هو مطلوب لاستخدام الحزمة: dependenciesname__.

إذا كنت تريد حقًا تثبيت حزم التطوير في هذه الحالة ، يمكنك تعيين خيار التكوين devإلى true، ربما من سطر الأوامر على النحو التالي:

npm install "$package" --dev

الخيار هو falseافتراضيًا لأن هذه الحالة أقل شيوعًا.

peerDependencies

(تم اختباره قبل 3.0)

المصدر: https://nodejs.org/en/blog/npm/peer-dependencies/

باستخدام التبعيات العادية ، يمكنك الحصول على إصدارات متعددة من التبعية: يتم تثبيته ببساطة داخل node_modules من التبعية.

مثلا إذا كان كل من dependency1 و dependency2 كلاهما يعتمد على dependency3 في إصدارات مختلفة ، فستبدو شجرة المشروع كما يلي:

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

الإضافات ، مع ذلك ، هي حزم لا تتطلب عادة الحزمة الأخرى ، والتي تسمى المضيف في هذا السياق. في حين أن:

  • الإضافات مطلوبة من قبل المضيف
  • تقدم الإضافات واجهة قياسية يتوقع المضيف العثور عليها
  • سيتم استدعاء المضيف فقط مباشرة من قبل المستخدم ، لذلك يجب أن يكون هناك إصدار واحد منه.

مثلا إذا كان نظير dependency1 و dependency2 يعتمدان على dependency3 ، فإن شجرة المشروع ستبدو كما يلي:

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

يحدث هذا على الرغم من أنك لم تذكر dependency3 أبدًا في ملف package.json الخاص بك.

أعتقد أن هذا مثال على نمط تصميم Inversion of Control .

ومن الأمثلة النموذجية على تبعيات الأقران هي Grunt ، والمضيف ، ومكوناته الإضافية.

على سبيل المثال ، في المكون الإضافي Grunt مثل https://github.com/gruntjs/grunt-contrib-uglify ، سترى ما يلي:

  • gruntهو peer-dependency
  • الوظيفة require('grunt') فقط هي تحت tests/: لا يستخدمه البرنامج فعليًا.

بعد ذلك ، عندما يستخدم المستخدم مكوّنًا إضافيًا ، سيطلب ضمنيًا المكوّن الإضافي من Gruntfileعن طريق إضافة سطر grunt.loadNpmTasks('grunt-contrib-uglify') ، لكن gruntسيتصل به المستخدم مباشرةً.

لن ينجح هذا إذا كان كل مكون إضافي يتطلب إصدارًا مختلفًا من Grunt.

كتيب

أعتقد أن الوثائق تجيب على السؤال جيدًا ، ربما لم تكن على دراية كافية بما يكفي مع مديري الحزم/العقدين الآخرين. ربما أفهمها فقط لأني أعرف القليل عن روبي بوندلر.

الخط الرئيسي هو:

سيتم تثبيت هذه الأشياء عند إجراء ارتباط npm أو تثبيت npm من جذر الحزمة ويمكن إدارتها مثل أي معلمة أخرى لتهيئة npm. انظر npm-config (7) لمعرفة المزيد حول هذا الموضوع.

ثم ضمن npm-config (7) ، ابحث عن devname__:

Default: false
Type: Boolean

Install dev-dependencies along with packages.

إذا كنت لا ترغب في تثبيت devDependencies ، يمكنك استخدام npm install --production

418
Gayan Charith

على سبيل المثال ، عادةً ما يكون الموكا "devDependency" ، لأن الاختبار ليس ضروريًا في الإنتاج ، في حين أن "إكسبريس" ستكون تبعية.

99
Dan Kohn

لحفظ حزمة إلى package.json كـ تبعيات dev:

npm install "$package" --save-dev

عندما تقوم بتشغيل npm install ، فسوف يقوم بتثبيت devDependencies و dependencies. لتجنب تثبيت devDependencies run:

npm install --production
58
Mohammed Safeer

التبعيات
تبعيات يحتاج مشروعك إلى تشغيلها ، مثل مكتبة توفر وظائف تستدعيها من الكود.
يتم تثبيتها بشكل متقاطع (إذا كان يعتمد A على B يعتمد على C ، تثبيت npm على A سيتم تثبيت B و C).
مثال: lodash: يدعو مشروعك بعض وظائف lodash.

devDependencies
التبعيات التي تحتاجها فقط أثناء التطوير أو الإصدار ، مثل المترجمين الذين يأخذون الكود الخاص بك ويقومون بترجمته إلى جافا سكريبت أو أطر اختبار أو مولدات وثائق.
لم يتم تثبيتها بشكل متقاطع (إذا كان A يعتمد على B dev- يعتمد على C ، تثبيت npm على A سيتم تثبيت B فقط).
مثال: grunt: يستخدم مشروعك grunt لبناء نفسه.

peerDependencies
تبعيات ربط مشروعك أو تعديله في المشروع الأصل ، وعادة ما يكون مكونًا إضافيًا لبعض المكتبات أو الأدوات الأخرى. الغرض منه هو أن يكون مجرد فحص ، والتأكد من أن المشروع الأصل (المشروع الذي سيعتمد على المشروع الخاص بك) لديه تبعية على المشروع الذي تتصل به. لذلك إذا قمت بإنشاء مكون إضافي C يضيف وظيفة إلى المكتبة B ، فسوف يحتاج شخص ما يقوم بمشروع A إلى الاعتماد على B إذا كان لديه اعتماد على C.
لم يتم تثبيتها (ما لم npm <3) ، يتم التحقق منها فقط.
مثال: grunt: يضيف مشروعك وظائف إلى grunt ولا يمكن استخدامه إلا في المشروعات التي تستخدم grunt.

تشرح هذه الوثائق تبعيات النظراء جيدًا: https://nodejs.org/en/blog/npm/peer-dependencies/

أيضًا ، تم تحسين وثائق npm بمرور الوقت ، ولديها الآن تفسيرات أفضل لأنواع مختلفة من التبعيات: https://github.com/npm/cli/blob/latest/doc/files/package.json.md # التبعيات

40
qwertzguy

هناك بعض الوحدات والحزم الضرورية فقط للتطوير ، والتي ليست مطلوبة في الإنتاج. مثل ذلك يقول ذلك في الوثائق :

إذا كان هناك من يخطط لتنزيل الوحدة النمطية الخاصة بك واستخدامها في برنامجهم ، فمن المحتمل أنهم لا يريدون أو يحتاجون إلى تنزيل وبناء إطار الاختبار أو الوثائق الخارجي الذي تستخدمه. في هذه الحالة ، من الأفضل سرد هذه العناصر الإضافية في تجزئة devDependencies.

33
Amberlamps

التفسير البسيط الذي جعل الأمر أكثر وضوحًا بالنسبة لي هو:

عند نشر تطبيقك ، يلزم تثبيت الوحدات النمطية في التبعيات أو لن يعمل التطبيق الخاص بك. لا تحتاج إلى تثبيت الوحدات النمطية في devDependencies على خادم الإنتاج لأنك لا تعمل على تطوير هذا الجهاز. حلقة الوصل

12
Jyoti Duhan

أود أن أضيف إلى الإجابة وجهة نظري بشأن تفسيرات التبعيات هذه

  • dependencies تستخدم للاستخدام المباشر في قاعدة البيانات الخاصة بك ، والأشياء التي عادة ما تنتهي في رمز الإنتاج ، أو أجزاء من التعليمات البرمجية
  • devDependencies تُستخدم في عملية الإنشاء ، والأدوات التي تساعدك على إدارة الكيفية التي سينتهي بها رمز النهاية ، ووحدات اختبار الطرف الثالث ، (مثل عناصر حزمة الويب)
9
Sîrbu Nicolae-Cezar

عند محاولة توزيع حزمة npm ، يجب عليك تجنب استخدام dependencies. بدلاً من ذلك ، عليك التفكير في إضافته إلى peerDependencies أو إزالته من dependencies.

0
Melchia

peerDependencies لم يكن له معنى بالنسبة لي حتى قرأت هذا المقتطف من منشور مدونة حول الموضوع Ciro المذكورة أعلاه :

ما تحتاجه [ plugins ] هو وسيلة للتعبير عن هذه "التبعيات" بين الإضافات وحزمة المضيف الخاصة بهم. بطريقة ما للقول ، "أنا أعمل فقط عند توصيلي بالإصدار 1.2.x من حزمة المضيف الخاصة بي ، لذلك إذا قمت بتثبيت لي ، فتأكد من أنها بجانب مضيف متوافق". نسمي هذه العلاقة تبعية النظراء.

المكوّن الإضافي يفعل {توقع إصدارًا محددًا من المضيف ...

peerDependencies مخصصة للإضافات ، والمكتبات التي تتطلب مكتبة "مضيف" لأداء وظيفتها ، ولكن ربما تمت كتابتها في وقت قبل تم إصدار أحدث إصدار من المضيف.

أي إذا كتبت PluginX v1 لـ HostLibraryX v3 وأبتعدت ، فلا يوجد ضمان بأن PluginX v1 ستعمل عند إصدار HostLibraryX v4 (أو حتى HostLibraryX v3.0.1).

... لكن المكوّن الإضافي لا يعتمد على المضيف ...

من وجهة نظر المكون الإضافي ، يعمل فقط يضيف إلى مكتبة المضيف. لا أحتاج فعلاً إلى "المضيف" لإضافة تبعية إلى مكون إضافي ، وغالبًا ما لا تستخدم الإضافات حرفيًا {التابعة على مضيفهم. إذا لم يكن لديك المضيف ، لا يقوم البرنامج المساعد بأي شيء بشكل ضار.

هذا يعني أن dependencies ليس المفهوم الصحيح للمكونات الإضافية.

والأسوأ من ذلك ، إذا تمت معاملة مضيفي على أنه تبعية ، فسينتهي بنا الأمر في هذا الموقف الذي يذكر منشور المدونة نفسه (تم تحريره قليلاً لاستخدام هذه الإجابة في Host & plugin):

ولكن الآن ، [إذا تعاملنا مع الإصدار المعاصر من HostLibraryX باعتباره تبعية لـ PluginX ،] فإن تشغيل npm install ينتج عنه رسم تبعي غير متوقع لـ

├── [email protected]
└─┬ [email protected]
  └── [email protected]

سأترك حالات الفشل الطفيفة التي تأتي من المكون الإضافي باستخدام واجهة برمجة تطبيقات [HostLibraryX] مختلفة عن التطبيق الرئيسي لخيالك.

... ومن الواضح أن المضيف لا يعتمد على البرنامج المساعد ...

... هذا هو بيت القصيد من الإضافات. الآن إذا كان المضيف لطيفًا بدرجة كافية لتضمين معلومات التبعية لـ {الكل من المكونات الإضافية الخاصة به ، فهذا سيؤدي إلى حل المشكلة ، لكن سيؤدي ذلك أيضًا إلى ظهور مشكلة ثقافية جديدة ضخمة: إدارة المكونات الإضافية !

بيت القصيد من الإضافات هو أنها يمكن أن تقرن بشكل مجهول. في عالم مثالي ، سيكون وجود إدارة المضيف أمرًا أنيقًا ومرتبًا ، لكننا لن نطلب قطط قطيع من المكتبات.

إذا لم نكن نعتمد بشكل هرمي ، فربما نحن أقراننا ...

بدلاً من ذلك ، لدينا مفهوم كوننا أقرانًا. لا يوجد مضيف أو مكون إضافي في دلو التبعية للطرف الآخر. كلاهما يعيش في نفس المستوى من الرسم البياني التبعية.

... لكن هذه ليست علاقة تلقائية.

إذا كنت PluginX v1 و توقع نظيرًا لـ (أي ، {لدي peerDependency من) HostLibraryX v3 ، فسأقول ذلك. إذا قمت بالترقية التلقائية إلى أحدث HostLibraryX v4 (لاحظ أن الإصدار4) و قمت بتثبيت Plugin v1 ، فهل تحتاج إلى معرفة ، أليس كذلك؟

لا يمكن لـ npm إدارة هذا الموقف بالنسبة لي -

"مهلا ، أرى أنك تستخدم PluginX v1! أقوم تلقائيًا بترقية إصدار HostLibraryX من v4 إلى v3 ، kk؟"

... أو ...

"مهلا ، أشاهد أنك تستخدم PluginX v1. هذا يتوقع HostLibraryX v3 ، الذي تركته في الغبار أثناء التحديث الأخير. لكي تكون آمنًا ، أقوم بإلغاء تثبيت Plugin v1!! 1! تلقائيًا"

ماذا عن لا ، npm ؟!

لذلك npm لا. ينبهك الموقف ، ويتيح لك معرفة ما إذا كان HostLibraryX v4 هو نظير مناسب لـ Plugin v1.


المقطع الختامي

الإدارة الجيدة peerDependency في الإضافات ستجعل هذا المفهوم يعمل بشكل حدسي أكثر في الممارسة العملية. من نشر المدونة ، مرة أخرى ...

نصيحة واحدة: يجب أن تكون متطلبات تبعية الأقران ، على عكس متطلبات التبعيات العادية ، متساهلة. يجب عليك عدم قفل تبعيات نظير الخاص بك إلى إصدارات تصحيح معينة. سيكون من المزعج حقًا أن يعتمد أحد نظرائي المكون الإضافي Chai على Chai 1.4.1 ، بينما اعتمد الآخر على Chai 1.5.0 ، ببساطة لأن المؤلفين كانوا كسولين ولم يقضوا الوقت في معرفة الحد الأدنى الفعلي من إصدار Chai متوافق مع.

0
ruffin

بالمختصر

  1. تبعيات - npm install <package> save-prod instalsl الحزم المطلوبة من قبل التطبيق الخاص بك في بيئة الإنتاج.

  2. DevDependencies - npm install <package> --save-dev يقوم بتثبيت الحزم المطلوبة فقط للتطوير والاختبار المحلي

  3. مجرد كتابة npm install يقوم بتثبيت جميع الحزم المذكورة في package.json

لذلك إذا كنت تعمل على جهاز الكمبيوتر المحلي الخاص بك ، فما عليك سوى كتابة npm install ومتابعة :)

0
cherankrish