В чем разница между зависимостями, devDependencies и peerDependencies в пакете npm.файл json?
документация отвечает на мой вопрос очень плохо. Я не понял этих объяснений. Кто-нибудь может сказать проще? Может быть, с примерами, если трудно выбрать простые слова?
10 ответов
резюме важных различий в поведении:
-
dependencies
установленных на обоих:-
npm install
из каталога, содержащегоpackage.json
-
npm install $package
в любом другом каталоге
-
-
devDependencies
являются:- также установлен на
npm install
в каталоге, который содержитpackage.json
, если вы проходите--production
флаг (перейти вверх Гаян Charith это). - не установлен на
npm install "$package"
в любом другом каталоге, если вы не дадите ему . - не устанавливаются транзитивно.
- также установлен на
-
- до 3.0: всегда устанавливаются, если отсутствует, и вызывают ошибку, если несколько несовместимых версий зависимости будут использоваться разными зависимости.
-
ожидается, что начиная с 3.0 (непроверено): дайте предупреждение, если отсутствует на
npm install
, и вы должны решить зависимость самостоятельно вручную. При запуске, если зависимость отсутствует, вы получаете сообщение об ошибке (упомянутое @nextgentech)
-
транзитивность (упоминается Бен Хатчинсон):
dependencies
устанавливаются транзитивно: если A требует B, и B требуется C, затем c устанавливается, иначе B не может работать, и A.devDependencies
не устанавливаются транзитивно. Е. Г. нам не нужно Тест Б чтобы проверить, так что зависимости B-тестирования могут быть опущены.
опции не обсуждаются здесь:
-
bundledDependencies
который обсуждается по следующему вопросу:преимущества bundledDependencies над нормальными зависимостями в NPM -
optionalDependencies
(упоминается Эйдана Фельдмана)
в разделе 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
.