В чем разница между зависимостями, devDependencies и peerDependencies в файле npm package.json?
Эта документация очень плохо отвечает на мой вопрос. Я не понял эти объяснения. Кто-то может сказать более простыми словами? Может быть, с примерами, если трудно выбрать простые слова?
РЕДАКТИРОВАТЬ также добавил peerDependencies
, что тесно связано и может привести к путанице.
19 ответов
Резюме важных различий в поведении:
dependencies
установлены на обоих:npm install
из каталога, который содержитpackage.json
npm install $package
в любом другом каталоге
devDependencies
являются:- также установлен на
npm install
в каталоге, который содержитpackage.json
, если вы не пройдете--production
флаг (поднять голос Гаяна Чарита). - не установлен на
npm install "$package"
в любом другом каталоге, если вы не дадите ему--dev
вариант. - не установлены транзитивно.
- также установлен на
peerDependencies
:- до версии 3.0: всегда устанавливаются, если отсутствуют, и выдают ошибку, если различные несовместимые версии будут использовать несколько несовместимых версий зависимости.
- ожидается начиная с версии 3.0 (не проверено): выдает предупреждение, если отсутствует на
npm install
, и вы должны решить эту зависимость самостоятельно. При запуске, если зависимость отсутствует, вы получаете сообщение об ошибке (упомянуто nextgentech)
Транзитивность (упомянутая Беном Хатчисоном):
dependencies
устанавливаются транзитивно: если A требует B, а B требует C, то C устанавливается, в противном случае B не может работать, а также A.devDependencies
не установлены транзитивно. Например, нам не нужно тестировать B для тестирования A, поэтому тестовые зависимости B могут быть опущены.
Связанные параметры здесь не обсуждаются:
bundledDependencies
который обсуждается по следующему вопросу: Преимущества bundledDependencies по сравнению с обычными зависимостями в NPMoptionalDependencies
(упоминается Эйданом Фельдманом)
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
этоpeerDependency
- единственный
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
зависимости
Зависимости, которые должен запускать ваш проект, например, библиотека, предоставляющая функции, которые вы вызываете из своего кода.
Они устанавливаются транзитивно (если A зависит от B, зависит от C, npm install на A установит B и C).
Пример: lodash: ваш проект вызывает некоторые функции lodash.
devDependencies
Зависимости, которые вам нужны только во время разработки или выпуска, например, компиляторы, которые берут ваш код и компилируют его в javascript, тестовые среды или генераторы документации.
Они не установлены транзитивно (если A зависит от B, dev зависит от C, установка npm на 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/npm/blob/master/doc/files/package.json.md#devdependencies
В качестве примера, mocha обычно представляет собой devDependency, поскольку тестирование не требуется в производственной среде, в то время как express будет зависимостью.
Чтобы сохранить пакет в package.json как зависимости dev:
npm install "$package" --save-dev
Когда ты бежишь npm install
он установит оба devDependencies
а также dependencies
, Чтобы избежать установки devDependencies
бежать:
npm install --production
Есть некоторые модули и пакеты, необходимые только для разработки, которые не нужны в производстве. Как говорится в документации:
Если кто-то планирует загрузить и использовать ваш модуль в своей программе, то он, вероятно, не хочет или не нуждается в загрузке и создании используемой вами среды внешнего тестирования или документации. В этом случае лучше перечислить эти дополнительные элементы в хэше devDependencies.
peerDependencies
не совсем понятно для меня, пока я не прочитаю этот фрагмент из поста в блоге на тему Ciro, упомянутую выше:
То, что нужно [ плагинам ], - это способ выражения этих "зависимостей" между плагинами и их хост-пакетом. Какой-то способ сказать: "Я работаю, только когда подключен к версии 1.2.x моего хост-пакета, поэтому, если вы устанавливаете меня, будьте уверены, что он находится рядом с совместимым хостом". Мы называем эти отношения зависимостью одноранговых узлов.
Плагин действительно ожидает конкретную версию хоста...
peerDependencies
предназначены для плагинов, библиотек, которым для выполнения своих функций требуется библиотека "хост", но, возможно, они были написаны за время до выпуска последней версии хоста.
То есть если я напишу PluginX v1
за HostLibraryX v3
и уйти, нет гарантии PluginX v1
будет работать когда HostLibraryX v4
(или даже HostLibraryX v3.0.1
) выпущен.
... но плагин не зависит от хоста...
С точки зрения плагина, он только добавляет функции в библиотеку хоста. Мне действительно не нужно, чтобы хост добавлял зависимость к плагину, и плагины часто не зависят буквально от своего хоста. Если у вас нет хоста, плагин безвредно ничего не делает.
Это означает dependencies
не совсем правильная концепция для плагинов.
Еще хуже, если бы с моим хостом обращались как с зависимостью, мы бы оказались в такой ситуации, о которой упоминается в том же посте в блоге (отредактировано немного, чтобы использовать этот ответ, составленный host & plugin):
Но теперь, [если мы будем рассматривать современную версию HostLibraryX как зависимость для PluginX,] работает
npm install
приводит к неожиданному графику зависимости├── HostLibraryX@4.0.0 └─┬ PluginX@1.0.0 └── HostLibraryX@3.0.0
Я оставлю тонкие сбои, которые исходят от плагина с использованием API-интерфейса [HostLibraryX], отличного от основного приложения для вашего воображения.
... и хост, очевидно, не зависит от плагина...
... в этом весь смысл плагинов. Теперь, если хост достаточно хорош, чтобы включить информацию о зависимостях для всех своих плагинов, это решит проблему, но это также создаст огромную культурную проблему: управление плагинами!
Весь смысл плагинов в том, что они могут соединяться анонимно. В идеальном мире, если бы хозяин управлял ими, все было бы аккуратно и аккуратно, но мы не собираемся требовать библиотек со стадами кошек.
Если мы не зависимы от иерархии, может быть, мы внутризависимые коллеги...
Вместо этого у нас есть концепция того, чтобы быть сверстниками. Ни хост, ни плагин не находятся в корзине зависимостей другого. Оба живут на одном уровне графа зависимостей.
... но это не автоматические отношения.
Если я PluginX v1
и ожидать peer (то есть иметь 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, которой они являются. совместим с.
Простое объяснение, которое сделало его более ясным для меня:
При развертывании приложения необходимо установить модули в зависимостях, иначе ваше приложение не будет работать. Модули в devDependencies не нужно устанавливать на рабочий сервер, так как вы не разрабатываете на этом компьютере. ссылка на сайт
Я нашел простое объяснение.
Короткий ответ:
зависимости"... те, которые действительно необходимы вашему проекту для работы в производственной среде".
devDependencies"... это те, которые вам понадобятся во время разработки".
peerDependencies"если вы хотите создать и опубликовать свою собственную библиотеку, чтобы ее можно было использовать в качестве зависимости"
Подробнее в этом сообщении: https://code-trotter.com/web/dependencies-vs-devdependencies-vs-peerdependencies
Я хотел бы добавить к ответу мой взгляд на объяснения этих зависимостей
dependencies
используются для непосредственного использования в вашей кодовой базе, вещах, которые обычно заканчиваются в производственном коде, или кусках кодаdevDependencies
используются для процесса сборки, инструменты, помогающие управлять конечным кодом, сторонние тестовые модули (например, веб-пакеты)
Коротко
Зависимости -
npm install <package> --save-prod
устанавливает пакеты, необходимые вашему приложению в производственной среде.DevDependencies -
npm install <package> --save-dev
устанавливает пакеты, необходимые только для локальной разработки и тестированияПросто набираю
npm install
устанавливает все пакеты, указанные в package.json
поэтому, если вы работаете на своем локальном компьютере, просто введите npm install
и продолжаем:)
Зависимости и зависимости от разработчиков
Зависимости разработчика - это модули, которые требуются только во время разработки, тогда как зависимости требуются во время выполнения. Если вы развертываете свое приложение, необходимо установить зависимости, иначе ваше приложение просто не будет работать. Библиотеки, которые вы вызываете из своего кода, который позволяет запускать программу, можно рассматривать как зависимости.
Например, React, React - дом
Модули зависимостей Dev не нужно устанавливать на производственном сервере, поскольку вы не собираетесь разрабатывать на этой машине. Компиляторы, которые скрывают ваш код в javascript, тестовые фреймворки и генераторы документов могут рассматриваться как зависимости dev, поскольку они требуются только во время разработки.
Например, ESLint, Babel, webpack.
@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
зависимости : пакеты, которые необходимы вашему проекту/пакету для работы в продакшене.
devDependencies: пакеты, которые необходимы вашему проекту/пакету для работы во время разработки, но не нужны в производстве (например, тестовые пакеты)
peerDependencies: пакеты, с которыми ваш проект/пакет должен работать в тандеме («взаимодействуя» с ними) или в качестве основы, полезны в основном при разработке плагина/компонента , чтобы сообщить, с какой версией «основного» пакета работает ваш плагин. /component должен работать (например: React 16)
Зависимости
Это пакеты, которые необходимо запустить вашему пакету, поэтому они будут установлены, когда люди запустят
npm install PACKAGE-NAME
Примером может служить использование jquery в своем проекте. Если у кого-то не установлен jquery, это не сработает. Чтобы сохранить как зависимость, используйте
npm install --save
Dev-зависимости
Это зависимости, которые вы используете при разработке, но они не нужны, когда люди используют его, поэтому, когда люди запускают
npm install
, он не установит их, так как они не нужны. Например, если вы используете мокко для тестирования, людям не нужен мокко для запуска, поэтому
npm install
не устанавливает его. Чтобы сохранить как зависимость от разработчика, используйте
npm install PACKAGE --save-dev
Зависимости от сверстников
Их можно использовать, если вы хотите создать и опубликовать свою собственную библиотеку, чтобы ее можно было использовать в качестве зависимости. Например, если вы не хотите, чтобы ваш пакет использовался в качестве зависимости в другом проекте, они также будут установлены, когда кто-то установит проект, в котором ваш проект является зависимостью. В большинстве случаев вы не будете использовать одноранговые зависимости.
При попытке распространить пакет npm вы должны избегать использования dependencies
, Вместо этого вам нужно рассмотреть возможность добавления его в peerDependencies
или удалите его из dependencies
,
Разница между ними в том, что devDependencies — это модули, которые требуются только во время разработки , а зависимости — это модули, которые также требуются во время выполнения .
Чтобы сохранить зависимость как devDependency при установке, нам нужно выполнить #npm install --save-dev , а не просто #npm install --save
Хорошее сокращение для установки devDependency, которое я люблю использовать, это #npm i -D. Сокращение для сохранения обычной зависимости -S вместо -D.
Некоторые хорошие примеры зависимостей, которые потребуются во время выполнения, включают React, Redux, Express и Axios.
Некоторыми хорошими примерами установки devDependencies могут быть Nodemon, Babel, ESLint и среды тестирования, такие как Chai, Mocha, Enzyme и т. д.
При использовании Webpack для сборки внешнего приложения различие между зависимостями и devDependencies не столь очевидно. Для окончательного пакета не имеет значения, где вы размещаете зависимости (но это может быть важно для других инструментов). Вот почему документация кажется запутанной.
Я нашел объяснение здесь: имеют ли значение «зависимости» и «devDependencies» при использовании Webpack?
зависимости необходимы для запуска, devDependencies только для разработки
Посмотрите официальную документацию, пожалуйста:
Что нам нужно, так это способ выражения этих «зависимостей» между плагинами и их хост-пакетом. Можно сказать: «Я работаю только при подключении к версии 1.2.x моего хост-пакета, поэтому, если вы устанавливаете меня, убедитесь, что он находится рядом с совместимым хостом». Мы называем эти отношения зависимостью от сверстников.