В чем разница между зависимостями, 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.