Какая разница между зависимостями, devDependencies и peerDependencies в файле npm package.json?
Эта документация очень плохо отвечает на мой вопрос. Я не понял этих объяснений. Может ли кто-нибудь сказать более простые слова? Может быть, с примерами, если трудно выбрать простые слова?
EDIT также добавил peerDependencies
, который тесно связан и может вызвать путаницу.
Ответы
Ответ 1
Резюме важных различий в поведении:
-
dependencies
установлены на обоих:
-
npm install
из каталога, который содержит package.json
-
npm install $package
в любом другом каталоге
-
devDependencies
являются:
- также устанавливается в
npm install
в каталог, который содержит package.json
, если вы не пропустите флаг --production
(go upvote Gayan Charith answer). - не устанавливается в
npm install "$package"
в любом другом каталоге, если вы не --dev
опцию --dev
. - не установлены транзитивно.
-
peerDependencies
:
- до версии 3.0: всегда устанавливаются, если отсутствуют, и выдают ошибку, если различные несовместимые версии будут использовать несколько несовместимых версий зависимости.
- ожидается запуск с версии 3.0 (не проверено): выдает предупреждение, если отсутствует при
npm install
, и вы должны самостоятельно решить эту зависимость. При запуске, если зависимость отсутствует, вы получаете сообщение об ошибке (упомянуто @nextgentech)
-
Транзитивность (упомянутая Беном Хатчисоном):
-
dependencies
устанавливаются транзитивно: если A требует B, а B требует C, то C устанавливается, в противном случае B не может работать, как и A.
-
devDependencies
не устанавливается транзитивно. Например, нам не нужно тестировать B, чтобы тестировать A, поэтому тестирование B-зависимостей можно не учитывать.
Связанные параметры здесь не обсуждаются:
devDependencies
для запуска требуются dependencies
, только для разработки devDependencies
, например: модульные тесты, перенос сценариев CoffeeScript в JavaScript, минификация,...
Если вы собираетесь разрабатывать пакет, вы загружаете его (например, через 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
зависит от 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.
Руководство
Я думаю, что документация достаточно хорошо отвечает на этот вопрос, может быть, вы не просто достаточно знакомы с менеджерами узлов/других пакетов. Я, вероятно, понимаю это только потому, что немного знаю о Ruby-бандлере.
Ключевая строка:
Эти вещи будут установлены при выполнении npm link или npm install из корня пакета и могут управляться как любой другой параметр конфигурации npm. Смотрите npm-config (7) для более подробной информации по теме.
А затем в npm-config (7) найдите dev
:
Default: false
Type: Boolean
Install dev-dependencies along with packages.
Ответ 2
Если вы не хотите устанавливать devDependencies, вы можете использовать npm install --production
Ответ 3
В качестве примера, мокко, как правило, является devDependency, поскольку тестирование не требуется в производстве, а выражение - зависимость.
Ответ 4
Чтобы сохранить пакет в package.json как зависимости dev:
npm install "$package" --save-dev
Когда вы запустите npm install
он установит как devDependencies
и dependencies
. Чтобы избежать установки devDependencies
выполните:
npm install --production
Ответ 5
зависимости
Зависимости, которые должен запускать ваш проект, например, библиотека, предоставляющая функции, которые вы вызываете из своего кода.
Они устанавливаются транзитивно (если A зависит от B, зависит от C, npm install на A установит B и C).
Пример: lodash: ваш проект вызывает некоторые функции lodash.
devDependencies
Зависимости, которые вам нужны только во время разработки или выпуска, например, компиляторы, которые берут ваш код и компилируют его в javascript, тестовые среды или генераторы документации.
Они не устанавливаются транзитивно (если A зависит от B, dev зависит от C, npm install на 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#devdependencies
Ответ 6
Существуют некоторые модули и пакеты, необходимые только для разработки, которые не нужны в производстве. Как говорится в документации:
Если кто-то планирует загрузить и использовать ваш модуль в своей программе, то они, вероятно, не хотят или не должны загружать и создавать внешнюю среду тестирования или документации, которые вы используете. В этом случае лучше всего перечислить эти дополнительные элементы в хеше dev.developments.
Ответ 7
Простое объяснение, которое сделало его более понятным для меня:
При развертывании приложения необходимо установить модули в зависимости или приложение не будет работать. Модули в devDependencies не должны устанавливаться на производственном сервере, так как вы не разрабатываете на этой машине. ссылка на сайт
Ответ 8
Я хотел бы добавить к ответу мое мнение об этих объяснениях зависимостей
-
dependencies
используются для прямого использования в вашей кодовой базе, вещи, которые обычно заканчиваются производственным кодом, или куски кода -
devDependencies
используются для процесса сборки, инструменты, которые помогут вам управлять тем, как закончится конечный код, сторонние тестовые модули (например, веб файлы)
Ответ 9
peerDependencies
не имеет для меня peerDependencies
смысла, пока я не прочитаю этот фрагмент из сообщения в блоге по теме Ciro, упомянутой выше:
Что нужно [ плагинам ] - это способ выражения этих "зависимостей" между плагинами и их пакетом хоста. Некоторый способ сказать: "Я работаю только при подключении к версии 1.2.x моего пакета хоста, поэтому, если вы установите меня, убедитесь, что он вместе с совместимым хостом". Мы называем это отношение равным.
Плагин ожидает определенную версию хоста...
peerDependencies
для плагинов, библиотеки, которым требуется библиотека "хост" для выполнения своей функции, но могут быть написаны за раз до того, как была выпущена последняя версия хоста.
То есть, если я напишу PluginX v1
для HostLibraryX v3
и уйду, нет гарантии, что PluginX v1
будет работать, когда HostLibraryX v4
(или даже HostLibraryX v3.0.1
).
... но плагин не зависит от хоста...
С точки зрения плагина он только добавляет функции в библиотеку хоста. Мне не нужен "хост", чтобы добавить зависимость к плагину, а плагины часто не зависят от их хоста. Если у вас нет хоста, плагин безобидно ничего не делает.
Это означает, что dependencies
не совсем правильная концепция для плагинов.
Хуже того, если мой хозяин рассматривался как зависимость, мы попали бы в эту ситуацию, о которой упоминается в одном и том же блоге (немного отредактированный для использования этого ответа в составе хоста и плагина):
Но теперь [если мы рассматриваем современную версию HostLibraryX как зависимость для PluginX,] запускаем результаты npm install
на графике неожиданной зависимости
├── [email protected]
└─┬ [email protected]
└── [email protected]
Я оставляю тонкие сбои, которые происходят из плагина, используя другой API [HostLibraryX], чем основное приложение для вашего воображения.
... и хост явно не зависит от плагина...
... что весь смысл плагинов. Теперь, если хост был достаточно хорош, чтобы включить информацию о зависимостях для всех своих плагинов, это решило бы проблему, но это также привело бы к огромной новой культурной проблеме: управление плагинами!
Весь смысл плагинов в том, что они могут соединяться анонимно. В идеальном мире, если хозяин будет управлять ими, все будет аккуратно и аккуратно, но мы не будем требовать, чтобы библиотеки стадо-кошек.
Если мы не зависим от иерархии, возможно, мы являемся взаимозависимыми сверстниками...
Вместо этого у нас есть концепция быть сверстниками. Ни хост, ни плагин не находятся в другом контейнере зависимостей. Оба они живут на одном уровне графика зависимостей.
... но это не автоматизированная связь.
Если я являюсь PluginX v1
и ожидаю, что он (то есть, имеет peerDependency of) HostLibraryX v3
, я скажу так. Если вы обновили версию до последней HostLibraryX v4
(обратите внимание, что версия 4) И установите Plugin v1
, вам нужно знать, правильно?
npm
не может справиться с этой ситуацией для меня -
"Эй, я вижу, вы используете PluginX v1
! Я автоматически HostLibraryX
рейтинг HostLibraryX
с v4 до v3, kk?"
... или же...
"Привет, я вижу, что вы используете PluginX v1
который ожидает HostLibraryX v3
, который вы оставили в пыли во время последнего обновления. Чтобы быть в безопасности, я автоматически удаляю Plugin v1
!! 1!
Как насчет нет, нпм?!
Так что npm не делает. Он предупреждает вас об этой ситуации и позволяет выяснить, является ли HostLibraryX v4
подходящим партнером для Plugin v1
.
кода
Хорошее управление peerDependency
в плагинах заставит эту концепцию работать более интуитивно на практике. Из сообщения в блоге, еще раз...
Один из советов: требования к равным интересам, в отличие от требований для регулярных зависимостей, должны быть снисходительны. Вы не должны блокировать зависимостей сверстников вплоть до конкретных версий патча. Было бы очень неприятно, если бы один плагин Chai зависел от Chai 1.4.1, в то время как другой зависел от Chai 1.5.0, просто потому, что авторы ленивы и не тратили время на выяснение минимальной версии Chai, которые они совместимы с,
Ответ 10
Короче говоря
Зависимости - npm install <package> --save-prod
устанавливает пакеты, необходимые для вашего приложения, в производственную среду.
DevDependencies - npm install <package> --save-dev
устанавливает пакеты требуются только для локальной разработки и тестирования
Просто наберите npm install
, чтобы установить все пакеты, упомянутые в
package.json
так что если вы работаете на локальном компьютере, просто наберите npm install
и продолжайте :)
Ответ 11
Зависимости от dev-зависимостей
Dev-зависимости - это модули, которые требуются только во время разработки, тогда как зависимости требуются во время выполнения. Если вы развертываете свое приложение, необходимо установить зависимости, иначе ваше приложение просто не будет работать. Библиотеки, которые вы вызываете из своего кода, который позволяет запускать программу, могут рассматриваться как зависимости.
Eg- Реагируй, Реагируй - дом
Модули зависимостей Dev не нужно устанавливать на рабочем сервере, так как вы не собираетесь разрабатывать на этом компьютере.компиляторы, которые преобразуют ваш код в javascript, тестовые среды и генераторы документов могут рассматриваться как dev-зависимости, так как они требуются только во время разработки.
Eg- ESLint, Babel, веб-пакет
@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, важно использовать правильный флаг для правильных модулей. Если вам нужно, чтобы ваш модуль npm функционировал, используйте флаг "--save", чтобы сохранить модуль в качестве зависимости. Если ваш модуль не нуждается в функционировании, но необходим для тестирования, используйте флаг "--save -dev".
# For dependent modules
npm install dependent-module --save
# For dev-dependent modules
npm install development-module --save-dev
Ответ 12
При попытке распространения пакета npm вы должны избегать использования dependencies
. Вместо этого вам нужно рассмотреть возможность добавления его в peerDependencies
или удалить его из dependencies
.