web-dev-qa-db-fra.com

Quelle est la différence entre Bower et npm?

Quelle est la différence fondamentale entre 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.

1705
Games Brainiac

Tous les gestionnaires de paquets ont de nombreux inconvénients. Vous devez juste choisir avec qui vous pouvez vivre.

Histoire

npm a commencé à gérer les modules node.js (c'est pourquoi les paquetages vont dans node_modules par défaut), mais cela fonctionne aussi pour le front-end lorsqu'il est combiné avec Browserify ou webpack .

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

Taille de repo

npm est beaucoup, beaucoup plus volumineux que bower, y compris le code JavaScript à usage général (comme country-data pour les informations sur le pays ou sorts pour les fonctions de tri utilisables en amont ou en aval).

Bower a une quantité de paquets beaucoup plus petite.

Traitement des styles, etc.

Bower comprend les styles, etc.

npm est axé sur JavaScript. Les styles sont soit téléchargés séparément, soit requis par quelque chose comme npm-sass ou sass-npm.

Traitement des dépendances

La plus grande différence est que npm crée des dépendances imbriquées (mais est plat par défaut), tandis que Bower requiert un arbre de dépendance plat (ce qui met la résolution de la dépendance à la charge de l'utilisateur) .

Un arbre de dépendance imbriqué signifie que vos dépendances peuvent avoir leurs propres dépendances, qui peuvent avoir les leurs, etc. Cela permet à deux modules d’exiger différentes versions de la même dépendance et de continuer à fonctionner. Notez que depuis npm v3, l’arborescence des dépendances disparaît par défaut (gain d’espace) et n’est imbriquée que nécessaire, par exemple si deux dépendances ont besoin de leur propre version de Underscore.

Certains projets utilisent les deux, c’est qu’ils utilisent Bower pour les packages front-end et npm pour les outils de développement tels que Yeoman, Grunt, Gulp, JSHint, CoffeeScript, etc.


Ressources

1883
Sindre Sorhus

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

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

Il est beaucoup plus difficile d'éviter les conflits de dépendance sans imbriquer des dépendances. Ceci est fondamental pour le fonctionnement de npm et s’est avéré une approche extrêmement efficace.

On Bower page d'accueil:

Bower est optimisé pour le front-end. Bower utilise un arbre de dépendance plat, ne nécessitant qu'une version par paquet, ce qui réduit le chargement de pages au 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:

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

Comme vous pouvez le constater, certaines dépendances sont installées de manière récursive. La dépendance A a trois instances installées!

Tonnelle:

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

Vous voyez ici 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, différente de la dépendance C. npm installe les deux versions de cette dépendance, de sorte que cela fonctionnera de toute façon, mais Bower vous donnera un conflit , car elle ne fonctionne pas. comme la duplication (car le chargement de la même ressource sur une page Web est très inefficace et coûteux, il peut en outre générer de graves erreurs). Vous devrez choisir manuellement la version que vous souhaitez installer. Cela peut avoir pour effet qu'une des dépendances va se rompre, mais vous devrez quand même remédier à cela.

Ainsi, l’utilisation courante est Bower pour les packages que vous souhaitez publier sur vos pages Web (par exemple runtime , où vous évitez les doublons), et utilisez npm pour d’autres tâches, telles que testing, construction, optimisation, vérification, etc. (par exemple temps de développement , où la duplication est moins préoccupante).

Mise à jour pour npm 3:

nPM 3 fait toujours les choses différemment par rapport à Bower. Il installera les dépendances globalement, mais uniquement pour la première version rencontrée. 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 version racine)
    • dep C v1.0
      • dep A v2.0 (cette version est différente de la version racine, il s'agira donc d'une installation imbriquée)

Pour plus d'informations, je suggère de lire le docs of npm

356
Justus Romijn

TL; DR: La plus grande différence dans l'utilisation quotidienne ne réside pas dans les dépendances imbriquées ... mais dans la différence entre les modules et les globals.

Je pense que les affiches précédentes ont bien couvert certaines des distinctions fondamentales. (L'utilisation de dépendances imbriquées par npm est en effet très utile pour la gestion d'applications volumineuses et complexes, 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'une des distinctions les plus fondamentales entre Bower et npm. Si vous lisez les réponses ci-dessus, vous verrez que les "modules" de Word sont souvent utilisés dans le contexte de npm. Mais c'est mentionné avec désinvolture, comme s'il pouvait même s'agir d'une différence de syntaxe.

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

L'approche Bower: des ressources globales, comme <script> Balises

À la racine, Bower se charge de charger des fichiers de script ordinaires. Peu importe ce que contiennent ces fichiers de script, Bower les chargera. Ce qui signifie fondamentalement que Bower revient à inclure tous vos scripts dans des <script> simples dans le <head> de votre code HTML.

Donc, même approche de base que vous êtes habitué, mais vous obtenez quelques commodités d'automatisation Nice:

  • Auparavant, vous deviez inclure les dépendances JS dans votre référentiel de projet (pendant le développement) ou les obtenir via CDN. Maintenant, vous pouvez ignorer ce poids de téléchargement supplémentaire dans le référentiel, et quelqu'un peut effectuer rapidement un bower install et obtenir instantanément ce dont il a besoin, localement.
  • Si une dépendance Bower spécifie ensuite ses propres dépendances dans son bower.json, celles-ci seront également téléchargées pour vous.

Mais au-delà, Bower ne change pas la façon dont nous écrivons javascript. Rien de ce qui se passe dans les fichiers chargés par Bower ne doit changer du tout. En particulier, cela signifie que les ressources fournies dans les scripts chargés par Bower seront (toujours, 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épendances explicites

Tout le code dans Nodeland (et donc tout le code chargé via npm) est structuré en modules (en particulier, en tant qu'implémentation de format de module CommonJS , ou maintenant, en tant que module ES6 ) Ainsi, 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 façon que Node.

Des personnes plus intelligentes que moi ont abordé la question "Pourquoi des modules?", Mais voici un résumé de la capsule:

  • Tout ce qui se trouve dans un module est effectivement namespaced, ce qui signifie qu'il ne s'agit plus d'une variable globale et que vous ne pouvez pas la référencer accidentellement sans le vouloir.
  • 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) pour pouvoir être utilisé
  • Cela signifie que vous pouvez avoir plusieurs versions de la même dépendance externe (lodash, par exemple) dans différentes parties de votre application, sans créer de conflit. (Cela arrive étonnamment souvent, car 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 entre en conflit. Ou vous avez deux dépendances externes qui veulent chacune une version différente.)
  • Toutes les dépendances étant injectées manuellement dans un module particulier, il est très facile de les raisonner. Vous savez pertinemment que: "Le seul code que je dois prendre en compte lorsque je travaille dessus est ce que j’ai délibérément choisi d’injecter ici".
  • Parce que même le contenu des modules injectés est encapsulé derrière la variable à laquelle vous l'attribuez, et que tout le code s'exécute dans une portée limitée, les surprises et les collisions deviennent très improbables. Il est beaucoup moins probable que quelque chose de l'une de vos dépendances redéfinisse accidentellement une variable globale sans que vous ne vous en rendiez compte, ou que vous le fassiez. (Cela peut ​​arriver, mais vous devez généralement vous en sortir, avec quelque chose comme window.variable. Le seul accident qui a encore tendance à se produire est l'attribution de this.variable , ne réalisant pas que this est réellement window dans le contexte actuel.)
  • Lorsque vous souhaitez tester un module individuel, vous pouvez très facilement savoir: qu'est-ce qui d'autre (dépendances) affecte le code qui s'exécute dans le module? Et, puisque 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, plus facile à raisonner et à tester, et avoir une plus grande certitude sur ce qui se passe.


Environ 30 secondes sont nécessaires pour apprendre à utiliser la syntaxe du module CommonJS/Node. Dans un fichier JS donné, qui sera un module, vous déclarez d’abord les dépendances extérieures que vous souhaitez utiliser, comme ceci:

var React = require('react');

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

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

module.exports = myModule;

Ensuite, pour utiliser un flux de travail basé sur CommonJS dans le navigateur, vous utiliserez des outils tels que Browserify pour saisir tous les fichiers de module individuels, encapsuler leur contenu à l'exécution et les injecter les uns dans les autres, si nécessaire.

ET, étant donné que les modules ES6 (que vous transpirerez probablement sur ES5 avec Babel ou similaire) sont de plus en plus acceptés et fonctionnent aussi bien dans le navigateur que dans Node 4.0, nous devrions mentionner a bon aperç de ceux-là aussi.

Plus d'informations sur les modèles d'utilisation des modules dans this deck .


EDIT (février 2017): Le fil Yarn de Facebook est un potentiel de remplacement/supplément très important pour npm de nos jours: une gestion de paquetages rapide, déterministe et hors ligne qui s'appuie sur ce que npm vous apporte. Cela vaut la peine de jeter un coup d’œil sur tout projet JS, d’autant plus qu’il est très facile de l’échanger.


EDIT (mai 2019) "Bower a finalement été obsolète . Fin de l'histoire." (h/t: @DanDascalescu, ci-dessous, pour un résumé complet).

Et, alors que Yarn est toujours actif , la dynamique s’est en grande partie déplacée vers npm une fois qu’il a adopté certaines des caractéristiques clés de Yarn.

264
XML

Mise à jour 2017-oct.

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

Réponse plus ancienne

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 emballer des modules Web entiers (html, css, js) et cela fonctionne très bien.

Bower se présente comme le gestionnaire de paquets pour le Web. Ce serait génial si cela était vrai - un gestionnaire de paquets qui améliorerait ma vie en tant que développeur front-end serait génial. Le problème est que Bower n’offre aucun outillage spécialisé à cet effet. Je ne connais AUCUN outil que je sache, mais surtout aucun outil particulièrement utile pour les développeurs front-end. Il n’ya aucun avantage pour un développeur frontal à utiliser Bower over npm.

Nous devrions cesser d’utiliser Bower et nous regrouper autour de npm. Heureusement, c'est ce que se passe :

Module counts - bower vs. npm

Avec browserify ou webpack, il devient extrêmement facile de concaténer tous vos modules en gros fichiers minifiés, ce qui est génial pour la performance, en particulier pour les appareils mobiles. Ce n’est pas le cas avec Bower, qui aura besoin de 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 au départ vous paraître mauvais, mais une fois que vous avez traversé quelques épisodes de enfer de la dépendance , vous réaliserez qu’il est possible d’avoir plusieurs versions. d'un module est une très belle fonctionnalité. Notez que npm inclut un très pratique outil de déduplication qui garantit automatiquement que vous n’utilisez que deux versions d’un module si vous avez à (si) deux modules les deux peuvent utiliser la 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 rollup sont largement considérés comme étant meilleurs que Browserify à partir d'août 2016.)

127
Dan Dascalescu

Bower maintient une version unique des modules, il essaie seulement de vous aider à choisir celui qui vous convient le mieux.

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

NPM est préférable pour les modules de noeud car il existe un système de modules et que vous travaillez localement. Bower est bon pour le navigateur car il n’ya actuellement qu’une portée globale et vous voulez être très sélectif quant à la version avec laquelle vous travaillez.

45
Sagivf

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

  • L'utilisation programmatique était douloureuse
  • L'interface de Bower ne cessait de changer
  • Certaines fonctionnalités, comme le raccourci d'URL, sont entièrement cassées
  • Utiliser Bower et npm dans le même projet est pénible
  • Garder le champ de la version de bower.json synchronisé avec les balises git est douloureux
  • Contrôle de la source! = Gestion des paquets
  • Le support CommonJS n'est pas simple

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

33
Nick Heiner

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 environnement node.js ou des outils de développement construits à l'aide de node.js tels que Karma, lint, minifiers, etc. 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 manière de spécifier des dépendances consiste à créer un fichier appelé package.json contenant 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 frontales. Bibliothèques telles que jQuery, AngularJS, underscore, etc. Similaire à npm, il contient un fichier dans lequel vous pouvez spécifier une liste de dépendances appelée bower.json. Dans ce cas, vos dépendances frontales sont installées en exécutant bower install qui les installe par défaut dans un dossier appelé bower_components.

Comme vous pouvez le constater, bien qu’ils effectuent une tâche similaire, ils s’adressent à un ensemble de bibliothèques très différent.

17
Henry Neo

Pour de nombreuses personnes travaillant avec node.js, l'un des principaux avantages de bower est la gestion des dépendances qui ne sont pas du tout du javascript. S'ils travaillent avec des langages compilés en javascript, npm peut être utilisé pour gérer certaines de leurs dépendances. Cependant, toutes leurs dépendances ne seront pas des modules node.js. Certains de ceux qui compilent en javascript peuvent avoir un comportement étrange lié au langage source, ce qui fait que leur compilation compilée en javascript est une option inélégante lorsque les utilisateurs attendent du code source.

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

7
jessopher

Bower et Npm sont des gestionnaires de paquets pour javascript. Il y a beaucoup de confusion lorsque nous devrions utiliser Bower ou Npm. Certains projets ont Npm et Bower tous les deux. Ici, j’ai expliqué les objectifs de ces deux outils et vous apprendrez où bower doit être utilisé et où npm doit être utilisé.

Bower

Bower est créé niquement pour le développement frontal et est optimisé dans cet esprit. Il utilise un arbre de dépendance plat, ne nécessitant qu'une version par paquet, ce qui réduit le chargement de la page. Il vise principalement une charge de ressources minimale.

Bower a un fichier de configuration appelé bower.json. Dans ce fichier, nous pouvons gérer la configuration de Bower, notamment les dépendances dont nous avons besoin, les détails de la licence, la description, le nom, etc.

Bower convient aux paquets front-end tels que jquery, angular, react, braise, knock-out, colonne vertébrale, etc.

Npm (gestionnaire de paquet de noeud)

Npm est le plus souvent tilisé pour gérer les modules Node.js, mais cela fonctionne aussi pour le front-end. Il utilise un arbre de dépendance imbriqué, ce qui signifie que vos dépendances peuvent avoir leurs propres dépendances, qui peuvent avoir les leurs, etc. Un arbre de dépendance imbriqué signifie que vos dépendances peuvent avoir leurs propres dépendances, qui peuvent avoir les leurs, etc. C'est vraiment génial sur le serveur où vous n'avez pas à vous soucier de l'espace et de la latence.

Cela ne fonctionne évidemment pas très bien au départ car nous avons besoin de jQuery dans nos projets. Nous n'avons besoin que d'une copie de jQuery, mais lorsqu'un autre paquet nécessite jQuery, il téléchargera une nouvelle copie de jQuery. C’est l’un des principaux inconvénients de Npm.

Npm a un fichier de configuration appelé package.json. Dans ce fichier, nous pouvons gérer la configuration de Npm, notamment les dépendances dont nous avons besoin, les détails de la licence, la description, le nom, etc. Npm fournit des dépendances et DevDependencies. Dependencies téléchargera et conservera les fichiers frontaux tels que Jquery, Angular et ainsi de suite. DevDependencies téléchargera et maintiendra des outils de développement tels que Grunt, Gulp, JSHint, etc.

La raison pour laquelle de nombreux projets utilisent ces deux technologies est qu’elles utilisent Bower pour les packages front-end et Npm pour les outils de développement tels que Grunt, Gulp, JSHint, etc.

3
Saniya syed qureshi