Чим відрізняється Бауер від нм / хв?


1763

У чому полягає принципова різниця між bowerта npm? Просто хочеться чогось простого і простого. Я бачив, як деякі мої колеги використовують bowerі npmвзаємозамінно в своїх проектах.


7
Пов'язаний відповідь stackoverflow.com/a/21199026/1310070
sachinjain024

4
можливий дублікат управління залежностями Javascript: npm vs bower vs volo?
Anotherdave

7
Відповідь на це питання видається застарілою. Чи може хтось сказати нам, що робити у 2016 році, якщо ми використовуємо npm 3, який підтримує рівну залежність? Яка різниця між npm3 та bower та яка найкраща практика зараз?
amdev

2
Підсумок, @amdev: bower застарілий. npm (або Пряжа, що є лише незначною різницею), де це. Я не знаю жодної життєздатної альтернативи.
XML

Відповіді:


1914

Усі менеджери пакунків мають багато недоліків. Вам просто потрібно вибрати, з чим можна жити.

Історія

npm почав керувати модулями node.js (саме тому пакети переходять node_modulesза замовчуванням), але він працює і для передньої частини в поєднанні з Browserify або webpack .

Чаша створена виключно для передньої частини та оптимізована з урахуванням цього.

Розмір репо

npm набагато більше, ніж bower, включаючи JavaScript загального призначення (наприклад, country-dataдля інформації про країну або sortsдля сортування функцій, які можна використовувати на передньому або задньому кінці).

Bower має набагато меншу кількість пакетів.

Поводження зі стилями тощо

Бауер включає стилі тощо.

npm зосереджено на JavaScript. Стилі завантажуються окремо, або вимагається щось на зразок npm-sassабо sass-npm.

Обробка залежності

Найбільша різниця полягає в тому, що npm робить вкладені залежності (але за замовчуванням є рівними), тоді як Bower вимагає дерева плоских залежностей (покладає тягар розв'язання залежності на користувача) .

Вкладене дерево залежностей означає, що ваші залежності можуть мати власні залежності, які можуть мати власні тощо. Це дозволяє двом модулям вимагати різних версій однакової залежності і все ще працювати. Зверніть увагу на npm v3, дерево залежностей буде за замовчуванням (заощаджуючи простір) і вкладається лише там, де потрібно, наприклад, якщо для двох залежностей потрібна своя версія підкреслення.

Деякі проекти використовують і те, і інше: вони використовують Bower для передових пакетів і npm для таких інструментів для розробників, як Yeoman, Grunt, Gulp, JSHint, CoffeeScript тощо.


Ресурси


37
Чому вкладене дерево залежності не робить це добре на передньому кінці?
Lars Nyström

24
Чи міг би пакет пакетів npm не бути рівним деревом залежності? Я зіткнувся з "чому нам потрібні 2 менеджери пакунків?" дилема.
Стівен Вачон

38
Що ви маєте на увазі під «деревом плоскої залежності»? Плоске дерево - що - список? Це не дерево тоді.
mvmn

14
Власне, стежка - це також дерево. Це просто особливий випадок. З WikiPedia: "У математиці, а точніше в теорії графів, дерево - це непрямий графік, у якому будь-які дві вершини з'єднані рівно одним шляхом".
Jørgen Fogh

42
npm 3 підтримує дерево плоскої залежності зараз.
ваза

361

Ця відповідь є доповненням до відповіді Сіндре Сорхуса. Основна різниця між 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

Як бачите, деякі залежності встановлюються рекурсивно. Залежність A має три встановлені екземпляри!

Чаша:

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).

  • [вузли_модулі]
    • dep A v1.0
    • dep B v1.0
      • dep A v1.0 (використовує кореневу версію)
    • dep C v1.0
      • dep A v2.0 (ця версія відрізняється від кореневої версії, тому це буде вкладена установка)

Для отримання додаткової інформації пропоную прочитати документи npm 3


4
Зараз це майже кліше, коли "розробка програмного забезпечення стосується лише компромісів". Це хороший приклад. Слід вибрати або більшу стабільність, npm або мінімальне завантаження ресурсів bower.
jfmercer

6
@Shrek Я неявно заявляю, що ви насправді можете використовувати обидва. Як я констатую в заключному пункті, вони мають різні цілі. Це не компроміс в моїх очах.
Юстус Ромінь

А-а, я бачу, я зрозумів тебе неправильно. Або я не читав достатньо уважно. Дякуємо за роз’яснення. :-) Добре, що обидва можна використовувати без компромісів.
jfmercer

4
@AlexAngas Я додав оновлення для npm3. Він все ще має деякі основні відмінності порівняно з Бауер. npm, ймовірно, завжди підтримуватиме кілька версій залежностей, тоді як Bower цього не робить.
Юстус Ромінь

npm 3 наближається до bower;)
ni3

269

TL; DR: Найбільша різниця у повсякденному використанні - це не вкладені залежності ... це різниця між модулями та глобальними.

Я думаю, що попередні плакати добре висвітлювали деякі основні відмінності. (використання вкладених залежностей npm дійсно дуже корисно в управлінні великими, складними програмами, хоча я не думаю, що це найважливіше розходження.)

Я здивований, однак, що ніхто не пояснив однозначно однієї з найбільш фундаментальних відмінностей між Бауер і npm. Якщо ви прочитаєте відповіді вище, ви побачите слово "модулі", яке часто використовується в контексті npm. Але це згадується випадково, наче це може бути навіть просто синтаксичною різницею.

Але це відмінність модулів від глобалів (або модулів проти «скриптів»), можливо, є найбільш важливою різницею між Bower і npm. Підхід npm введення всього в модулі вимагає від вас змінити спосіб написання Javascript для браузера, майже напевно, на краще.

Підхід Бауера: глобальні ресурси, як <script>теги

У корені Bower - це завантаження простих старих файлів скриптів. Що б не містили ці файли скриптів, Bower їх завантажує. Що в основному означає, що Bower так само, як включення всіх ваших сценаріїв у звичайний старий <script>у <head>вашому HTML.

Отже, той самий базовий підхід, до якого ви звикли, але ви отримуєте деякі приємні зручності автоматизації:

  • Вам раніше потрібно було включати залежності JS у проект репо (під час розробки) або отримувати їх через CDN. Тепер ви можете пропустити додаткову вагу завантаження в репо, і хтось може швидко bower installі негайно зробити все, що потрібно, локально.
  • Якщо залежність від Бауера тоді визначає свої власні залежності bower.json, вони також будуть завантажені для вас.

Але крім цього, Бауер не змінює те, як ми пишемо JavaScript . Нічого про те, що знаходиться всередині файлів, завантажених Bower, взагалі не потрібно змінювати. Зокрема, це означає, що ресурси, надані в скриптах, завантажених Bower, (як правило, але не завжди) все ще визначатимуться як глобальні змінні , доступні з будь-якої точки контексту виконання браузера.

Підхід npm: загальні JS-модулі, явне введення залежності

Весь код у ділянці вузла (і, отже, весь код, завантажений через npm), структурується як модулі (конкретно, як реалізація формату модуля CommonJS або зараз як модуль ES6). Отже, якщо ви використовуєте NPM для обробки залежностей від браузера (через Browserify або щось інше, що робить ту саму роботу), ви структуруєте свій код так само, як і Node.

Розумніші люди, ніж я, вирішили питання "Чому модулі?", Але ось короткий підсумок:

  • Все, що знаходиться всередині модуля, має ефективний простір імен , тобто більше не є глобальною змінною, і ви не можете випадково посилатися на нього, не маючи намір.
  • Все, що знаходиться всередині модуля, повинно бути навмисно введене в певний контекст (як правило, в інший модуль), щоб використовувати його
  • Це означає, що ви можете мати кілька версій однієї і тієї ж зовнішньої залежності (припустімо, скажімо) в різних частинах вашої програми, і вони не зіткнуться / конфліктуватимуть. (Це трапляється напрочуд часто, тому що ваш власний код хоче використовувати одну версію залежності, але одна з ваших зовнішніх залежностей вказує іншу, яка конфліктує. Або у вас є дві зовнішні залежності, кожна з яких бажає іншої версії.)
  • Оскільки всі залежності вводяться вручну в певний модуль, міркувати про них дуже просто. Ви знаєте фактично: "Єдиний код, який я повинен враховувати, працюючи над цим, - це те, що я навмисно вирішив вводити сюди" .
  • Оскільки навіть вміст введених модулів інкапсульовано за змінною, якій ви її призначите, і весь код виконується в обмеженій області, сюрпризи та зіткнення стають дуже малоймовірними. Це набагато, набагато менше ймовірність, що щось із однієї з ваших залежностей випадково переосмислить глобальну змінну, не усвідомлюючи цього, або що ви зробите це. (Це може статися, але вам зазвичай потрібно вийти зі свого шляху, щоб зробити щось подібне window.variable. Одна випадковість, яка все ще має місце, - це присвоєння this.variable, не усвідомлення того, що thisє насправді windowв поточному контексті.)
  • Коли ви хочете протестувати окремий модуль, ви можете легко зрозуміти: що саме (залежності) впливає на код, який працює всередині модуля? А оскільки ви явно все вводите, ви можете легко знущатися над цими залежностями.

Як на мене, використання модулів для фронтального коду зводиться до: роботи в набагато вужчому контексті, простіше міркувати і перевіряти, і мати більшу впевненість у тому, що відбувається.


Навчається використовувати синтаксис модуля CommonJS / Node лише 30 секунд. Всередині заданого файлу JS, який буде модулем, ви спочатку оголошуєте будь-які зовнішні залежності, які ви хочете використовувати, наприклад:

var React = require('react');

Всередині файлу / модуля ви робите все, що зазвичай хотіли, і створюєте якийсь об'єкт або функцію, яку ви хочете піддавати стороннім користувачам, називаючи це, можливо myModule.

В кінці файлу ви експортуєте все, що ви хочете, щоб поділитися зі світом, наприклад:

module.exports = myModule;

Потім, щоб використовувати робочий процес на основі CommonJS у браузері, ви будете використовувати такі інструменти, як Browserify, щоб захопити всі ці окремі файли модулів, інкапсулювати їх вміст під час виконання та вводити їх один одному в міру необхідності.

І, оскільки модулі ES6 (які, швидше за все, можна перетворити на ES5 з Babel або подібними), набувають широкого визнання, і працюють як у браузері, так і в Node 4.0, слід також згадати хороший огляд їх.

Детальніше про схеми роботи з модулями на цій колоді .


EDIT (лютий 2017 р.): Пряжа Facebook є дуже важливою потенційною заміною / доповненням для npm в наші дні: швидке, детерміноване, офлайн-управління пакетами, яке ґрунтується на тому, що npm дає вам. Варто пошукати будь-який проект JS, тим більше, що його так просто замінити на нього / вийти.


EDIT (травень 2019 р.) "Бауер остаточно застарів . Кінець історії". (h / t: @DanDascalescu, нижче, для короткого підсумку.)

І хоча Пряжа все ще активна , багато імпульсу для неї змістилося назад до npm, коли вона прийняла деякі ключові особливості Пряжі.


13
Радий, що ця відповідь була тут, в інших популярних відповідях ця деталь не згадується. npm змушує писати модульний код.
Хуан Мендес

Вибачте, від фольклорного представника, який дуже мало піклується про все, що трапляється в jalands parlands, але так трапляється, він веде бізнес, який використовує невеликий веб-додаток. Нещодавно змушені були спробувати npm, від використання bower з інструментарієм, який ми використовуємо для розробки чортової речі в Інтернеті. Я можу вам сказати, що найбільша різниця - це час очікування, npm займає віки. Пам’ятайте, що це складання мультфільму xkcd з хлопцями, які грають у бої на мечах, кричать на «компіляцію» на свого начальника; це майже те, що npm додав до bower.
Педро Родрігес

129

2017-жовтень оновлення

Бауер остаточно застарів . Кінець історії.

Старіша відповідь

Від Маттіаса Петтера Йохансона, розробника JavaScript компанії Spotify :

Майже у всіх випадках більш доцільно використовувати Browserify та npm над Bower. Це просто краще рішення для упаковки для прикладних програм, ніж Bower. У Spotify ми використовуємо npm для упаковки цілих веб-модулів (html, css, js), і це працює дуже добре.

Bower брендує себе як менеджер пакетів для Інтернету. Було б дивовижно, якби це було правдою - менеджер пакунків, який поліпшив моє життя як розробник, що передує. Проблема полягає в тому, що Bower не пропонує спеціалізованих інструментів для цієї мети. Він пропонує НЕ інструменти, про які я знаю, що npm не робить, і особливо жоден, який спеціально корисний для розробників інтерфейсу. Професійна програма для використання Bower над npm просто не має ніякої користі.

Ми повинні перестати використовувати bower і консолідуватись навколо npm. На щастя, ось що відбувається :

Кількість модулів - бауер проти npm

Завдяки перегляду веб-сторінок або веб-пакету об’єднувати всі ваші модулі у великі мінімізовані файли стає надзвичайно просто, що є приголомшливим для продуктивності, особливо для мобільних пристроїв. Не так, як з Бауером, для отримання такого ж ефекту знадобиться значно більше праці.

npm також пропонує вам можливість використовувати кілька версій модулів одночасно. Якщо ви ще не зробили багато розробок додатків, це спочатку може вразити вас як погану річ, але , переживши кілька притч пекла залежності, ви зрозумієте, що мати можливість мати декілька версій одного модуля - це цілком чорт чудова особливість. Зауважте, що npm включає дуже зручний інструмент дедупінгу, який автоматично гарантує, що ви використовуєте лише дві версії модуля, якщо вам це потрібно - якщо два модулі можуть використовувати одну і ту ж версію одного модуля, вони будуть. Але якщо вони не можуть , то вам дуже зручно.

(Зверніть увагу , що Webpack і Накопичувальний широко вважається краще , ніж Browserify від серпня 2016 року)


7
<sarcasm> Будь ласка, майте на увазі, що навіть для проекту "привіт світові" для запуску потрібні 300+ модулів ... </sarcasm>: O
Маріуш Джамро

1
Я не згоден, що "великі мінімізовані файли" є приголомшливими для продуктивності, особливо для мобільних пристроїв ". Зовсім навпаки: обмежена пропускна здатність вимагає невеликих файлів, завантажених на вимогу.
Майкл Францл

Не дуже гарна порада. Більшість пакетів npm - це лише резервний модуль nodejs. Якщо ви не робите JavaScript на бекенді, або у вас немає модульної системи, кількість пакетів не має значення, оскільки Bower набагато краще відповідає вашим потребам
Джерардо Гриньолі


45

Bower підтримує єдину версію модулів, вона лише намагається допомогти вибрати правильний / найкращий для вас.

Управління залежністю від Javascript: npm vs bower vs volo?

NPM краще для вузлових модулів, оскільки існує модульна система, і ви працюєте локально. Bower корисний для браузера, оскільки наразі існує лише глобальна сфера, і ви хочете бути дуже вибіркові щодо версії, з якою працюєте.


4
Я відчуваю, що Сіндре згадує це, коли він говорить про вкладену залежність.
Ігри Brainiac

5
@GamesBrainiac ваше правильне, я просто подумав, що я би сказав це своїми словами.
Сагівф

1
@Sagivf Це НЕ ваші власні слова, якщо ви не також wheresrhys, який надав оригінальну відповідь тут
dayuloli

4
@Sagivf Немає нічого поганого в тому, щоб скопіювати ** відповідні частини відповідей інших, якщо вони самі не надали відповіді. Це трохи поблажнило мене, ти сказала, "просто подумала, що я це викладу своїми словами". Кредит повинен надходити там, де належить кредит.
денулолі

2
Не знаю, чому ви так сильно вибрали цю відповідь. У цій відповіді дійсно є нова інформація / перспектива.
Кальвін

33

Моя команда відійшла від Бауера і перейшла в npm через:

  • Використання програм було болючим
  • Інтерфейс Bower постійно змінювався
  • Деякі функції, як-от скорочення URL-адреси, повністю порушені
  • Використання як Bower, так і npm в одному проекті є болісним
  • Синхронізація поля версії bower.json синхронізована з тегами git
  • Контроль джерела! = Управління пакетом
  • Підтримка CommonJS не є простою

Більш детально див. "Чому моя команда використовує npm замість" bower " .


17

Знайшов це корисне пояснення з http://ng-learn.org/2013/11/Bower-vs-npm/

З одного боку, npm був створений для установки модулів, що використовуються в середовищі node.js, або інструментів розробки, побудованих за допомогою node.js, таких як Karma, lint, minifiers тощо. npm може встановлювати модулі локально в проекті (за замовчуванням у node_modules) або глобально для використання у кількох проектах. У великих проектах спосіб визначати залежності - це створити файл під назвою package.json, який містить перелік залежностей. Цей список розпізнається npm, коли ви запускаєте npm install, який потім завантажує та встановлює їх для вас.

З іншого боку, баунер був створений для управління вашими залежностями. Бібліотеки, такі як jQuery, AngularJS, підкреслення тощо. Подібно до npm, у нього є файл, у якому ви можете вказати список залежностей під назвою bower.json. У цьому випадку ваші залежності між собою встановлюються запуском установки bower, яка за замовчуванням встановлює їх у папці під назвою bower_components.

Як бачите, хоча вони виконують подібне завдання, вони націлені на зовсім інший набір бібліотек.


1
З появою npm dedupe, це трохи застаріло. Дивіться відповідь Маттіаса .
Дан Даскалеску

7

Для багатьох людей, що працюють з node.js, головна перевага bower - це управління залежностями, які взагалі не є JavaScript. Якщо вони працюють з мовами, які компілюються в javascript, npm може використовуватися для управління деякими їх залежностями. однак, не всі їх залежності будуть модулями node.js. Деякі з тих, що компілюються в javascript, можуть мати дивне стилювання для мов джерела, що робить передачу їх навколо компільованого javascript неелегантною опцією, коли користувачі очікують вихідного коду.

Не все в пакеті npm має бути орієнтованим на JavaScript, але для пакетів бібліотеки npm, принаймні, деякі з них повинні бути.


У цій публікації в блозі npmjs зазначено: "Ваш пакет може містити що завгодно, будь то ES6, клієнтський JS або навіть HTML та CSS. Це речі, які, природно, з'являються поряд з JavaScript, тому поставте їх туди".
Дан Даскалеску

1
Існує різниця між тим, що може містити , і повинна включати . Звичайно, вони можуть містити що завгодно, але в цілому вони повинні включати якийсь інтерфейс до commonJS. Зрештою, це "менеджер пакетів вузлів". Частина про Ці речі, які, природно, з’являються поряд із Javascript . Є багато речей, які дотично пов'язані з javascript, які, природно, не з'являються уздовж нього.
Джессофер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.