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 simple et simple. J'ai vu certains de mes collègues utiliser bower et npm manière interchangeable dans leurs projets.

Npm est le plus utilisé pour la gestion des modules Node.js, mais il fonctionne également pour l' interface frontale combiné à la décompte Browserify et / ou $ npm dedupe .

Bower est créé uniquement pour le front-end et est optimisé dans cet esprit. La plus grande différence est que npm fait l'arbre de dépendance imbriqué (taille lourde) tandis que Bower nécessite un arbre de dépendance plate (met le fardeau de la résolution de dépendance sur l'utilisateur) .

Une arborescence de dépendance imbriquée signifie que vos dépendances peuvent avoir leurs propres dépendances qui peuvent avoir leurs propres, et ainsi de suite. C'est vraiment génial sur le serveur où vous n'avez pas à vous soucier de l'espace et de la latence. Il vous permet de ne pas vous soucier des conflits de dépendance, car toutes vos dépendances utilisent, par exemple, leur propre version de soulignement. Cela évidemment ne fonctionne pas bien sur le front-end. Imaginez un site devant télécharger trois copies de jQuery.

La raison pour laquelle de nombreux projets utilisent les deux, c'est qu'ils utilisent Bower pour les packs frontaux et npm pour les outils de développement tels que Yeoman, Grunt, Gulp, JSHint, CoffeeScript, etc.

Tous les gestionnaires de paquets ont de nombreux inconvénients. Il suffit de choisir avec lequel vous pouvez vivre.


Ressources

  • Dépendances imbriquées – Insight sur pourquoi node_modules fonctionne comme il le fait

Cette réponse est une addition à 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 de Npm :

Il est beaucoup plus difficile d'éviter les conflits de dépendance sans dépendance de nidification. Ceci est fondamental pour la façon dont npm fonctionne et s'est avéré être une approche extrêmement réussie.

Sur la page d'accueil de Bower :

Bower est optimisé pour le front-end. Bower utilise un arborescence de dépendance plate, nécessitant une seule version pour chaque paquet, ce qui réduit le chargement de la page au minimum.

Bref, npm vise la stabilité. Bower vise une charge de ressources minimale. Si vous extrayez la structure de dépendance, vous verrez cela:

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 voir, installe certaines dépendances 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 

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

Alors, pourquoi ennuyer en utilisant 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 afin qu'elle fonctionne de toute façon, mais Bower vous donnera un conflit car il n'aime pas la duplication (car le chargement de la même ressource sur une page Web est Très inefficace et coûteuse, elle peut aussi donner des erreurs sérieuses). 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ésoudre de toute façon.

Ainsi, l'utilisation courante est Bower pour les paquets que vous souhaitez publier sur vos pages Web (par exemple, l' exécution , où vous évitez les doublons) et utilisez npm pour d'autres éléments, comme les tests, la construction, l'optimisation, la vérification, etc. (p. Ex. , 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 à l'échelle mondiale, mais uniquement pour la première version qu'elle 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 version racine)
    • Dep C v1.0
      • Dep A v2.0 (cette version est différente de la version racine, donc une installation imbriquée)

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

TL: DR: la plus grande différence dans l'utilisation quotidienne n'est pas une dépendance imbriquée … c'est la différence entre les modules et les globals.

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

Je suis toutefois surpris que personne n'ait explicitement expliqué une des distinctions les plus fondamentales 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é de façon décontractée, comme s'il s'agissait même d'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 exige que vous modifiez la façon dont vous écris Javascript pour le navigateur, pour certainement pour le mieux.

The Bower Approach: Ressources mondiales, comme <script> Tags

À la racine, Bower s'appuie sur le chargement de fichiers de script simples. Quels que soient ces fichiers de script contiennent, Bower les chargera. Ce qui signifie essentiellement que Bower ressemble à inclure tous vos scripts dans des <script> simples dans la <head> de votre code HTML.

Donc, la même approche de base que vous avez l'habitude, mais vous obtenez de bonnes commodités d'automatisation:

  • Vous aviez besoin d'inclure les dépendances de JS dans votre compte de projet (en cours de développement) ou de les obtenir via CDN. Maintenant, vous pouvez ignorer ce poids de téléchargement supplémentaire dans le compte de rechange, et quelqu'un peut faire une bower install rapide et avoir instantanément ce dont ils ont besoin localement.
  • Si une dépendance Bower spécifie 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 à propos de ce qui se passe dans les fichiers chargés par Bower doit changer du tout. En particulier, cela signifie que les ressources fournies dans les scripts chargés par Bower (généralement, mais pas toujours) seront toujours définies comme des 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, en tant que mise en œuvre du format du module CommonJS , ou maintenant, en tant que 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 personnes plus intelligentes que j'ai abordé la question de «Pourquoi les modules?», Mais voici un sommaire de la capsule:

  • Tout ce qui se trouve à l'intérieur d'un module est effectivement dénommé , ce qui signifie qu'il ne s'agit plus d'une variable globale, et vous ne pouvez pas vous référer accidentellement sans avoir l'intention de le faire.
  • Tout ce qui se trouve dans un module doit être injecté intentionnellement dans un contexte particulier (généralement un autre module) afin de l'utiliser
  • Cela signifie que vous pouvez avoir plusieurs versions de la même dépendance externe (lodash, disons) dans diverses parties de votre application, et elles ne vont pas entrer en collision ou conflit. (Cela se produit étonnamment souvent, car votre propre code veut utiliser une version d'une dépendance, mais une de vos dépendances externes spécifie une autre qui entre en conflit. Ou vous avez deux dépendances externes qui veulent toutes une version différente.)
  • Parce que toutes les dépendances sont injectées manuellement dans un module particulier, il est très facile de raisonner à leur sujet. Vous savez par un fait: "Le seul code que je dois considérer lorsque je travaille sur ce sujet 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 que vous l'affectez, et que tout 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 automatiquement une variable globale sans que vous ne la réalisiez ou que vous le fassiez. (Cela peut arriver, mais il faut que vous fassiez partie de votre chemin, avec quelque chose comme window.variable . L'accident qui a toujours eu lieu est d'attribuer cette this.variable , ne pas se rendre compte qu'il s'agit en réalité d'une window dans le courant le contexte.)
  • Lorsque vous souhaitez tester un module individuel, vous pouvez facilement le savoir: exactement, quoi d'autre (dépendances) affecte le code qui se déroule dans le module? Et, parce que vous injectez explicitement tout, vous pouvez facilement se moquer de ces dépendances.

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


Il ne faut que 30 secondes pour apprendre à utiliser la syntaxe du module CommonJS / Node. À l'intérieur d'un fichier JS donné, qui va être un module, vous déclarez tout d'abord les dépendances extérieures que vous souhaitez utiliser, comme ceci:

var React = require('react');

À l'intérieur du 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 .

À la fin d'un fichier, vous exportez ce que vous souhaitez 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 comme Browserify pour saisir tous ces fichiers de modules individuels, encapsuler leur contenu au moment de l'exécution et les injecter les uns aux autres au besoin.

Et, étant donné que les modules ES6 (que vous transporteras probablement vers ES5 avec Babel ou similaire) gagnent une grande acceptation et fonctionnent à la fois dans le navigateur ou dans Node 4.0, nous devrions mentionner un bon aperçu de ces derniers.

En savoir plus sur les modèles pour travailler avec les modules dans ce jeu .


EDIT (février 2017): Facebook's Yarn 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. Il vaut la peine de regarder tout projet JS, d'autant plus qu'il est si facile de l'échanger.

2017-Mai mise à jour

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

Réponse plus ancienne

De Mattias Petter Johansson, développeur de 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 est. Chez Spotify, nous utilisons npm pour coller des modules Web entiers (html, css, js) et cela fonctionne très bien.

Bower se marque en tant que gestionnaire de paquets pour le web. Ce serait génial si cela était vrai – un gestionnaire de paquetage qui améliorerait la vie en tant que développeur frontal serait génial. Le problème est que Bower n'offre aucun outil spécialisé à cet effet. Il n'offre aucun outil que je sais que npm ne fonctionne pas, et en particulier aucun qui est spécifiquement utile pour les développeurs de front-end. Il n'y a tout simplement aucun avantage pour un développeur frontal d'utiliser Bower sur npm.

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

Le module compte - bower vs. npm

Avec le navigateur ou le webpack, il devient super-facile de concaténer tous vos modules dans de grands fichiers minifiés, ce qui est génial pour les performances, en particulier pour les appareils mobiles. Pas tellement 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 vous frapper comme une mauvaise chose, mais une fois que vous avez traversé quelques blessures de l' enfer de la dépendance, vous vous rendez compte que la possibilité d'avoir plusieurs versions d'un module est très jolie Excellente fonctionnalité. Notez que npm comprend un outil de décompte très pratique qui garantit automatiquement que vous utilisez uniquement deux versions d'un module si vous devez réellement – si deux modules peuvent utiliser la même version d'un module, ils le feront. Mais s'ils ne le peuvent pas , vous êtes très pratique.

(Notez que Webpack et rollup sont généralement considérés comme meilleurs que Browserify à partir d'août 2016.)

Bower maintient une seule version de modules, elle tente uniquement de vous aider à sélectionner le meilleur / meilleur pour vous.

Gestion de la dépendance Javascript: npm vs bower vs volo?

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

Mon équipe s'est éloigné de Bower et a migré vers npm car:

  • L'utilisation programmatique était pénible
  • L'interface de Bower n'a cessé de changer
  • Certaines fonctionnalités, comme la sténographie url, sont entièrement brisées
  • L'utilisation de Bower et de npm dans le même projet est douloureuse
  • Garder le champ de la version bower.json en synchronisation avec les tags git est douloureux
  • Contrôle source! = Gestion des paquets
  • Le soutien de CommonJS n'est pas simple

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

J'ai trouvé cette explication utile à partir 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 Karma, peluches, minifiers, etc. Npm peut installer des modules localement dans un projet (par défaut dans node_modules) ou globalement pour être utilisé par plusieurs projets. Dans les grands projets, la façon de spécifier les dépendances est de 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. Des bibliothèques comme jQuery, AngularJS, soulignement, etc. Comme pour npm il a un fichier dans lequel vous pouvez spécifier une liste de dépendances appelées bower.json. Dans ce cas, vos dépendances frontend sont installées en exécutant l'installation de bower qui, par défaut, les installe dans un dossier appelé bower_components.

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

Pour beaucoup de 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 langues qui compilaient sur 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 compiler sur javascript peuvent avoir une source de langue source source étrange, ce qui rend le passage sur les compilé à javascript une option inelegant lorsque les utilisateurs s'attendent à un code source.

Pas tout dans un paquet npm doit être javascript orienté vers l'utilisateur, mais pour les paquets de bibliothèque npm, au moins certains d'entre eux devraient être.

J'aimerais essayer de répondre

"Il n'y a tout simplement aucun avantage pour un développeur frontal à utiliser Bower sur npm" est tout à fait présomptif et suppose qu'il ne peut y avoir de bénéfice lorsque la vérité est, vous n'avez tout simplement pas encore vu. Donc, je dois être en désaccord avec cette déclaration, simplement fondée uniquement sur le principe.

Dans les premiers jours, le npm (et le dossier node_modules généralement associé) était une isolation solide des outils de construction contre le dossier des composants de bower qui contenait le code effectivement incorporé à l'application elle-même. Cela a une énorme valeur organisationnelle.

Pourquoi devrais-je consolider mes outils de construction dans ma application et vérifier cela dans le dépôt? Devrais-je vérifier Visual Studio et MSBuild aussi? Nous avons besoin d'une séparation propre pour plus de clarté. Donc, si en effet, la tendance est de ne faire que npm, alors je vais chercher un moyen d'installer des modules npm d'application dans une structure complètement distincte des modules npm environnementaux. Si je parviens à autre chose que npm pour un outil de construction (je veux dire, hey, le monde JS est volatile, les gens), alors je vais vouloir la portabilité que la séparation offre. Si tout débarque dans node_modules, je devrais commencer à ajouter des lignes .gitignore pour chaque dossier d'outil de construction.

Aller strictement npm risque de sacrifier l'organisation pour la réduction d'outils. Sans parler des milliers de composants Bower utilisés qui ne seront jamais portés à npm, ce qui vous obligera à l'utiliser de toute façon. Il suppose également que node.js est la fin. Nous n'aurons jamais d'autre chose. Comme je l'ai dit, assez présomptif. Je préfère la séparation, tout comme une politique de préparation.

Maintenant en bref

NPM signifie "Node Package Manager" , donc, alors que les modules NPM peuvent être utilisés pour un certain nombre d'utilisations, la plupart sont destinées à fonctionner dans l'écosystème Node.js. Les modules NPM peuvent inclure une spécification de fichier "principale" qui vous permet d'exporter un objet JavaScript en l'assignant comme "module.exports". Ce module peut ensuite être "importé" dans un autre module ou fichier en utilisant require ("module name"). Les modules NPM se trouveront dans la mesure où ils se situent à l'emplacement correct en fonction des conventions de dénomination NPM, ce qui se fait mieux en installant avec la commande "NPM INSTALL" . En raison de cette conception modulaire, les modules NPM ont besoin de toutes les dépendances requises pour fonctionner. Par conséquent, lorsque vous installez un module NPM, vous installez également tout le code dépendant. Cela peut souvent être des milliers de fichiers individuels. Que vous utilisiez Node.js ou Browserify, vous aurez besoin de tout ce code pour exécuter ce module "principal". Node.js charge tous ces fichiers du système de fichiers et Browserify les regroupe en un ou plusieurs fichiers à charger dans votre navigateur. Lorsque les paquetages NPM sont déployés dans un dépôt, le contenu est stocké dans le dépôt. Cela permet de contrôler facilement ce qui est déployé avec le paquet et ce contenu peut être construit à partir du code source puis supprimé puisque le paquet publié est stocké dans le dépôt.

Les modules Bower peuvent également spécifier un ou plusieurs fichiers "Main", mais ceux-ci n'ont aucun but technique. Contrairement à NPM, Bower n'est pas lié à un écosystème spécifique. Ainsi, lorsque Bootstrap spécifie "moins / bootstrap.less" comme l'un de ses fichiers principaux, vous devez savoir que vous devrez utiliser ceci comme un point d'entrée pour le traitement LESS pour que cela ait une signification. Comment (ou si) vous traitez ce fichier LESS correspond à vous. Très probablement, ce que vous voulez vraiment, ce sont les fichiers CSS pré-traités dans le dossier "dist / css" et vous souhaitez obtenir l'autre contenu tel que les polices et vous souhaitez que ce contenu se trouve dans la structure de fichier correcte à utiliser avec le CSS. C'est à vous (généralement en lisant la documentation pour le paquet) pour déterminer comment utiliser ce contenu (généralement avec une balise HTML dans une application Web). De manière similaire à NPM, Bower vous permet également de spécifier les dépendances qui peuvent être installées automatiquement à l'aide de "BOWER INSTALL" . Cependant, étant donné que les modules Bower sont généralement destinés à être utilisés pour le client (c.-à-d. Inclure simplement une étiquette pour utiliser le contenu), le nombre de dépendances est généralement plus petit et, dans certains cas, même les dépendances «douces» signifient qu'elles ne sont pas installées Automatiquement, mais si vous souhaitez utiliser une certaine fonctionnalité, vous pouvez les installer et les utiliser. L'utilisation de dépendances n'est pas automatique puisque vous devez généralement les ajouter à votre HTML en plaçant une étiquette avant la balise pour le module qui dépend de celles-ci. Les paquetages Bower ne sont PAS stockés dans le dépôt. Bower suppose que le contenu du package se trouve dans un dépôt GIT. Par conséquent, vous ne pouvez pas simplement créer le contenu du package, puis le supprimer après le déploiement. Vous devez stocker le contenu emballé dans le dépôt GIT.

Je suppose que l'intention est de déterminer si un type de module est «meilleur» que l'autre. En d'autres termes, vous devriez créer des modules NPM ou Bower et, si les deux sont disponibles, que vous devriez utiliser. Je pense que les deux réponses sont les mêmes. Si vous souhaitez maximiser l'adoption de votre module et qu'il fonctionnera sans avoir besoin de l'écosystème Node.js, vous devriez publier comme les deux (et également envisager tout autre type de dépôt que vous pensez que cela profiterait à votre communauté d'utilisateurs). Si c'est le cas pour un référentiel privé et que vous savez que tout le monde de l'équipe utilise NPM et non Bower, l'ajout d'un référentiel Bower car il est «destiné au client» n'a tout simplement pas de sens. S'il s'agit d'un dépôt public, pourquoi ne pas déployer les deux. Quant à savoir si vous utilisez la version Bower ou NPM d'un module disponible dans les deux, cela dépend de votre écosystème et de vos préférences. Si vous utilisez Node.js (ou Browserify), utilisez la version NPM. Si vous n'utilisez rien de cet écosystème (ce qui est très peu probable ces jours-ci), vous pouvez utiliser la version Bower. Une autre considération clé est le stockage du paquet. Si vous ne souhaitez pas conserver le contenu du package dans un dépôt GIT et que vous souhaitez seulement conserver le code source dans GIT, je vous recommande NPM.