Quelle est la différence entre Bower et npm?

Quelle est la différence fondamentale entre les bower et npm? Je veux juste quelque chose de clair et simple. J'ai vu certains de mes collègues utiliser bower et npm de manière interchangeable dans leurs projets.

1636
demandé sur Haifeng Zhang 2013-09-05 20:53:19

9 réponses

Tous les gestionnaires de paquets ont de nombreux inconvénients. Vous avez juste à choisir ce que vous pouvez vivre avec.

Historique

Npm a commencé à gérer le nœud.les modules js (c'est pourquoi les paquets vont dans node_modules par défaut), mais cela fonctionne aussi pour le frontal lorsqu'il est combiné avec Browserify ou WebPack.

Bower est créé uniquement pour le front-end et est optimisé dans cet esprit.

Taille du repo

Mnp est beaucoup, beaucoup plus grand que bower, y compris JavaScript à usage général (comme country-data pour les informations de pays ou sorts pour les fonctions de tri utilisables sur le frontal ou le back end).

Bower a une quantité beaucoup plus petite de paquets.

Gestion des styles etc

Bower comprend des styles, etc.

Npm se concentre sur JavaScript. Les Styles sont téléchargés séparément ou requis par quelque chose comme npm-sass ou sass-npm.

Gestion des Dépendances

La plus grande différence est que npm ne imbriqué dépendances (mais est plat par défaut) tandis que Bower nécessite un arbre de dépendance plat (met le fardeau de la résolution des dépendances sur l'utilisateur) .

Un arbre de dépendance imbriqué signifie que vos dépendances peuvent avoir leurs propres dépendances qui peuvent avoir les leurs, et ainsi de suite. Cela permet à deux modules d'exiger des versions différentes de la même depndency et de continuer à fonctionner. Notez que depuis npm v3, l'arborescence des dépendances sera par défaut plate (économisant de l'espace) et ne s'imbriquera que si nécessaire, par exemple si deux les dépendances ont besoin de leur propre version de Underscore.

Certains projets utilisent les deux, C'est Qu'ils utilisent Bower pour les paquets frontaux et npm pour les outils de développement tels que Yeoman, Grunt, Gulp, JSHint, CoffeeScript, etc.


Ressources

1842
répondu Sindre Sorhus 2018-06-29 11:57:23

Cette réponse est un ajout à la réponse de Sindre Sorhus. La principale différence entre npm et Bower est la façon dont ils traitent les dépendances récursives. Notez qu'ils peuvent être utilisés ensemble dans un seul projet.

Sur la FAQ npm: (archive.org lien du 6 septembre 2015)

, Il est beaucoup plus difficile d'éviter les conflits de dépendance sans imbrication dépendance. Ceci est fondamental pour la façon dont npm fonctionne, et a avéré être un très grand succès approche.

Le Bower page d'accueil:

Bower est optimisé pour le front-end. Bower utilise une dépendance plate arborescence, ne nécessitant qu'une seule version pour chaque paquet, réduisant le chargement de la page à un minimum.

En bref, npm vise la stabilité. Bower vise une charge de ressources minimale. Si vous dessinez la structure de dépendance, vous verrez ceci:

Mnp:

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

Comme vous pouvez le voir, il installe certaines dépendances récursivement. La Dépendance D'Un a trois instances installées!

Bower:

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

Ici vous voyez que toutes les dépendances uniques sont au même niveau.

Alors, pourquoi s'embêter à utiliser npm?

Peut-être que la dépendance B nécessite une version différente de la dépendance a que la dépendance C. npm installe les deux versions de cette dépendance donc cela fonctionnera de toute façon, mais Bower vous donnera un conflit car il n'aime pas la duplication (car charger la même ressource sur une page web est très inefficace et coûteux, aussi il peut donner quelques erreurs graves). Vous devrez choisir manuellement la version que vous souhaitez installer. Cela peut avoir pour effet que l'une des dépendances se brise, mais c'est quelque chose que vous devrez réparer de toute façon.

Ainsi, L'utilisation courante est Bower pour les paquets que vous souhaitez publier sur vos pages Web (par exemple runtime, où vous évitez la duplication), et utilisez npm pour d'autres choses, comme tester, construire, optimiser, vérifier, etc. (par ex. Temps de développement, où la duplication est moins préoccupante).

Mise à Jour pour la ngp 3:

Npm 3 fait toujours les choses différemment par rapport à Bower. Il installera les dépendances globalement, mais seulement pour la première version qu'il rencontre. Les autres versions sont installées dans l'arborescence (le module parent, puis node_modules).

  • [node_modules]
    • dep a v1. 0
    • dep B v1.0
      • dep a v1. 0 (utilise la racine version)
    • dep C v1.0
      • dep a v2. 0 (Cette version est différente de la version racine, ce sera donc une installation imbriquée)

Pour plus d'informations, je suggère de lire les documents de npm 3

341
répondu Justus Romijn 2018-07-05 13:33:22

TL; DR: la plus grande différence dans l'utilisation quotidienne n'est pas les dépendances imbriquées... c'est la différence entre les modules et les globaux.

Je pense que les affiches précédentes ont bien couvert certaines des distinctions de base. (l'utilisation de dépendances imbriquées par npm est en effet très utile dans la gestion d'applications complexes et volumineuses, bien que je ne pense pas que ce soit la distinction la plus importante.)

Je suis surpris, cependant, que personne n'ait explicitement expliqué l'un des plus fondamentaux distinctions entre Bower et npm. Si vous lisez les réponses ci-dessus, vous verrez le mot "modules" utilisé souvent dans le contexte de npm. Mais il est mentionné avec désinvolture, comme si cela pouvait même être une différence de syntaxe.

Mais cette distinction de modules vs globals (ou modules vs 'scripts') est peut-être la différence la plus importante entre Bower et npm. L'approche npm de tout mettre en modules vous oblige à changer la façon dont vous écrivez Javascript pour le navigateur, presque certainement pour le mieux.

L'Approche Bower: Ressources Globales, Comme <script> Tags

À la racine, Bower consiste à charger des fichiers de script anciens. Quel que soit le contenu de ces fichiers de script, Bower les chargera. Ce qui signifie essentiellement que Bower est comme inclure tous vos scripts dans les vieux <script> dans le <head> de votre HTML.

Donc, même approche de base à laquelle vous êtes habitué, mais vous obtenez de belles commodités d'automatisation:

  • tu en avais besoin incluez les dépendances JS dans votre repo de projet (pendant le développement), ou obtenez-les via CDN. Maintenant, vous pouvez sauter ce poids de téléchargement supplémentaire dans le repo, et quelqu'un peut faire un rapide bower install et instantanément avoir ce dont ils ont besoin, localement.
  • si une dépendance Bower spécifie alors ses propres dépendances dans son bower.json, celles-ci seront également téléchargées pour vous.

Mais au-delà de cela, Bower ne change pas la façon dont nous écrivons javascript . Rien sur ce qui se passe à l'intérieur des fichiers chargés par Bower besoin de changement. En particulier, cela signifie que les ressources fournies dans les scripts chargés par Bower seront (généralement, mais pas toujours) toujours définies comme variables globales, disponibles à partir de n'importe où dans le contexte d'exécution du navigateur.

L'approche npm: modules js communs, injection de dépendance explicite

Tout le code dans Node land (et donc tout le code chargé via npm) est structuré en modules (en particulier, comme une implémentation du format de module CommonJS , ou maintenant, comme un module ES6). Donc, si vous utilisez NPM pour gérer les dépendances côté navigateur (via Browserify ou autre chose qui fait le même travail), vous structurerez votre code de la même manière que Node.

Des gens plus intelligents que moi ont abordé la question de " pourquoi les modules?", Mais voici un résumé de la capsule:

  • Tout ce qui se trouve dans un module est effectivement namespaced , ce qui signifie que ce n'est plus une variable globale, et vous ne pouvez pas la référencer accidentellement sans l'intention de.
  • Tout ce qui se trouve à l'intérieur d'un module doit être intentionnellement injecté dans un contexte particulier (généralement un autre module) afin d'en faire usage
  • cela signifie que vous pouvez avoir plusieurs versions de la même dépendance externe (lodash, disons) dans différentes parties de votre application, et elles ne se heurteront pas/ne seront pas en conflit. (Cela arrive étonnamment souvent, parce que votre propre code veut utiliser une version d'une dépendance, mais l'une de vos dépendances externes en spécifie une autre qui est en conflit. Ou vous avez deux dépendances externes qui veulent chacune une version différente.)
  • Comme toutes les dépendances sont injectées manuellement dans un module particulier, il est très facile de les raisonner. Vous savez pertinemment: "le seul code que je dois prendre en compte lorsque je travaille sur ceci est ce que j'ai intentionnellement choisi d'injecter ici" .
  • parce que même le contenu des modules injectés est encapsulé derrière la variable à laquelle vous l'affectez, et tout le code s'exécute dans un portée limitée, surprises et collisions deviennent très improbables. Il est beaucoup, beaucoup moins probable que quelque chose de l'une de vos dépendances redéfinisse accidentellement une variable globale sans que vous vous en rendiez compte, ou que vous le fassiez. (Il peut arriver, mais vous devez généralement faire tout votre possible pour le faire, avec quelque chose comme window.variable. Le seul accident qui a encore tendance à se produire est d'attribuer this.variable, sans se rendre compte que this est en fait window dans le contexte actuel.)
  • Quand vous voulez pour tester un module individuel, vous pouvez très facilement savoir: exactement quoi d'autre (dépendances) affecte le code qui s'exécute à l'intérieur du module? Et, parce que vous injectez explicitement tout, vous pouvez facilement vous moquer de ces dépendances.

Pour moi, l'utilisation de modules pour le code frontal se résume à: travailler dans un contexte beaucoup plus étroit qui est plus facile à raisonner et à tester, et avoir une plus grande certitude sur ce qui se passe.


Cela ne prend qu'environ 30 secondes pour apprendre à utiliser la syntaxe du module CommonJS/Node. Dans un fichier JS donné, qui va être un module, vous déclarez d'abord toutes les dépendances extérieures que vous voulez utiliser, comme ceci:

var React = require('react');

Dans le fichier / module, vous faites ce que vous voulez normalement, et créez un objet ou une fonction que vous voudrez exposer à des utilisateurs extérieurs, en l'appelant peut-être myModule.

A la fin d'un fichier, vous exportez ce que vous voulez partager avec le monde, comme ce:

module.exports = myModule;

Ensuite, pour utiliser un flux de travail basé sur CommonJS dans le navigateur, vous utiliserez des outils tels que Browserify pour récupérer tous ces fichiers de modules individuels, encapsuler leur contenu à l'exécution et les injecter les uns dans les autres au besoin.

Et, puisque les modules ES6 (que vous allez probablement transpiler vers ES5 avec Babel ou similaire) gagnent une large acceptation, et fonctionnent à la fois dans le navigateur ou dans le nœud 4.0, nous devrions mentionner un bon aperçu de ceux-ci aussi.

Plus sur les modèles pour travailler avec des modules dans cette plate-forme.


EDIT (Feb 2017): Yarn de Facebook est un remplacement/supplément potentiel très important pour npm ces jours-ci: gestion de paquets rapide, déterministe et hors ligne qui s'appuie sur ce que npm vous donne. Cela vaut la peine de regarder n'importe quel projet JS, d'autant plus qu'il est si facile de l'échanger.

256
répondu XML 2017-05-07 07:39:28

Mise à jour 2017-Octobre

Bower a finalement été obsolète. Fin de l'histoire.

Ancienne Réponse

De Mattias Petter Johansson, développeur JavaScript chez Spotify :

Dans presque tous les cas, il est plus approprié d'utiliser Browserify et npm sur Bower. C'est simplement une meilleure solution d'emballage pour les applications frontales que Bower. Chez Spotify, nous utilisons npm pour empaqueter des modules web entiers (html, css, js) et cela fonctionne très bien.

Bower marques comme le gestionnaire de paquets pour le web. Ce serait génial si cela était vrai - un gestionnaire de paquets qui a rendu ma vie meilleure en tant que développeur frontal serait génial. Le problème est que Bower n'offre aucun outillage spécialisé à cet effet. Il n'offre aucun outillage que je connaisse que npm ne le fait pas, et surtout aucun qui n'est spécifiquement utile pour les développeurs frontaux. Il n'y a tout simplement aucun avantage pour un développeur frontal à utiliser Bower sur npm.

Nous devrions cesser d'utiliser bower et consolider autour npm. Heureusement, c'est ce que se passe:

Nombre de modules-bower vs npm

Avec browserify ou webpack, il devient super facile de concaténer tous vos modules en gros fichiers minifiés, ce qui est génial pour les performances, en particulier pour les appareils mobiles. Pas avec Bower, ce qui nécessitera beaucoup plus de travail pour obtenir le même effet.

Npm vous offre également la possibilité d'utiliser plusieurs versions de modules simultanément. Si vous n'avez pas fait beaucoup de développement d'applications, cela pourrait d'abord vous sembler une mauvaise chose, mais une fois que vous avez traversé quelques épisodes de dépendance enfer vous vous rendrez compte que la possibilité d'avoir plusieurs versions d'un module est une fonctionnalité sacrément grande. Notez que npm inclut un outil très pratique dedupe {[4] } qui s'assure automatiquement que vous n'utilisez que deux versions d'un module si vous avez à-si deux modules peuvent utiliser le même version d'un module, ils le feront. Mais s'ils ne peuvent pas , Vous avez une sortie très pratique.

(Notez que Webpack et cumulatif sont largement considérés comme mieux que Browserify que de Août 2016.)

120
répondu Dan Dascalescu 2017-11-16 21:40:48

Bower maintient une seule version de modules, il essaie seulement de vous aider à sélectionner la bonne / meilleure pour vous.

Gestion des dépendances Javascript: npm vs bower vs volo?

NPM est meilleur pour les modules de nœuds car il existe un système de modules et vous travaillez localement. Bower est bon pour le navigateur car il n'y a actuellement que la portée globale, et vous voulez être très sélectif sur la version avec laquelle vous travaillez.

43
répondu Sagivf 2017-05-23 11:55:01

Mon équipe s'est éloignée de Bower et a migré vers npm parce que:

  • L'utilisation programmatique était douloureuse
  • L'interface de Bower a continué à changer
  • Certaines fonctionnalités, comme le raccourci url, sont entièrement brisées
  • utiliser à la fois Bower et npm dans le même projet est douloureux
  • garder bower.le champ de version json synchronisé avec les balises git est douloureux
  • Contrôle De La Source != gestion des paquets
  • Le support de CommonJS n'est pas simple

Pour plus de détails, voir "Pourquoi mon équipe utilise npm au lieu de bower" .

31
répondu Nick Heiner 2015-11-21 04:04:51

Trouvé cette explication utile de http://ng-learn.org/2013/11/Bower-vs-npm/

D'une part, npm a été créé pour installer des modules utilisés dans un nœud.environnement js, ou outils de développement construits à l'aide de node.js tel Karma, peluches, minifiers et ainsi de suite. npm peut installer des modules localement dans un projet ( par défaut dans node_modules ) ou globalement pour être utilisés par plusieurs projets. Dans les grands projets, la façon de spécifier les dépendances consiste à créer un fichier appelé package.JSON qui contient une liste de dépendances. Cette liste est reconnue par npm lorsque vous exécutez npm install, qui les télécharge et les installe pour vous.

D'autre part bower a été créé pour gérer vos dépendances frontend. Bibliothèques comme jQuery, AngularJS,underscore, etc. Semblable à npm, il a un fichier dans lequel vous pouvez spécifier une liste de dépendances appelée bower.json. Dans ce cas vos dépendances frontend sont installées en exécutant bower install qui les installe par défaut dans un dossier appelé bower_components.

Comme vous pouvez le voir, bien qu'ils effectuent une tâche similaire, ils sont ciblés sur un ensemble très différent de bibliothèques.

14
répondu Henry Neo 2014-10-10 03:26:45

Pour de nombreuses personnes travaillant avec node.js, un avantage majeur de bower est de gérer les dépendances qui ne sont pas du tout javascript. S'ils travaillent avec des langages qui compilent en javascript, npm peut être utilisé pour gérer certaines de leurs dépendances. cependant, toutes leurs dépendances ne seront pas node.modules js. Certains de ceux qui compilent en javascript peuvent avoir une modification étrange du langage source qui rend leur passage compilé en javascript une option inélégante lorsque les utilisateurs sont attendre le code source.

Tout dans un paquet npm ne doit pas être JavaScript orienté utilisateur, mais pour les paquets de bibliothèque npm, au moins une partie devrait l'être.

4
répondu jessopher 2014-10-11 21:27:09

Bower et Npm sont des gestionnaires de paquets pour javascript.

Bower

Bower est créé uniquement pour le développement frontal. Il utilise un arbre de dépendance plat, nécessitant une seule version pour chaque paquet, réduisant ainsi le chargement de la page. Il vise principalement une charge de ressources minimale. Il a moins de contributeurs et donc le processus de développement est lent.

Bower a un fichier de configuration appelé bower.json. Dans ce fichier Nous pouvons maintenir la configuration pour Bower comme quelles dépendances nous besoin et détails de licence, description, Nom et ainsi de suite. Bower convient aux paquets frontaux comme jquery, angular, react, ember, knockout, backbone et ainsi de suite.

Npm

Npm est le plus couramment utilisé pour gérer le nœud.modules js, mais cela fonctionne aussi pour le front-end. Il utilise l'arbre de dépendance imbriqué ainsi que l'arbre de dépendance plat. Il est populaire et a beaucoup de contributeurs. Donc sa nouvelle version vient toujours avec des fonctionnalités intéressantes.

Mnp a un fichier de configuration package appelé.json. Dans ce fichier, Nous pouvons maintenir la configuration pour Npm comme les dépendances dont nous avons besoin et les détails de la licence, la description, le nom et ainsi de suite. Npm fournit des dépendances et DevDependencies. Les dépendances téléchargeront et maintiendront les fichiers frontaux comme Jquery, Angular et ainsi de suite. DevDependencies téléchargera et maintiendra des outils de développement comme Grunt, Gulp, JSHint et ainsi de suite.

Cela ne fonctionne évidemment pas si bien sur le front-end, car nous avons besoin de jQuery dans notre projet. Nous avons besoin d'une seule copie de jQuery, mais quand un autre paquet nécessite jQuery, alors il téléchargera à nouveau une copie de plus de jQuery. C'est l'un des principaux inconvénients de la Ngp.

Note clé: la raison pour laquelle de nombreux projets utilisent les deux est Qu'ils utilisent Bower pour les paquets frontaux et Npm pour les outils de développement. Multiplier le gestionnaire de paquets dans votre projet rend votre flux de travail plus difficile. Npm 3 couplé avec browserify ou webpack est la voie à suivre maintenant.

1
répondu Abdul Alim Shakir 2018-01-07 09:26:35