В чем разница между зависимостями, devDependencies и peerDependencies в пакете npm.файл json?

документация отвечает на мой вопрос очень плохо. Я не понял этих объяснений. Кто-нибудь может сказать проще? Может быть, с примерами, если трудно выбрать простые слова?

10 ответов


резюме важных различий в поведении:

  • dependencies установленных на обоих:

    • npm install из каталога, содержащего package.json
    • npm install $package в любом другом каталоге
  • devDependencies являются:

    • также установлен на npm install в каталоге, который содержит package.json, если вы проходите --production флаг (перейти вверх Гаян Charith это).
    • не установлен на npm install "$package" в любом другом каталоге, если вы не дадите ему .
    • не устанавливаются транзитивно.
  • peerDependencies:

    • до 3.0: всегда устанавливаются, если отсутствует, и вызывают ошибку, если несколько несовместимых версий зависимости будут использоваться разными зависимости.
    • ожидается, что начиная с 3.0 (непроверено): дайте предупреждение, если отсутствует на npm install, и вы должны решить зависимость самостоятельно вручную. При запуске, если зависимость отсутствует, вы получаете сообщение об ошибке (упомянутое @nextgentech)
  • транзитивность (упоминается Бен Хатчинсон):

    • dependencies устанавливаются транзитивно: если A требует B, и B требуется C, затем c устанавливается, иначе B не может работать, и A.

    • devDependencies не устанавливаются транзитивно. Е. Г. нам не нужно Тест Б чтобы проверить, так что зависимости B-тестирования могут быть опущены.

опции не обсуждаются здесь:

в разделе devDependencies

dependencies требуются для запуска, devDependencies только для разработки, например: модульные тесты, CoffeeScript для транспиляции Javascript, minification, ...

если вы собираетесь разработать пакет, загрузите его (например, через git clone), перейдите к его корню, который содержит package.json, а

npm install

так как у вас фактический источник, понятно, что вы хотите его разработать, поэтому по умолчанию оба dependencies (так как вы, конечно, должны работать, чтобы развиваться) и devDependency зависимости также установлены.

Если, однако, вы только конечный пользователь, который просто хочет установить пакет, чтобы использовать его, вы будете делать из любого каталога:

npm install "$package"

в этом случае вы обычно не хотите зависимостей разработки, поэтому вы просто получаете то, что необходимо для использования пакета: dependencies.

если вы действительно хотите установить пакеты разработки в этом случае, вы можете установить 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 peer зависит от dependency3, дереве проекта будет выглядеть так:

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

это происходит, хотя вы никогда не упоминаете dependency3 в своем .

я думаю, что это экземпляр инверсия управления шаблон дизайна.

прототипическим примером одноранговых зависимостей является Grunt, хост и его плагины.

например, на плагине Grunt, таком как https://github.com/gruntjs/grunt-contrib-uglify, вы увидите, что:

  • grunt это peerDependency
  • только require('grunt') под tests/: это на самом деле не используется программой.

потом, когда пользователь будет использовать плагин, он будет неявно требовать плагин от Gruntfile добавить grunt.loadNpmTasks('grunt-contrib-uglify') линия, но это grunt что пользователь будет звонить напрямую.

это не сработало бы, если бы каждый плагин требовал другой версии Grunt.

руководство

я думаю, что doc отвечает на вопрос довольно хорошо, возможно, вы недостаточно знакомы с менеджерами узлов / других пакетов. Я, вероятно, понимаю это только потому, что знаю немного о Ruby упаковщик.

ключи:

эти вещи будут установлены при выполнении npm link или npm install из корня пакета и могут управляться как любой другой параметр конфигурации npm. Увидеть НПМ-конфиг(7) для более по теме.

а затем в npm-config (7) Найдите dev:

Default: false
Type: Boolean

Install dev-dependencies along with packages.

Если вы не хотите устанавливать devDependencies, вы просто можете использовать npm install --production


в качестве примера mocha обычно будет devDependency, так как тестирование не требуется в производстве, в то время как express будет зависимостью.


сохранить пакет пакета.в JSON как зависимости dev:

npm install "$package" --save-dev

при выполнении npm install он установит оба devDependencies и dependencies. Чтобы избежать установки devDependencies run:

npm install --production

есть некоторые модули и пакеты, необходимые только для развития, которые не нужны в производстве. Как говорится в документация:

Если кто-то планирует загрузить и использовать ваш модуль в своей программе, то они, вероятно, не хотят или не должны загружать и создавать внешнюю среду тестирования или документации, которую вы используете. В этом случае лучше всего перечислить эти дополнительные элементы в хэше devDependencies.


зависимости
Зависимости, которые необходимо запустить проекту, например библиотека, предоставляющая функции, вызываемые из кода.
Они устанавливаются транзитивно (если A зависит от B зависит от C, npm install on A установит B и C).
пример: lodash: ваш проект вызывает некоторые функции lodash.

в разделе devDependencies
Зависимости, необходимые только во время разработки или выпуска, например компиляторы, которые принимают ваш код и скомпилируйте его в javascript, тестовые фреймворки или генераторы документации.
Они не устанавливаются транзитивно (если A зависит от B dev-зависит от C, npm install on A установит только B).
пример: grunt: ваш проект использует grunt для создания себя.

peerDependencies
Зависимости, которые ваш проект подключает или изменяет в Родительском проекте, обычно плагин для какой-либо другой библиотеки или инструмента. Оно просто предназначено быть проверьте, что родительский проект (проект, который будет зависеть от вашего проекта) зависит от проекта, в который вы подключаетесь. Поэтому, если вы создаете плагин C, который добавляет функциональность в библиотеку B, то кто-то, делающий проект A, должен будет иметь зависимость от B, если у них есть зависимость от C.
Они не установлены (если только npm пример: grunt: ваш проект добавляет функциональность к grunt и может использоваться только в проектах, которые используют хмыкнуть.

эта документация объясняет одноранговые зависимости очень хорошо:https://nodejs.org/en/blog/npm/peer-dependencies/

кроме того, документация npm была улучшена с течением времени и теперь имеет лучшие объяснения различных типов зависимостей: https://github.com/npm/npm/blob/master/doc/files/package.json.md#devdependencies


простое объяснение, которое сделало его более ясным для меня:

при развертывании приложения необходимо установить модули в зависимостях, иначе приложение не будет работать. Модули в devDependencies не нужно устанавливать на рабочем сервере, так как вы не разрабатываете на этой машине. ссылке


Я хотел бы добавить к ответу мой взгляд на эти объяснения зависимостей

  • dependencies используются для прямого использования в вашей кодовой базе, вещи, которые обычно заканчиваются в производственном коде, или куски кода
  • devDependencies используются для процесса сборки, инструментов, которые помогут вам управлять тем, как закончится код, сторонних тестовых модулей, (ex. webpack stuff)

peerDependencies не совсем имел смысл для меня, пока я не прочитал этот фрагмент из блоге на тему Сиро указано выше:

что [Плагины] нужно-это способ выражения этих зависимостей между плагинами и их хост-пакет. Какой-то способ сказать: "я работаю только при подключении к версии 1.2.x моего хост-пакета, поэтому, если вы установите меня, убедитесь, что он находится рядом с совместимым хостом."Мы называем это отношения одноранговая зависимость.

плагин ожидал конкретная версия хоста...

peerDependencies предназначены для плагинов, библиотек, которые требуют" хост " библиотеки для выполнения своей функции, но, возможно, были написаны в то время до последняя версия хоста была выпущена.

то есть, если я пишу PluginX v1 на HostLibraryX v3 и уйти, нет никакой гарантии PluginX v1 будет работать, когда HostLibraryX v4 (или даже ) является.

... но плагин не зависит на хосте...

С точки зрения плагина, это только добавляет функции для размещения библиотеки. Мне действительно "не нужен" хост, чтобы добавить зависимость к плагину, и плагины часто не буквально зависит на их хозяина. Если у вас нет хоста, плагин безвредно ничего не делает.

это значит dependencies не правильная концепция для плагинов.

еще хуже, если бы мой хозяин рассматривался как зависимость, мы бы оказались в этой ситуации, что в том же блоге упоминается (отредактировано немного, чтобы использовать этот ответ, составленный host & plugin):

но теперь, [если мы рассматриваем современную версию HostLibraryX как зависимость для PluginX,] работает npm install приводит к неожиданному графику зависимостей

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

я оставлю тонкий сбои, которые происходят из плагина, используя другой API [HostLibraryX], чем основное приложение для вашего воображения.

... и хозяин, очевидно, не зависит от плагина...

... в этом весь смысл плагинов. Теперь, если хозяин был достаточно хорош, чтобы включить информацию о зависимостях для все своих плагинов, что бы решить проблему, но это также представит огромную новую культурную проблему: управление плагинов!

весь смысл плагинов в том, что они могут объединяться анонимно. В идеальном мире, имея хозяина управлять ими все было бы аккуратно и аккуратно, но мы не собираемся требовать библиотеки стадных кошек.

если мы не иерархически зависимых, может быть, мы ровесники intradependent...

вместо этого, у нас есть такое понятие, как сверстники. Ни хост, ни плагин не находятся в ведре зависимостей другого. Оба живут на одном и том же уровне зависимости диаграмма.

... но это не автоматические отношения.

если я PluginX v1 и ожидал Пэр (то есть,имейте peerDependency) HostLibraryX v3, Я так и скажу. Если вы автоматически обновили до последней HostLibraryX v4 (обратите внимание, что версия 4) и есть Plugin v1 установлен, вам нужно знать, верно?

npm не могу справиться с этой ситуацией для меня --

"Эй, я вижу, вы используете PluginX v1! Я автоматически понижаюHostLibraryX от v4 до v3, КК?"

... или...

"Эй, я вижу, вы используете PluginX v1. Что ожидает HostLibraryX v3, который вы оставили в пыли во время последнего обновления. Чтобы быть в безопасности, я автоматически удаляю Plugin v1!!1!

как насчет нет, НПМ?!

так npm не делает. Он предупреждает Вас о ситуации и позволяет вам понять если HostLibraryX v4 является подходящим пэром для Plugin v1.


кода

хороший peerDependency управление в плагинах сделает эту концепцию более интуитивно понятной на практике. От в блоге, еще раз...

один совет: требования к одноранговой зависимости, в отличие от требований для регулярных зависимостей, должны быть снисходительными. Вы не должны блокировать свои одноранговые зависимости до определенных версий исправлений. Было бы очень досадно, если бы один плагин Chai peer-зависел от Chai 1.4.1, в то время как другой зависел от Chai 1.5.0, просто потому, что авторы были ленивы и не тратили время на выяснение фактической минимальной версии Chai, с которой они совместимы.


при попытке распространения пакета npm следует избегать использования dependencies. Вместо этого вам нужно рассмотреть возможность добавления его в peerDependencies или удалить его из dependencies.