it-roy-ru.com

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

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

EDIT также добавил peerDependencies, который тесно связан и может привести к путанице.

1653
Vitalii Korsakov

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

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

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

    • также установлен в npm install в каталоге, который содержит package.json, если вы не передадите флаг --production (go upvote ответ Гаян Чарит ).
    • не устанавливается в npm install "$package" в любом другом каталоге, если вы не укажете ему параметр --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/

Плагины, однако, являются пакетами, которые обычно не требуют другого пакета, который в данном контексте называется Host. Вместо:

  • плагины требуются Host
  • плагины предлагают стандартный интерфейс, который Хозяин ожидает найти
  • только Хост будет вызываться напрямую пользователем, поэтому должна быть одна его версия.

Например. если dependency1 и dependency2 peer зависят от dependency3, дерево проекта будет выглядеть так:

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

Это происходит, даже если вы никогда не упоминаете dependency3 в своем файле package.json.

Я думаю, что это пример Inversion of Control шаблон проектирования.

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

Например, для такого плагина 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.

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

402
Gayan Charith

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

95
dankohn

Чтобы сохранить пакет в package.json как зависимости dev: 

npm install "$package" --save-dev

Когда вы запустите npm install, он установит devDependencies и dependencies. Чтобы избежать установки devDependencies запустите:

npm install --production
55
Mohammed Safeer

зависимости
Зависимости, необходимые вашему проекту, например, библиотека, предоставляющая функции, которые вы вызываете из своего кода.
Они устанавливаются транзитивно (если 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

34
qwertzguy

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

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

33
Amberlamps

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

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

11
Jyoti Duhan

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

  • dependencies используются для непосредственного использования в вашей кодовой базе, вещах, которые обычно заканчиваются в рабочем коде, или фрагментам кода
  • devDependencies используются для процесса сборки, инструменты, которые помогают вам управлять конечным кодом, сторонние тестовые модули (например, материал webpack)
8
Sîrbu Nicolae-Cezar

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

0
Melchia

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

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

Плагин делает ожидаемо конкретную версию Host ...

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

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

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

С точки зрения плагина, он только добавляет функционирует в библиотеке Host. На самом деле мне не «нужен» Хост, чтобы добавить зависимость к плагину, и плагины часто не буквально зависят от своего Хоста. Если у вас нет Хоста, плагин безвредно ничего не делает.

Это означает, что dependencies не совсем подходящая концепция для плагинов. 

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

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

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

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

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

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

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

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

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

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

Если я 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 зависел от 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