В чем принципиальное отличие между bower
и npm
? Просто хочу что-то простое и простое. Я видел, что некоторые из моих коллег используют bower
и npm
взаимозаменяемо в своих проектах.
В чем разница между Bower и npm?
Ответ 1
У всех менеджеров пакетов есть много минусов. Вам просто нужно выбрать, с чем вы можете жить.
история
npm начал управлять модулями node.js (поэтому пакеты по умолчанию node_modules
в node_modules
), но он работает и для внешнего интерфейса в сочетании с Browserify или webpack.
Bower создан исключительно для внешнего интерфейса и оптимизирован с учетом этого.
Размер репо
npm намного, намного больше, чем bower, включая JavaScript общего назначения (например, country-data
о стране для информации о стране или sorts
для функций сортировки, которые можно использовать на переднем или заднем конце).
Бауэр имеет гораздо меньшее количество пакетов.
Обработка стилей и т.д.
Бауэр включает в себя стили и т.д.
Npm ориентирован на JavaScript. Стили либо загружаются отдельно, либо требуют чего-то вроде npm-sass
или sass-npm
.
Обработка зависимостей
Самым большим отличием является то, что npm выполняет вложенные зависимости (но по умолчанию является плоским), в то время как Bower требует плоское дерево зависимостей (накладывает бремя разрешения зависимостей на пользователя).
Вложенное дерево зависимостей означает, что ваши зависимости могут иметь свои собственные зависимости, которые могут иметь свои собственные, и так далее. Это позволяет двум модулям требовать разные версии одной и той же зависимости и при этом работать. Обратите внимание, что начиная с npm v3, дерево зависимостей по умолчанию будет плоским (экономия места) и будет гнездиться только там, где это необходимо, например, если двум зависимостям требуется собственная версия Underscore.
В некоторых проектах используется то, что они используют Bower для интерфейсных пакетов и npm для инструментов разработчика, таких как Yeoman, Grunt, Gulp, JSHint, CoffeeScript и т.д.
Ресурсы
- Вложенные зависимости - понимание того, почему node_modules работает так, как работает
Ответ 2
Этот ответ является дополнением к ответу Синдре Сорхуса. Основное различие между npm и Bower заключается в том, как они обрабатывают рекурсивные зависимости. Обратите внимание, что они могут быть использованы вместе в одном проекте.
Часто задаваемые вопросы о npm : (ссылка на archive.org от 6 сентября 2015 г.)
Гораздо сложнее избежать конфликтов зависимостей без вложенных зависимостей. Это имеет фундаментальное значение для работы npm и оказалось чрезвычайно успешным подходом.
На домашней странице Bower :
Бауэр оптимизирован для внешнего интерфейса. Bower использует плоское дерево зависимостей, для которого требуется только одна версия для каждого пакета, что снижает загрузку страницы до минимума.
Короче говоря, npm стремится к стабильности. Бауэр стремится к минимальной нагрузке на ресурсы. Если вы нарисуете структуру зависимостей, вы увидите это:
NPM:
project root
[node_modules] // default directory for dependencies
-> dependency A
-> dependency B
[node_modules]
-> dependency A
-> dependency C
[node_modules]
-> dependency B
[node_modules]
-> dependency A
-> dependency D
Как вы можете видеть, он устанавливает некоторые зависимости рекурсивно. Зависимость А имеет три установленных экземпляра!
Беседка:
project root
[bower_components] // default directory for dependencies
-> dependency A
-> dependency B // needs A
-> dependency C // needs B and D
-> dependency D
Здесь вы видите, что все уникальные зависимости находятся на одном уровне.
Итак, зачем использовать npm?
Возможно, для зависимости B требуется другая версия зависимости A, чем для зависимости C. npm устанавливает обе версии этой зависимости, поэтому она все равно будет работать, но Bower создаст вам конфликт, потому что не любит дублирование (поскольку загрузка одного и того же ресурса на веб-странице очень неэффективно и дорого, а также может привести к серьезным ошибкам). Вам нужно будет вручную выбрать, какую версию вы хотите установить. Это может привести к тому, что одна из зависимостей будет нарушена, но это нужно исправить в любом случае.
Таким образом, обычно используется Bower для пакетов, которые вы хотите опубликовать на своих веб-страницах (например, во время выполнения, где вы избегаете дублирования), и использовать npm для других вещей, таких как тестирование, сборка, оптимизация, проверка и т.д. (Например, время разработки где дублирование вызывает меньшую озабоченность).
Обновление для npm 3:
Npm 3 по-прежнему работает по-другому по сравнению с Bower. Он установит зависимости глобально, но только для первой версии, с которой он столкнется. Другие версии устанавливаются в дереве (родительский модуль, затем node_modules).
- [node_modules]
- Dep A v1.0
- Dep B v1.0
-
Dep A v1.0(использует корневую версию)
-
- Dep C v1.0
- dep A v2.0 (эта версия отличается от корневой версии, поэтому это будет вложенная установка)
Для получения дополнительной информации, я предлагаю прочитать документы по npm 3
Ответ 3
TL; DR: самая большая разница в повседневном использовании - это не вложенные зависимости... это разница между модулями и глобальными переменными.
Я думаю, что предыдущие плакаты хорошо освещали некоторые основные различия. (Использование npm вложенных зависимостей действительно очень полезно для управления большими и сложными приложениями, хотя я не считаю это самым важным отличием.)
Я удивлен, однако, что никто не объяснил одно из самых фундаментальных различий между Bower и npm. Если вы прочитаете ответы выше, вы увидите слово "модули", часто используемое в контексте npm. Но это упоминается случайно, как будто это может быть просто разница в синтаксисе.
Но это различие между модулями и глобальными (или модулями и "скриптами"), возможно, является наиболее важным отличием между Bower и npm. Подход npm для размещения всего в модулях требует, чтобы вы изменили способ написания Javascript для браузера, почти наверняка в лучшую сторону.
Подход Бауэра: глобальные ресурсы, теги <script>
В корне Bower о загрузке простых старых файлов сценариев. Что бы ни содержали эти файлы скриптов, Бауэр загрузит их. Что в основном означает, что Bower подобен включению всех ваших сценариев в простой старый <script>
в <head>
вашего HTML.
Итак, тот же базовый подход, к которому вы привыкли, но вы получаете некоторые удобные возможности автоматизации:
- Раньше вам приходилось включать JS-зависимости в репозиторий вашего проекта (при разработке) или получать их через CDN. Теперь вы можете пропустить этот дополнительный вес загрузки в репо, и кто-то может сделать быструю
bower install
и сразу же получить то, что ему нужно, локально. - Если зависимость Bower затем указывает свои собственные зависимости в своем
bower.json
, они также будут загружены для вас.
Но кроме этого, Бауэр не меняет то, как мы пишем JavaScript. Ничего из того, что происходит внутри файлов, загружаемых Bower, вообще не должно меняться. В частности, это означает, что ресурсы, предоставляемые в скриптах, загружаемых Bower, будут (обычно, но не всегда) по-прежнему определяться как глобальные переменные, доступные из любого места в контексте выполнения браузера.
Подход npm: общие JS-модули, явное внедрение зависимостей
Весь код в Node land (и, следовательно, весь код, загруженный через npm) структурирован как модули (в частности, как реализация формата модуля CommonJS, или теперь как модуль ES6). Итак, если вы используете NPM для обработки зависимостей на стороне браузера (через Browserify или что-то еще, что делает ту же работу), вы будете структурировать свой код так же, как это делает Node.
Более умные люди, чем я, взялись за вопрос "Почему модули?", Но здесь краткая сводка:
- Все, что находится внутри модуля, фактически является пространством имен, что означает, что оно больше не является глобальной переменной, и вы не можете случайно ссылаться на него без намерения.
- Все, что находится внутри модуля, должно быть намеренно введено в определенный контекст (обычно в другой модуль), чтобы использовать его
- Это означает, что вы можете иметь несколько версий одной и той же внешней зависимости (скажем, lodash) в разных частях вашего приложения, и они не будут конфликтовать/конфликтовать. (Это происходит на удивление часто, потому что ваш собственный код хочет использовать одну версию зависимости, но одна из ваших внешних зависимостей задает другую, которая конфликтует. Или у вас есть две внешние зависимости, каждая из которых требует своей версии.)
- Поскольку все зависимости вводятся вручную в конкретный модуль, очень легко рассуждать о них. Вы точно знаете: "Единственный код, который мне нужно учитывать при работе над этим, - это то, что я намеренно выбрал для внедрения здесь".
- Поскольку даже содержимое внедренных модулей инкапсулировано за переменной, которой вы назначаете его, и весь код выполняется в ограниченной области, неожиданности и коллизии становятся очень маловероятными. Гораздо менее вероятно, что что-то из одной из ваших зависимостей будет случайно переопределять глобальную переменную без вашего осознания или того, что вы это сделаете. (Это может случиться, но вам обычно приходится делать все возможное, чтобы сделать это, с чем-то вроде
window.variable
. Единственная авария, которая все еще имеет место, это присвоитьthis.variable
, не осознавая, чтоthis
на самом делеwindow
в текущем контекст). - Когда вы хотите протестировать отдельный модуль, вы можете очень легко узнать: что еще (зависимости) влияет на код, который выполняется внутри модуля? И, поскольку вы явно вводите все, вы можете легко высмеивать эти зависимости.
Для меня использование модулей для внешнего кода сводится к: работе в гораздо более узком контексте, который легче рассуждать и тестировать, и большей уверенности в происходящем.
Это займет около 30 секунд, чтобы научиться использовать синтаксис модуля CommonJS/Node. Внутри данного файла JS, который будет модулем, вы сначала объявляете любые внешние зависимости, которые хотите использовать, например так:
var React = require('react');
Внутри файла/модуля вы делаете все, что обычно делаете, и создаете какой-либо объект или функцию, которую вы хотите показать внешним пользователям, называя это, возможно, myModule
.
В конце файла вы экспортируете все, что хотите поделиться с миром, например так:
module.exports = myModule;
Затем, чтобы использовать основанный на CommonJS рабочий процесс в браузере, вы будете использовать такие инструменты, как Browserify, чтобы захватывать все эти отдельные файлы модулей, инкапсулировать их содержимое во время выполнения и вставлять их друг в друга по мере необходимости.
И, поскольку модули ES6 (которые вы, скорее всего, перенесете в ES5 с Babel или аналогичными), получают широкое признание и работают как в браузере, так и в Node 4.0, мы должны упомянуть и их хороший обзор.
Подробнее о шаблонах для работы с модулями в этой колоде.
РЕДАКТИРОВАТЬ (февраль 2017 г.): Facebook Yarn является очень важной потенциальной заменой/дополнением для npm в наши дни: быстрое, детерминистическое, автономное управление пакетами, основанное на том, что дает npm. Это стоит посмотреть на любой проект JS, особенно потому, что его так легко поменять местами.
РЕДАКТИРОВАТЬ (май 2019) "Бауэр, наконец, устарела. Конец истории". (h/t: @DanDascalescu, ниже, для краткого изложения.)
И, хотя Yarn все еще активен, большая часть импульса вернулась к npm, как только он принял некоторые ключевые функции Yarn.
Ответ 4
Обновление 2017-октябрь
Бауэр наконец-то устарела. Конец истории.
Старый ответ
От Маттиаса Петтера Йоханссона, разработчика JavaScript в Spotify:
Почти во всех случаях более уместно использовать Browserify и npm over Bower. Это просто лучшее упаковочное решение для интерфейсных приложений, чем Bower. В Spotify мы используем npm для упаковки целых веб-модулей (html, css, js), и это работает очень хорошо.
Бауэр позиционирует себя как менеджер пакетов для Интернета. Было бы замечательно, если бы это было правдой - менеджер пакетов, который сделал мою жизнь лучше, как фронтенд-разработчик, был бы потрясающим. Проблема в том, что Bower не предлагает специального инструмента для этой цели. Он не предлагает никаких инструментов, которые я знаю о том, чего нет в npm, и особенно тех, которые особенно полезны для разработчиков переднего плана. Для разработчика переднего плана просто не выгодно использовать Bower вместо npm.
Мы должны прекратить использовать беседку и консолидироваться около нпм. К счастью, вот что происходит:
С помощью browserify или webpack становится очень легко объединить все ваши модули в большие миниатюрные файлы, что является потрясающим по производительности, особенно для мобильных устройств. Не так с Бауэром, который потребует значительно больше труда, чтобы получить тот же эффект.
npm также предлагает вам возможность использовать несколько версий модулей одновременно. Если вы не занимались разработкой приложений, это может показаться плохим, но как только вы пройдете через несколько адских адептов зависимости, вы поймете, что иметь возможность иметь несколько версий одного модуля - это чертовски круто. отличная особенность. Обратите внимание, что npm включает в себя очень удобный инструмент дедупликации, который автоматически гарантирует, что вы используете только две версии модуля, если вам это действительно нужно - если два модуля могут использовать одну и ту же версию одного модуля, они это сделают. Но если они не могут, у вас есть очень удобный.
(Обратите внимание, что Webpack и накопительный пакет, по общему мнению, лучше, чем Browserify по состоянию на август 2016 года.)
Ответ 5
Bower поддерживает единую версию модулей, он только пытается помочь вам выбрать правильный/лучший для вас.
NPM лучше подходит для модулей node, потому что есть модульная система, и вы работаете локально. Bower хорош для браузера, потому что в настоящее время существует только глобальная область действия, и вы хотите быть очень избирательным относительно версии, с которой вы работаете.
Ответ 6
Моя команда отошла от Бауэра и переместилась на галлон, потому что:
- Использование программы было болезненным.
- Интерфейс Bower постоянно менялся
- Некоторые функции, такие как сокращение URL, полностью нарушены.
- Использование обоих Bower и npm в одном проекте болезненно
- Сохранение поля версии bower.json в синхронизации с тегами git является болезненным
- Контроль источника!= управление пакетами
- Поддержка CommonJS не является простой.
Подробнее см. "Почему моя команда использует npm вместо bower" .
Ответ 7
Нашел это полезное объяснение от http://ng-learn.org/2013/11/Bower-vs-npm/
С одной стороны, была создана npm для установки модулей, используемых в среде node.js, или средства разработки, построенные с использованием node.js таких Карма, lint, minifiers и так далее. npm может устанавливать модули локально в проекте (по умолчанию в node_modules) или глобально для использования несколькими проектами. В больших проектах способ задания зависимостей заключается в создании файла с именем package.json, который содержит список зависимостей. Этот список распознается npm при запуске npm install, который затем загружает и устанавливает их для вас.
С другой стороны, беседа была создана для управления внешними зависимостями. Библиотеки, такие как jQuery, AngularJS, подчеркивание и т.д. Подобно npm у него есть файл, в котором вы можете указать список зависимостей, называемых bower.json. В этом случае зависимости вашего интерфейса устанавливаются с помощью установки bower install, которая по умолчанию устанавливает их в папку с именем bower_components.
Как вы можете видеть, хотя они выполняют аналогичную задачу, они нацелены на совсем другой набор библиотек.
Ответ 8
Для многих людей, работающих с node.js, главное преимущество беседы заключается в управлении зависимостями, которые вообще не являются javascript. Если они работают с языками, которые компилируются в javascript, npm может использоваться для управления некоторыми из их зависимостей. однако не все их зависимости будут node.js-модулями. Некоторые из тех, которые компилируются в javascript, могут иметь странное специфическое манипулирование исходным языком, которое позволяет передавать их скомпилированные в javascript неэлегантную опцию, когда пользователи ожидают исходный код.
Не все в пакете npm должно быть обращенным к пользователю javascript, но для пакетов библиотеки npm, по крайней мере, некоторые из них должны быть.
Ответ 9
Bower и Npm являются менеджерами пакетов для javascript. Есть много путаницы, когда мы должны использовать Bower или Npm. В некоторых проектах есть Npm и Bower. Здесь я объяснил цели этих двух инструментов, и вы узнаете, где следует использовать беседку и где следует использовать npm.
Беседка
Bower создан исключительно для внешнего интерфейса и оптимизирован с учетом этого. Он использует плоское дерево зависимостей, требующее только одну версию для каждого пакета, что снижает загрузку страницы. Это в основном направлено на минимальную загрузку ресурсов.
Bower имеет конфигурационный файл с именем bower.json. В этом файле мы можем сохранить конфигурацию для Bower, например, какие зависимости нам нужны и детали лицензии, описание, имя и так далее.
Бауэр подходит для внешних пакетов, таких как jquery, angular, реагирует, тлеющий, нокаут, позвоночник и так далее.
Npm (менеджер пакетов Node)
Npm чаще всего используется для управления модулями Node.js, но также работает и для внешнего интерфейса. Он использует вложенное дерево зависимостей, что означает, что ваши зависимости могут иметь свои собственные зависимости, которые могут иметь свои собственные, и так далее. Вложенное дерево зависимостей означает, что ваши зависимости могут иметь свои собственные зависимости, которые могут иметь свои собственные, и так далее. Это действительно здорово на сервере, где вам не нужно сильно беспокоиться о пространстве и задержке.
Это явно не очень хорошо работает во фронтэнде, потому что нам нужен jQuery в наших проектах. Нам нужна только одна копия jQuery, но когда другой пакет требует jQuery, он снова загрузит еще одну копию jQuery. Это один из главных недостатков Npm.
Npm имеет файл конфигурации с именем package.json. В этом файле мы можем поддерживать конфигурацию для Npm, такую как зависимости, которые нам нужны, и детали лицензии, описание, имя и так далее. Npm предоставляет зависимости и DevDependencies. Зависимости будут загружать и поддерживать внешние файлы, такие как Jquery, Angular и так далее. DevDependencies будет загружать и поддерживать инструменты разработки, такие как Grunt, Gulp, JSHint и так далее.
Причина, по которой многие проекты используют оба, заключается в том, что они используют Bower для интерфейсных пакетов и Npm для инструментов разработчика, таких как Grunt, Gulp, JSHint и т.д.