¿Cuál es la diferencia fundamental entre bower
y npm
? Solo quiero algo simple y llano. He visto a algunos de mis colegas usar bower
e npm
intercambiablemente en sus proyectos.
¿Cuál es la diferencia fundamental entre bower
y npm
? Solo quiero algo simple y llano. He visto a algunos de mis colegas usar bower
e npm
intercambiablemente en sus proyectos.
Respuestas:
Todos los administradores de paquetes tienen muchas desventajas. Solo tienes que elegir con qué puedes vivir.
npm comenzó administrando módulos node.js (es por eso que los paquetes entran node_modules
por defecto), pero también funciona para el front-end cuando se combina con Browserify o webpack .
Bower está creado exclusivamente para el front-end y está optimizado teniendo esto en cuenta.
npm es mucho, mucho más grande que Bower, incluido JavaScript de uso general (como country-data
para información del país o sorts
para ordenar funciones que se pueden utilizar en el front-end o el back-end).
Bower tiene una cantidad mucho menor de paquetes.
Bower incluye estilos, etc.
npm se centra en JavaScript. Los estilos se descargan por separado o son requeridos por algo como npm-sass
o sass-npm
.
La mayor diferencia es que npm tiene dependencias anidadas (pero es plana por defecto) mientras que Bower requiere un árbol de dependencias plano (pone la carga de la resolución de la dependencia en el usuario) .
Un árbol de dependencias anidado significa que sus dependencias pueden tener sus propias dependencias que pueden tener las suyas propias, y así sucesivamente. Esto permite que dos módulos requieran versiones diferentes de la misma dependencia y aún funcionen. Tenga en cuenta que desde npm v3, el árbol de dependencias quedará plano de forma predeterminada (ahorrando espacio) y solo se anidará donde sea necesario, por ejemplo, si dos dependencias necesitan su propia versión de subrayado.
Algunos proyectos usan ambos es que usan Bower para paquetes front-end y npm para herramientas de desarrollo como Yeoman, Grunt, Gulp, JSHint, CoffeeScript, etc.
Esta respuesta es una adición a la respuesta de Sindre Sorhus. La principal diferencia entre npm y Bower es la forma en que tratan las dependencias recursivas. Tenga en cuenta que se pueden usar juntos en un solo proyecto.
En las preguntas frecuentes de npm : (enlace archive.org del 6 de septiembre de 2015)
Es mucho más difícil evitar conflictos de dependencia sin anidar dependencias. Esto es fundamental para la forma en que funciona npm, y ha demostrado ser un enfoque extremadamente exitoso.
En la página de inicio de Bower :
Bower está optimizado para el front-end. Bower utiliza un árbol de dependencia plano, que requiere solo una versión para cada paquete, lo que reduce la carga de la página al mínimo.
En resumen, npm apunta a la estabilidad. Bower apunta a una carga mínima de recursos. Si extrae la estructura de dependencia, verá esto:
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
Como puede ver, instala algunas dependencias de forma recursiva. ¡La dependencia A tiene tres instancias instaladas!
Cenador:
project root
[bower_components] // default directory for dependencies
-> dependency A
-> dependency B // needs A
-> dependency C // needs B and D
-> dependency D
Aquí verá que todas las dependencias únicas están en el mismo nivel.
Entonces, ¿por qué molestarse en usar npm?
Tal vez la dependencia B requiere una versión diferente de la dependencia A que la dependencia C. npm instala ambas versiones de esta dependencia para que funcione de todos modos, pero Bower le dará un conflicto porque no le gusta la duplicación (porque cargar el mismo recurso en una página web es muy ineficiente y costoso, también puede dar algunos errores graves). Deberá elegir manualmente la versión que desea instalar. Esto puede tener el efecto de que una de las dependencias se romperá, pero eso es algo que deberá solucionar de todos modos.
Por lo tanto, el uso común es Bower para los paquetes que desea publicar en sus páginas web (por ejemplo , tiempo de ejecución , donde evita la duplicación), y use npm para otras cosas, como pruebas, construcción, optimización, verificación, etc. (por ejemplo , tiempo de desarrollo , donde la duplicación es menos preocupante).
Actualización para npm 3:
npm 3 todavía hace las cosas de manera diferente en comparación con Bower. Instalará las dependencias globalmente, pero solo para la primera versión que encuentre. Las otras versiones se instalan en el árbol (el módulo principal, luego node_modules).
Para obtener más información, sugiero leer los documentos de npm 3
npm
o una carga de recursos mínima con bower
.
TL; DR: La mayor diferencia en el uso diario no son las dependencias anidadas ... es la diferencia entre módulos y globales.
Creo que los carteles anteriores han cubierto bien algunas de las distinciones básicas. (El uso de npm de dependencias anidadas es de hecho muy útil para administrar aplicaciones grandes y complejas, aunque no creo que sea la distinción más importante).
Sin embargo, me sorprende que nadie haya explicado explícitamente una de las distinciones más fundamentales entre Bower y npm. Si lee las respuestas anteriores, verá la palabra 'módulos' utilizada a menudo en el contexto de npm. Pero se menciona casualmente, como si pudiera ser una diferencia de sintaxis.
Pero esta distinción de módulos vs. globales (o módulos vs. 'scripts') es posiblemente la diferencia más importante entre Bower y npm. El enfoque npm de poner todo en módulos requiere que cambie la forma en que escribe Javascript para el navegador, casi seguramente para mejor.
<script>
etiquetasEn la raíz, Bower se trata de cargar archivos de script simples. Independientemente de lo que contengan esos archivos de script, Bower los cargará. Lo que básicamente significa que Bower es como incluir todas sus secuencias de comandos en los viejos <script>
en <head>
su HTML.
Entonces, el mismo enfoque básico al que estás acostumbrado, pero obtienes algunas buenas comodidades de automatización:
bower install
y tener instantáneamente lo que necesita, localmente.bower.json
, también se descargarán para usted.Pero más allá de eso, Bower no cambia la forma en que escribimos JavaScript . Nada de lo que pasa dentro de los archivos cargados por Bower debe cambiar en absoluto. En particular, esto significa que los recursos proporcionados en los scripts cargados por Bower (generalmente, pero no siempre) se definirán como variables globales , disponibles desde cualquier parte del contexto de ejecución del navegador.
Todo el código en Node land (y, por lo tanto, todo el código cargado a través de npm) está estructurado como módulos (específicamente, como una implementación del formato de módulo CommonJS , o ahora, como un módulo ES6). Entonces, si usa NPM para manejar las dependencias del lado del navegador (a través de Browserify o alguna otra cosa que haga el mismo trabajo), estructurará su código de la misma manera que Node.
Las personas más inteligentes que yo han abordado la pregunta "¿Por qué módulos?", Pero aquí hay un resumen de la cápsula:
window.variable
. El único accidente que aún suele ocurrir es la asignación this.variable
, sin darse cuenta de que this
realmente está window
en el contexto actual).Para mí, el uso de módulos para código de front-end se reduce a: trabajar en un contexto mucho más estrecho que es más fácil de razonar y probar, y tener una mayor certeza sobre lo que está sucediendo.
Solo lleva unos 30 segundos aprender a usar la sintaxis del módulo CommonJS / Node. Dentro de un archivo JS dado, que va a ser un módulo, primero declara cualquier dependencia externa que desee usar, como esta:
var React = require('react');
Dentro del archivo / módulo, haces lo que normalmente harías y creas algún objeto o función que querrás exponer a usuarios externos, llamándolo tal vez myModule
.
Al final de un archivo, exporta lo que quiera compartir con el mundo, así:
module.exports = myModule;
Luego, para usar un flujo de trabajo basado en CommonJS en el navegador, usará herramientas como Browserify para capturar todos esos archivos de módulos individuales, encapsular sus contenidos en tiempo de ejecución e inyectarlos entre sí según sea necesario.
Y, dado que los módulos ES6 (que probablemente transpilarás a ES5 con Babel o similar) están ganando una gran aceptación y funcionan tanto en el navegador como en el Nodo 4.0, también debemos mencionar una buena descripción general de ellos.
Más sobre patrones para trabajar con módulos en este mazo .
EDITAR (febrero de 2017): el hilo de Facebook es un reemplazo / suplemento potencial muy importante para npm en estos días: gestión de paquetes rápida, determinista y fuera de línea que se basa en lo que npm le brinda. Vale la pena echarle un vistazo a cualquier proyecto JS, especialmente porque es muy fácil cambiarlo de entrada / salida.
EDITAR (mayo de 2019) "Bower finalmente ha quedado en desuso . Fin de la historia". (h / t: @DanDascalescu, a continuación, para un resumen resumido).
Y, mientras Yarn todavía está activo , gran parte del impulso cambió a npm una vez que adoptó algunas de las características clave de Yarn.
Bower finalmente ha quedado en desuso . Fin de la historia.
De Mattias Petter Johansson, desarrollador de JavaScript en Spotify :
En casi todos los casos, es más apropiado usar Browserify y npm sobre Bower. Es simplemente una mejor solución de empaque para aplicaciones front-end que Bower. En Spotify, usamos npm para empaquetar módulos web completos (html, css, js) y funciona muy bien.
Bower se marca a sí mismo como el administrador de paquetes para la web. Sería increíble si esto fuera cierto: un administrador de paquetes que mejorara mi vida como desarrollador front-end sería increíble. El problema es que Bower no ofrece herramientas especializadas para este propósito. No ofrece herramientas que conozco que npm no tiene, y especialmente ninguna que sea específicamente útil para desarrolladores front-end. Simplemente no hay beneficio para un desarrollador front-end para usar Bower sobre npm.
Deberíamos dejar de usar Bower y consolidarnos alrededor de npm. Afortunadamente, eso es lo que está sucediendo :
Con browserify o webpack, se vuelve súper fácil concatenar todos sus módulos en grandes archivos minificados, lo que es increíble para el rendimiento, especialmente para dispositivos móviles. No es así con Bower, que requerirá mucho más trabajo para obtener el mismo efecto.
npm también le ofrece la posibilidad de usar múltiples versiones de módulos simultáneamente. Si no ha realizado mucho desarrollo de aplicaciones, esto inicialmente puede parecerle algo malo, pero una vez que haya pasado por algunos episodios del Infierno de la dependencia, se dará cuenta de que tener la capacidad de tener múltiples versiones de un módulo es bastante maldito. Gran característica. Tenga en cuenta que npm incluye una herramienta de deduplicación muy útil que se asegura automáticamente de que solo use dos versiones de un módulo si realmente tiene que hacerlo; si dos módulos pueden usar la misma versión de un módulo, lo harán. Pero si no pueden , tienes una salida muy útil.
(Tenga en cuenta que Webpack y el paquete acumulativo se consideran ampliamente mejores que Browserify a partir de agosto de 2016).
Bower mantiene una única versión de módulos, solo trata de ayudarlo a seleccionar el correcto / mejor para usted.
NPM es mejor para módulos de nodo porque hay un sistema de módulos y usted está trabajando localmente. Bower es bueno para el navegador porque actualmente solo existe el alcance global, y desea ser muy selectivo sobre la versión con la que trabaja.
Mi equipo se mudó de Bower y migró a npm porque:
Para obtener más detalles, consulte "Por qué mi equipo usa npm en lugar de bower" .
Encontré esta útil explicación en http://ng-learn.org/2013/11/Bower-vs-npm/
Por un lado, npm se creó para instalar módulos utilizados en un entorno node.js, o herramientas de desarrollo creadas con node.js como Karma, lint, minifiers, etc. npm puede instalar módulos localmente en un proyecto (por defecto en node_modules) o globalmente para ser utilizados por múltiples proyectos. En proyectos grandes, la forma de especificar dependencias es creando un archivo llamado package.json que contiene una lista de dependencias. Npm reconoce esa lista cuando ejecuta npm install, que luego las descarga e instala por usted.
Por otro lado, Bower fue creado para administrar sus dependencias frontend. Bibliotecas como jQuery, AngularJS, subrayado, etc. Similar a npm, tiene un archivo en el que puede especificar una lista de dependencias llamada bower.json. En este caso, sus dependencias frontend se instalan ejecutando bower install, que por defecto las instala en una carpeta llamada bower_components.
Como puede ver, aunque realizan una tarea similar, están dirigidos a un conjunto muy diferente de bibliotecas.
npm dedupe
, esto está un poco desactualizado. Ver la respuesta de Mattias .
Para muchas personas que trabajan con node.js, una de las principales ventajas de bower es la gestión de dependencias que no son javascript en absoluto. Si están trabajando con lenguajes que compilan a javascript, npm puede usarse para administrar algunas de sus dependencias. sin embargo, no todas sus dependencias serán módulos node.js. Algunos de los que compilan en JavaScript pueden tener una extraña manipulación específica del lenguaje fuente que hace que pasarlos compilados a JavaScript sea una opción poco elegante cuando los usuarios esperan el código fuente.
No todo en un paquete npm debe ser JavaScript orientado al usuario, pero para los paquetes de la biblioteca npm, al menos algunos de ellos deberían serlo.