it-swarm.com.de

Was ist der Unterschied zwischen Bower und npm?

Was ist der grundlegende Unterschied zwischen bower und npm? Ich will nur etwas Schlichtes. Ich habe einige meiner Kollegen gesehen, die bower und npm austauschbar in ihren Projekten verwendet haben.

1705
Games Brainiac

Alle Paketmanager haben viele Nachteile. Sie müssen nur auswählen, mit wem Sie leben können.

Geschichte

npm hat mit der Verwaltung von node.js-Modulen begonnen (daher werden Pakete standardmäßig in node_modules abgelegt), funktioniert aber auch für das Front-End, wenn es mit Browserify kombiniert wird oder Webpack .

Bower wird ausschließlich für das Frontend erstellt und unter Berücksichtigung dessen optimiert.

Größe des Repos

npm ist viel, viel größer als bower, einschließlich Allzweck-JavaScript (wie country-data für Länderinformationen oder sorts für Sortierfunktionen, die am Frontend oder am Backend verwendet werden können).

Bower hat viel weniger Pakete.

Umgang mit Styles etc

Laube enthält Stile usw.

npm konzentriert sich auf JavaScript. Stile werden entweder separat heruntergeladen oder werden von etwas wie npm-sass oder sass-npm benötigt.

Abhängigkeitsbehandlung

Der größte Unterschied besteht darin, dass npm verschachtelte Abhängigkeiten ausführt (aber standardmäßig flach ist), während Bower einen flachen Abhängigkeitsbaum benötigt (die Last der Abhängigkeitsauflösung liegt beim Benutzer) .

Ein verschachtelter Abhängigkeitsbaum bedeutet, dass Ihre Abhängigkeiten ihre eigenen Abhängigkeiten haben können, die ihre eigenen haben können, und so weiter. Dies ermöglicht, dass zwei Module unterschiedliche Versionen derselben Abhängigkeit benötigen und weiterhin funktionieren. Beachten Sie, dass der Abhängigkeitsbaum seit npm v3 standardmäßig flach ist (platzsparend) und nur dort verschachtelt wird, wo dies erforderlich ist, z. B. wenn zwei Abhängigkeiten ihre eigene Version von Unterstrich benötigen.

Einige Projekte verwenden beides, nämlich Bower für Front-End-Pakete und npm für Entwicklertools wie Yeoman, Grunt, Gulp, JSHint, CoffeeScript usw.


Ressourcen

1883
Sindre Sorhus

Diese Antwort ergänzt die Antwort von Sindre Sorhus. Der Hauptunterschied zwischen npm und Bower besteht darin, wie sie rekursive Abhängigkeiten behandeln. Beachten Sie, dass sie zusammen in einem einzelnen Projekt verwendet werden können.

Am npm FAQ : (archive.org link from 6 Sep 2015)

Es ist viel schwieriger, Abhängigkeitskonflikte zu vermeiden, ohne Abhängigkeiten zu verschachteln. Dies ist grundlegend für die Funktionsweise von npm und hat sich als äußerst erfolgreich erwiesen.

Auf Bower Homepage:

Bower ist für das Frontend optimiert. Bower verwendet einen flachen Abhängigkeitsbaum, für den nur eine Version für jedes Paket erforderlich ist, wodurch die Seitenlast auf ein Minimum reduziert wird.

Kurz gesagt, npm zielt auf Stabilität ab. Bower strebt eine minimale Ressourcenbelastung an. Wenn Sie die Abhängigkeitsstruktur zeichnen, sehen Sie Folgendes:

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

Wie Sie sehen, werden einige Abhängigkeiten rekursiv installiert. In Abhängigkeit A sind drei Instanzen installiert!

Laube:

project root
[bower_components] // default directory for dependencies
 -> dependency A
 -> dependency B // needs A
 -> dependency C // needs B and D
 -> dependency D

Hier sehen Sie, dass sich alle eindeutigen Abhängigkeiten auf derselben Ebene befinden.

Warum also npm verwenden?

Möglicherweise erfordert Abhängigkeit B eine andere Version von Abhängigkeit A als Abhängigkeit C. npm installiert beide Versionen dieser Abhängigkeit, sodass sie trotzdem funktioniert, aber Bower gibt Ihnen einen Konflikt , da dies nicht der Fall ist wie das Kopieren (da das Laden derselben Ressource auf einer Webseite sehr ineffizient und kostspielig ist, kann es auch zu schwerwiegenden Fehlern kommen). Sie müssen manuell auswählen, welche Version Sie installieren möchten. Dies kann dazu führen, dass eine der Abhängigkeiten unterbrochen wird, dies müssen Sie jedoch trotzdem beheben.

Die gebräuchliche Verwendung ist also Bower für die Pakete, die Sie auf Ihren Webseiten veröffentlichen möchten (z. B. Laufzeit , wo Sie Duplikationen vermeiden), und npm für andere Dinge wie Testen. Erstellen, Optimieren, Überprüfen usw. (z. B. Entwicklungszeit , bei der die Vervielfältigung weniger wichtig ist).

Update für Nr. 3:

npm 3 macht es immer noch anders als Bower. Die Abhängigkeiten werden global installiert, jedoch nur für die erste Version, auf die sie stoßen. Die anderen Versionen werden im Baum installiert (das übergeordnete Modul, dann node_modules).

  • [node_modules]
    • dep A v1.0
    • dep B v1.0
      • dep A v1.0 (verwendet Root-Version)
    • dep C v1.0
      • dep A v2.0 (Diese Version unterscheidet sich von der Root-Version, daher handelt es sich um eine verschachtelte Installation.)

Für weitere Informationen empfehle ich das docs of npm

356
Justus Romijn

TL; DR: Der größte Unterschied im täglichen Gebrauch sind nicht verschachtelte Abhängigkeiten, sondern der Unterschied zwischen Modulen und Globalen.

Ich denke, die vorherigen Poster haben einige der grundlegenden Unterschiede gut abgedeckt. (Die Verwendung verschachtelter Abhängigkeiten durch npm ist in der Tat sehr hilfreich bei der Verwaltung großer, komplexer Anwendungen, obwohl ich nicht der Meinung bin, dass dies der wichtigste Unterschied ist.)

Ich bin jedoch überrascht, dass niemand einen der grundlegendsten Unterschiede zwischen Bower und npm explizit erklärt hat. Wenn Sie die Antworten oben lesen, sehen Sie die Wortmodule, die häufig im Zusammenhang mit npm verwendet werden. Aber es wird beiläufig erwähnt, als ob es sich nur um einen Syntaxunterschied handeln könnte.

Aber diese Unterscheidung zwischen Modulen und Globalen (oder Modulen und 'Skripten') ist möglicherweise der wichtigste Unterschied zwischen Bower und npm. Der Ansatz von npm, alles in Module zu packen, erfordert eine Änderung der Art und Weise, wie Sie Javascript für den Browser schreiben, mit ziemlicher Sicherheit zum Besseren.

Der Bower-Ansatz: Globale Ressourcen, wie <script> Tags

Bei Root geht es bei Bower darum, einfache alte Skriptdateien zu laden. Was auch immer diese Skriptdateien enthalten, Bower lädt sie. Das bedeutet im Grunde, dass Bower alle Ihre Skripte in einfache alte <script> in den <head> Ihres HTML-Codes einfügt.

Also, derselbe grundlegende Ansatz, an den Sie gewöhnt sind, aber Sie haben einige nette Automatisierungskomforte:

  • Früher mussten Sie JS-Abhängigkeiten in Ihr Projektrepertoire aufnehmen (während der Entwicklung) oder über CDN beziehen. Jetzt können Sie dieses zusätzliche Downloadgewicht im Repo überspringen, und jemand kann einen schnellen bower install ausführen und hat sofort das, was er benötigt, vor Ort.
  • Wenn eine Bower-Abhängigkeit dann in ihrem bower.json ihre eigenen Abhängigkeiten angibt, werden diese auch für Sie heruntergeladen.

Aber darüber hinaus ändert Bower nicht, wie wir Javascript schreiben . Nichts an dem, was in den von Bower geladenen Dateien abläuft, muss sich ändern. Dies bedeutet insbesondere, dass die in von Bower geladenen Skripten bereitgestellten Ressourcen (normalerweise, aber nicht immer) weiterhin als globale Variablen definiert sind, die an einer beliebigen Stelle im Kontext der Browserausführung verfügbar sind.

Der npm-Ansatz: Allgemeine JS-Module, Explicit Dependency Injection

Der gesamte Code in Node land (und damit der gesamte über npm geladene Code) ist als Module strukturiert (speziell als Implementierung des CommonJS-Modulformats oder jetzt als ES6-Modul ). Wenn Sie NPM zum Behandeln von Abhängigkeiten auf der Browserseite verwenden (über Browserify oder etwas anderes, das die gleiche Aufgabe übernimmt), strukturieren Sie Ihren Code auf die gleiche Weise wie Node.

Klügere Leute, als ich die Frage „Warum Module?“ Beantwortet habe, aber hier ist eine Zusammenfassung der Kapseln:

  • Alles in einem Modul hat einen effektiven Namensraum , was bedeutet, dass es keine globale Variable mehr ist und Sie nicht versehentlich darauf verweisen können, ohne dies zu beabsichtigen.
  • Alles, was sich in einem Modul befindet, muss absichtlich in einen bestimmten Kontext (normalerweise ein anderes Modul) eingefügt werden, damit es verwendet werden kann
  • Dies bedeutet, dass Sie in verschiedenen Teilen Ihrer Anwendung mehrere Versionen derselben externen Abhängigkeit (z. B. lodash) haben können, die nicht kollidieren/in Konflikt geraten. (Dies passiert überraschend oft, weil Ihr eigener Code eine Version einer Abhängigkeit verwenden möchte, aber eine Ihrer externen Abhängigkeiten eine andere angibt, die in Konflikt steht. Oder Sie haben zwei externe Abhängigkeiten, die jeweils eine andere Version benötigen.)
  • Da alle Abhängigkeiten manuell in ein bestimmtes Modul eingefügt werden, ist es sehr einfach, über sie nachzudenken. Sie wissen mit Sicherheit: "Der einzige Code, den ich berücksichtigen muss, wenn ich daran arbeite, ist der, den ich absichtlich hier eingefügt habe" .
  • Da selbst der Inhalt von injizierten Modulen hinter der Variablen, der Sie sie zuweisen, gekapselt ist und der gesamte Code in einem begrenzten Bereich ausgeführt wird, werden Überraschungen und Kollisionen sehr unwahrscheinlich. Es ist viel, viel weniger wahrscheinlich, dass etwas aus einer Ihrer Abhängigkeiten versehentlich eine globale Variable neu definiert, ohne dass Sie es bemerken, oder dass Sie dies tun. (Es kann passieren, aber normalerweise müssen Sie sich Mühe geben, dies mit etwas wie window.variable zu tun. Der einzige Unfall, der immer noch auftritt, ist das Zuweisen this.variable, ohne zu wissen, dass this im aktuellen Kontext tatsächlich window ist.)
  • Wenn Sie ein einzelnes Modul testen möchten, können Sie sehr einfach wissen: Was genau (Abhängigkeiten) beeinflusst den Code, der innerhalb des Moduls ausgeführt wird? Und weil Sie explizit alles einspeisen, können Sie diese Abhängigkeiten leicht verspotten.

Für mich läuft die Verwendung von Modulen für Front-End-Code darauf hinaus, in einem viel engeren Kontext zu arbeiten, über den man leichter nachdenken und testen kann, und mehr Gewissheit darüber zu haben, was vor sich geht.


Das Erlernen der CommonJS/Node-Modulsyntax dauert nur etwa 30 Sekunden. In einer bestimmten JS-Datei, die ein Modul sein soll, deklarieren Sie zunächst alle externen Abhängigkeiten, die Sie verwenden möchten, wie folgt:

var React = require('react');

Innerhalb der Datei/des Moduls können Sie das tun, was Sie normalerweise tun würden, und ein Objekt oder eine Funktion erstellen, die Sie externen Benutzern zur Verfügung stellen möchten, und es möglicherweise myModule nennen.

Am Ende einer Datei exportieren Sie alles, was Sie mit der Welt teilen möchten, wie folgt:

module.exports = myModule;

Um einen CommonJS-basierten Workflow im Browser zu verwenden, verwenden Sie Tools wie Browserify, um alle diese einzelnen Moduldateien zu erfassen, ihren Inhalt zur Laufzeit zu kapseln und sie nach Bedarf ineinander zu injizieren.

UND, da ES6-Module (die Sie wahrscheinlich mit Babel oder ähnlichem auf ES5 übertragen werden) breite Akzeptanz finden und sowohl im Browser als auch in Node 4.0 funktionieren, sollten wir ein gut) erwähnen Übersicht auch von diesen.

Weitere Informationen zu Mustern für die Arbeit mit Modulen in dieses Deck .


EDIT (Feb 2017): Facebooks Yarn ist heutzutage ein sehr wichtiger potenzieller Ersatz/eine Ergänzung für npm: schnelles, deterministisches Offline-Paketmanagement, das auf dem aufbaut, was npm Ihnen bietet. Es lohnt sich, sich ein JS-Projekt anzuschauen, zumal es so einfach ist, es ein- und auszutauschen.


BEARBEITEN (Mai 2019) "Bower wurde endlich veraltet . Ende der Geschichte." (h/t: @DanDascalescu, unten, für eine markige Zusammenfassung.)

Und während Yarn noch aktiv ist, hat sich ein Großteil der Dynamik wieder auf npm verlagert, nachdem einige der Hauptfunktionen von Yarn übernommen wurden.

264
XML

Aktualisierung von 2017 bis Oktober

Bower wurde endlich veraltet . Ende der Geschichte.

Ältere Antwort

Von Mattias Petter Johansson, JavaScript-Entwickler bei Spotify :

In fast allen Fällen ist es besser, Browserify und npm über Bower zu verwenden. Es ist einfach eine bessere Verpackungslösung für Front-End-Apps als Bower. Bei Spotify verwenden wir npm, um ganze Webmodule (html, css, js) zu packen, und das funktioniert sehr gut.

Bower ist selbst der Paketmanager für das Web. Es wäre fantastisch, wenn dies wahr wäre - ein Paketmanager, der mein Leben als Front-End-Entwickler verbessert hätte, wäre fantastisch. Das Problem ist, dass Bower keine speziellen Werkzeuge für diesen Zweck anbietet. Es bietet KEINE Tools, von denen ich weiß, dass sie von npm nicht unterstützt werden, und insbesondere keine, die speziell für Front-End-Entwickler nützlich sind. Ein Front-End-Entwickler hat einfach keinen Vorteil, wenn er Bower über npm verwendet.

Wir sollten aufhören, Bower zu benutzen und uns gegen npm zusammenschließen. Zum Glück ist das, was passiert :

Module counts - bower vs. npm

Mit browserify oder webpack ist es kinderleicht, all Ihre Module zu großen, minimierten Dateien zu verknüpfen. Dies ist besonders für mobile Geräte von großer Leistung. Nicht so bei Bower, der wesentlich mehr Arbeit benötigt, um den gleichen Effekt zu erzielen.

npm bietet Ihnen auch die Möglichkeit, mehrere Versionen von Modulen gleichzeitig zu verwenden. Wenn Sie nicht viel an der Anwendungsentwicklung gearbeitet haben, kann dies zunächst als schlimm empfunden werden, aber wenn Sie ein paar Anfälle von Hölle der Abhängigkeit durchlaufen haben, werden Sie feststellen, dass Sie die Möglichkeit haben, mehrere Versionen zu verwenden eines Moduls ist ein verdammt tolles Feature. Beachten Sie, dass npm ein sehr praktisches Deduplizierungs-Tool enthält, das automatisch sicherstellt, dass Sie nur zwei Versionen eines Moduls verwenden, wenn Sie tatsächlich bis - haben, wenn zwei Module vorhanden sind Beide können die gleiche Version eines Moduls verwenden. Aber wenn sie nicht können, haben Sie ein sehr praktisches Out.

(Beachten Sie, dass Webpack und Rollup ab August 2016 allgemein als besser als Browserify gelten.)

127
Dan Dascalescu

Bower unterhält eine einzelne Version von Modulen und versucht nur, Ihnen bei der Auswahl des richtigen/besten für Sie zu helfen.

Javascript-Abhängigkeitsmanagement: npm vs bower vs volo?

NPM ist besser für Knotenmodule, da es ein Modulsystem gibt und Sie lokal arbeiten. Bower ist gut für den Browser, da es derzeit nur den globalen Geltungsbereich gibt und Sie sehr wählerisch bei der Version sein möchten, mit der Sie arbeiten.

45
Sagivf

Mein Team ist von Bower weggezogen und auf npm umgestiegen, weil:

  • Der programmatische Gebrauch war schmerzhaft
  • Bowers Benutzeroberfläche änderte sich ständig
  • Einige Funktionen, wie die URL-Kurzform, sind vollständig fehlerhaft
  • Die Verwendung von Bower und npm im selben Projekt ist schmerzhaft
  • Es ist schmerzhaft, das bower.json-Versionsfeld mit git-Tags synchron zu halten
  • Quellcodeverwaltung! = Paketverwaltung
  • Die CommonJS-Unterstützung ist nicht einfach

Weitere Informationen finden Sie unter "Warum mein Team npm anstelle von bower verwendet" .

33
Nick Heiner

Fanden diese nützliche Erklärung von http://ng-learn.org/2013/11/Bower-vs-npm/

Einerseits wurde npm erstellt, um Module zu installieren, die in einer node.j-Umgebung verwendet werden, oder um Entwicklungstools zu installieren, die mit node.js wie Karma, Lint, Minifiers usw. erstellt wurden. npm kann Module lokal in einem Projekt installieren (standardmäßig in node_modules) oder global, um von mehreren Projekten verwendet zu werden. In großen Projekten können Abhängigkeiten angegeben werden, indem eine Datei mit dem Namen package.json erstellt wird, die eine Liste von Abhängigkeiten enthält. Diese Liste wird von npm erkannt, wenn Sie npm install ausführen, das sie dann herunterlädt und für Sie installiert.

Andererseits wurde Bower erstellt, um Ihre Frontend-Abhängigkeiten zu verwalten. Bibliotheken wie jQuery, AngularJS, Unterstrich usw. Ähnlich wie npm enthält es eine Datei, in der Sie eine Liste von Abhängigkeiten mit dem Namen bower.json angeben können. In diesem Fall werden Ihre Frontend-Abhängigkeiten durch Ausführen von bower install installiert, das sie standardmäßig in einem Ordner namens bower_components installiert.

Wie Sie sehen, sind sie, obwohl sie eine ähnliche Aufgabe ausführen, auf eine ganz andere Gruppe von Bibliotheken ausgerichtet.

17
Henry Neo

Für viele Leute, die mit node.js arbeiten, ist es ein großer Vorteil von bower, Abhängigkeiten zu verwalten, die überhaupt kein Javascript haben. Wenn sie mit Sprachen arbeiten, die mit Javascript kompiliert werden, können mit npm einige ihrer Abhängigkeiten verwaltet werden. Es werden jedoch nicht alle Abhängigkeiten von node.js Modulen sein. Einige von denen, die mit Javascript kompiliert werden, haben möglicherweise eine seltsame quellsprachenspezifische Verwirrung, die die Weitergabe der mit Javascript kompilierten Dateien zu einer uneleganten Option macht, wenn Benutzer Quellcode erwarten.

Nicht alles in einem npm-Paket muss benutzerbezogenes Javascript sein, aber für npm-Bibliothekspakete sollte zumindest ein Teil davon vorhanden sein.

7
jessopher

Bower und Npm sind Paketmanager für Javascript. Es gibt viele Verwirrungen, wo wir Bower oder Npm verwenden sollten. Einige Projekte haben sowohl Npm als auch Bower. Hier habe ich die Verwendungszwecke dieser beiden Tools erklärt und Sie erfahren, wo die Laube verwendet werden muss und wo npm verwendet werden soll.

Laube

Bower wurde ausschließlich für die Front-End-Entwicklung erstellt und unter Berücksichtigung dessen optimiert. Es wird ein flacher Abhängigkeitsbaum verwendet, für den nur eine Version für jedes Paket erforderlich ist, wodurch die Seitenlast verringert wird. Es zielt hauptsächlich auf minimale Ressourcenbelastung ab.

Bower hat eine Konfigurationsdatei namens bower.json. In dieser Datei können wir die Konfiguration für Bower wie die benötigten Abhängigkeiten und Lizenzdetails, Beschreibung, Name usw. verwalten.

Bower eignet sich für Front-End-Pakete wie JQuery, Angular, React, Glut, Knockout, Backbone und so weiter.

Npm (Node Package Manager)

Npm ist am häufigsten wird zum Verwalten von Node.js-Modulen verwendet, funktioniert aber auch für das Front-End. Es wird ein verschachtelter Abhängigkeitsbaum verwendet. Dies bedeutet, dass Ihre Abhängigkeiten eigene Abhängigkeiten haben können, die eigene Abhängigkeiten haben können, und so weiter. Ein verschachtelter Abhängigkeitsbaum bedeutet, dass Ihre Abhängigkeiten ihre eigenen Abhängigkeiten haben können, die ihre eigenen haben können, und so weiter. Dies ist wirklich großartig auf dem Server, auf dem Speicherplatz und Latenz keine große Rolle spielen.

Dies funktioniert im Frontend offensichtlich nicht so gut, da wir in unseren Projekten jQuery benötigen. Wir brauchen nur eine Kopie von jQuery, aber wenn ein anderes Paket jQuery benötigt, lädt es erneut eine weitere Kopie von jQuery herunter. Dies ist einer der wichtigsten Nachteile von Npm.

Npm hat eine Konfigurationsdatei namens package.json. In dieser Datei können wir die Konfiguration für Npm wie die benötigten Abhängigkeiten und Lizenzdetails, Beschreibung, Name usw. verwalten. Npm bietet Abhängigkeiten und DevDependencies. Abhängigkeiten lädt die Front-End-Dateien wie Jquery, Angular und so weiter herunter und verwaltet sie. DevDependencies lädt und wartet Entwicklungstools wie Grunt, Gulp, JSHint und so weiter.

Der Grund, warum viele Projekte beide verwenden, ist, dass sie Bower für Front-End-Pakete und Npm für Entwicklertools wie Grunt, Gulp, JSHint usw. Verwenden.

3