Qual è la differenza tra Bower e npm?

Qual è la differenza fondamentale tra bower e npm ? Voglio solo qualcosa di semplice e chiaro. Ho visto alcuni dei miei colleghi usare bower e npm intercambiabile nei loro progetti.

Tutti i gestori di pacchetti hanno molti aspetti negativi. Devi solo scegliere con chi puoi vivere.

Storia

npm ha iniziato a gestire i moduli node.js (ecco perché i pacchetti entrano in node_modules per impostazione predefinita), ma funziona anche per il front-end quando combinato con Browserify o WebPack.

Bower è creato esclusivamente per il front-end ed è ottimizzato per questo.

Dimensione del pronti contro termine

npm è molto, molto più grande di bower, incluso JavaScript generico (come country-data nazionali per le informazioni sui paesi o gli sorts per le funzioni di ordinamento utilizzabili sul front-end o sul back-end).

Bower ha una quantità molto minore di pacchetti.

Gestione di stili ecc

Bower include stili, ecc.

npm è incentrato su JavaScript. Gli stili possono essere scaricati separatamente o richiesti da qualcosa come npm-sass o sass-npm .

Gestione delle dipendenze

La più grande differenza è che npm fa le dipendenze nidificate (ma è piatta per impostazione predefinita) mentre Bower richiede una struttura ad albero dipendente (mette l’onere della risoluzione delle dipendenze sull’utente) .

Un albero di dipendenza nidificato significa che le dipendenze possono avere le proprie dipendenze che possono avere le proprie e così via. Ciò consente a due moduli di richiedere versioni diverse della stessa depenency e funzionano ancora. Nota poiché npm v3, l’albero delle dipendenze sarà piatto per impostazione predefinita (risparmiando spazio) e anniderà solo dove necessario, ad esempio se due dipendenze necessitano della propria versione di Underscore.

Alcuni progetti usano entrambi è che usano Bower per pacchetti front-end e npm per strumenti di sviluppo come Yeoman, Grunt, Gulp, JSHint, CoffeeScript, ecc.


risorse

  • Dipendenze annidate – Scopri perché node_modules funziona come fa

Questa risposta è un’aggiunta alla risposta di Sindre Sorhus. La principale differenza tra npm e Bower è il modo in cui trattano le dipendenze ricorsive. Si noti che possono essere utilizzati insieme in un singolo progetto.

Domande frequenti su npm : (archive.org link del 6 set 2015)

È molto più difficile evitare i conflitti di dipendenza senza dipendenze di nidificazione. Questo è fondamentale per il modo in cui funziona npm e ha dimostrato di essere un approccio di grande successo.

Sulla homepage di Bower :

Bower è ottimizzato per il front-end. Bower utilizza un albero di dipendenza piatto, che richiede solo una versione per ogni pacchetto, riducendo al minimo il carico della pagina.

In breve, npm punta alla stabilità. Bower punta a un carico di risorse minimo. Se estrai la struttura delle dipendenze, vedrai questo:

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 

Come puoi vedere installa alcune dipendenze in modo ricorsivo. Dipendenza A ha tre istanze installate!

Bower:

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

Qui vedi che tutte le dipendenze uniche sono sullo stesso livello.

Quindi, perché preoccuparsi di usare npm?

Forse la dipendenza B richiede una versione diversa della dipendenza A rispetto alla dipendenza C. npm installa entrambe le versioni di questa dipendenza in modo che funzioni ugualmente, ma Bower ti darà un conflitto perché non gli piace la duplicazione (perché caricare la stessa risorsa su una pagina web è molto inefficiente e costoso, inoltre può dare alcuni errori gravi). Dovrai selezionare manualmente la versione che desideri installare. Ciò può avere l’effetto che una delle dipendenze si interrompe, ma è qualcosa che dovrai comunque risolvere.

Quindi, l’uso comune è Bower per i pacchetti che vuoi pubblicare sulle tue pagine web (es. Runtime , dove eviti la duplicazione) e usa npm per altre cose, come test, creazione, ottimizzazione, controllo, ecc. (Ad es. Tempo di sviluppo , dove la duplicazione è meno preoccupante).

Aggiornamento per npm 3:

npm 3 fa ancora le cose in modo diverso rispetto a Bower. Installa le dipendenze a livello globale, ma solo per la prima versione che incontra. Le altre versioni sono installate nell’albero (il modulo genitore, quindi node_modules).

  • [node_modules]
    • dep A v1.0
    • dep B v1.0
      • dep A v1.0 (usa la versione di root)
    • dep C v1.0
      • dep A v2.0 (questa versione è diversa dalla versione root, quindi sarà un’installazione nidificata)

Per maggiori informazioni, suggerisco di leggere i documenti di npm 3

TL; DR: La più grande differenza nell’uso quotidiano non è una dipendenza nidificata … è la differenza tra moduli e globali.

Penso che i precedenti poster abbiano coperto bene alcune delle distinzioni di base. (L’uso di npm delle dipendenze nidificate è davvero molto utile nella gestione di applicazioni grandi e complesse, sebbene non ritenga che sia la distinzione più importante.)

Sono sorpreso, tuttavia, che nessuno abbia esplicitamente spiegato una delle distinzioni più fondamentali tra Bower e npm. Se leggi le risposte sopra, vedrai la parola “moduli” usata spesso nel contesto di npm. Ma è citato casualmente, come se potesse anche solo essere una differenza di syntax.

Ma questa distinzione tra moduli e globali (o moduli rispetto a “script”) è probabilmente la differenza più importante tra Bower e npm. L’approccio npm di mettere tutto nei moduli richiede di cambiare il modo in cui si scrive Javascript per il browser, quasi certamente per il meglio.

L’approccio Bower: risorse globali, come

Alla radice, Bower riguarda il caricamento di file di script semplici. Qualunque sia il contenuto di questi file di script, Bower li caricherà. Il che significa sostanzialmente che Bower è come includere tutti gli script in semplici s nel del tuo HTML.

Quindi, lo stesso approccio di base a cui sei abituato, ma ottieni alcune buone comodità di automazione:

  • Avevi bisogno di includere dipendenze JS nel tuo repository di progetto (durante lo sviluppo), o ottenerle tramite CDN. Ora puoi saltare il peso del download aggiuntivo nel repository e qualcuno può eseguire un'installazione rapida e avere immediatamente ciò di cui hanno bisogno, localmente.
  • Se una dipendenza di Bower specifica le proprie dipendenze nel suo bower.json , anche queste verranno scaricate.

Ma oltre a questo, Bower non cambia il modo in cui scriviamo javascript . Niente su ciò che entra nei file caricati da Bower deve cambiare. In particolare, ciò significa che le risorse fornite negli script caricati da Bower saranno (di solito, ma non sempre) ancora definite come variabili globali , disponibili da qualsiasi posizione nel contesto di esecuzione del browser.

Approccio npm: moduli JS comuni, iniezione esplicita delle dipendenze

Tutto il codice in Node Land (e quindi tutto il codice caricato via npm) è strutturato come moduli (in particolare, come implementazione del formato del modulo CommonJS , o ora, come modulo ES6). Quindi, se usi NPM per gestire le dipendenze sul browser (tramite Browserify o qualcos'altro che fa lo stesso lavoro), strutturerai il tuo codice nello stesso modo in cui lo fa Node.

Le persone più intelligenti di me hanno affrontato la questione "Perché i moduli?", Ma ecco un riassunto delle capsule:

  • Qualunque cosa all'interno di un modulo è in effetti un namespace , il che significa che non è più una variabile globale e non è ansible accedervi accidentalmente senza l'intenzione di farlo.
  • Qualunque cosa all'interno di un modulo deve essere intenzionalmente iniettata in un particolare contesto (di solito un altro modulo) per farne uso
  • Ciò significa che puoi avere più versioni della stessa dipendenza esterna (lodash, diciamo) in varie parti della tua applicazione e che non si scontreranno / entreranno in conflitto. (Questo accade sorprendentemente spesso, perché il tuo codice vuole usare una versione di una dipendenza, ma una delle tue dipendenze esterne ne specifica un'altra che va in conflitto, oppure hai due dipendenze esterne che ognuna desidera una versione diversa.)
  • Poiché tutte le dipendenze vengono inserite manualmente in un particolare modulo, è molto facile ragionare su di esse. Sai per certo : "L'unico codice che devo prendere in considerazione quando lavoro su questo è quello che ho intenzionalmente scelto di iniettare qui" .
  • Poiché anche il contenuto dei moduli iniettati è incapsulato dietro la variabile a cui viene assegnato, e tutto il codice viene eseguito in un ambito limitato, le sorprese e le collisioni diventano molto improbabili. È molto, molto meno probabile che qualcosa da una delle tue dipendenze ridefinirà accidentalmente una variabile globale senza che tu te ne accorga o che lo farai. ( Può succedere, ma di solito devi fare di tutto per farlo, con qualcosa come window.variable . L'unico incidente che ancora tende a verificarsi è assegnare this.variable , senza rendersi conto che this è effettivamente la window nell'attuale contesto.)
  • Quando vuoi testare un singolo modulo, sei in grado di sapere molto facilmente: esattamente quale altro (dipendenze) sta influenzando il codice che viene eseguito all'interno del modulo? E, poiché stai iniettando esplicitamente tutto, puoi facilmente prendere in giro queste dipendenze.

Per me, l'uso di moduli per il codice di front-end si riduce a: lavorare in un contesto molto più ristretto che è più facile ragionare e testare e avere maggiore certezza su cosa sta succedendo.


Ci vogliono solo circa 30 secondi per imparare come usare la syntax del modulo CommonJS / Node. All'interno di un determinato file JS, che sarà un modulo, dichiarare per prima cosa tutte le dipendenze esterne che si desidera utilizzare, come questa:

var React = require('react');

All'interno del file / modulo, fai qualunque cosa tu voglia normalmente, e crea qualche object o funzione che vorresti esporre agli utenti esterni, chiamandolo forse myModule .

Alla fine di un file, esporti ciò che vuoi condividere con il mondo, in questo modo:

module.exports = myModule;

Quindi, per utilizzare un stream di lavoro basato su CommonJS nel browser, utilizzerai strumenti come Browserify per catturare tutti i singoli file di modulo, incapsulare i loro contenuti in fase di runtime e iniettarli a vicenda quando necessario.

E, dal momento che i moduli ES6 (che probabilmente traspari in ES5 con Babel o simili) stanno ottenendo ampia accettazione e funzionano sia nel browser che nel Nodo 4.0, dovremmo menzionare una buona panoramica di quelli pure.

Ulteriori informazioni sui modelli per lavorare con i moduli in questo mazzo .


EDIT (febbraio 2017): il filato di Facebook è un potenziale rimpiazzo / supplemento molto importante per npm in questi giorni: rapida, deterministica, gestione dei pacchetti offline che si basa su ciò che ti dà NPM. Vale la pena dare un'occhiata a qualsiasi progetto JS, in particolare perché è così facile da scambiare dentro / fuori.

Aggiornamento 2017-ottobre

Bower è stato finalmente deprecato . Fine della storia.

Risposta precedente

Da Mattias Petter Johansson, sviluppatore JavaScript di Spotify :

In quasi tutti i casi, è più appropriato utilizzare Browserify e npm su Bower. È semplicemente una soluzione di packaging migliore per le app di front-end rispetto a Bower. A Spotify usiamo npm per impacchettare interi moduli web (html, css, js) e funziona molto bene.

Bower si autodefinisce come gestore di pacchetti per il web. Sarebbe fantastico se fosse vero – un gestore di pacchetti che mi ha reso la vita migliore come sviluppatore front-end sarebbe fantastico. Il problema è che Bower non offre strumenti specifici per lo scopo. Non offre strumenti che io sappia che npm no, e specialmente nessuno che sia specificamente utile per gli sviluppatori front-end. Non c’è semplicemente alcun vantaggio per uno sviluppatore front-end di utilizzare Bower su npm.

Dovremmo smettere di usare bower e consolidarci attorno a npm. Per fortuna, questo è ciò che sta accadendo :

Conteggio dei moduli - bower vs. npm

Con browserify o webpack, diventa estremamente facile concatenare tutti i tuoi moduli in file minifigurati, il che è fantastico per le prestazioni, specialmente per i dispositivi mobili. Non così con Bower, che richiederà molto più lavoro per ottenere lo stesso effetto.

npm offre anche la possibilità di utilizzare più versioni di moduli contemporaneamente. Se non hai fatto molto sviluppo di applicazioni, questo potrebbe inizialmente sembrarti una brutta cosa, ma una volta che hai attraversato alcuni periodi infernali di dipendenza ti renderai conto che avere la possibilità di avere più versioni di un modulo è un vero e proprio dannato grande funzionalità. Notare che npm include uno strumento di deduplicazione molto utile che si assicura automaticamente che si utilizzino solo due versioni di un modulo, se proprio si deve : se due moduli possono entrambi usare la stessa versione di un modulo, lo faranno. Ma se non ci riescono , hai una mano molto utile.

(Si noti che Webpack e rollup sono ampiamente considerati migliori di Browserify ad agosto 2016.)

Bower mantiene una singola versione di moduli, cerca solo di aiutarti a selezionare quello corretto / migliore per te.

Gestione delle dipendenze Javascript: npm vs bower vs volo?

NPM è migliore per i moduli di nodo perché c’è un sistema di moduli e stai lavorando localmente. Bower fa bene al browser perché attualmente c’è solo l’ambito globale e si vuole essere molto selettivi sulla versione con cui si lavora.

La mia squadra si è trasferita da Bower e ha migrato su npm perché:

  • L’uso programmatico era doloroso
  • L’interfaccia di Bower continuava a cambiare
  • Alcune funzionalità, come l’url stenografia, sono completamente infranti
  • Usare sia Bower che npm nello stesso progetto è doloroso
  • Mantenere il campo della versione di bower.json in sincronia con i tag git è doloroso
  • Controllo del codice sorgente! = Gestione dei pacchetti
  • Il supporto di CommonJS non è semplice

Per maggiori dettagli, vedi “Perché il mio team usa npm invece di bower” .

Ho trovato questa utile spiegazione da http://ng-learn.org/2013/11/Bower-vs-npm/

Da un lato npm è stato creato per installare i moduli utilizzati in un ambiente node.js, o strumenti di sviluppo creati usando node.js come Karma, Lint, minifiers e così via. npm può installare moduli localmente in un progetto (per impostazione predefinita in node_modules) o globalmente per essere utilizzati da più progetti. Nei progetti di grandi dimensioni, il modo per specificare le dipendenze consiste nel creare un file chiamato package.json che contiene un elenco di dipendenze. Tale elenco viene riconosciuto da npm quando si esegue l’installazione di npm, che quindi viene scaricato e installato per l’utente.

D’altra parte è stato creato bower per gestire le dipendenze frontend. Librerie come jQuery, AngularJS, underscore, ecc. Simile a npm ha un file in cui è ansible specificare un elenco di dipendenze chiamato bower.json. In questo caso, le dipendenze frontend vengono installate eseguendo bower install che, per impostazione predefinita, le installa in una cartella denominata bower_components.

Come puoi vedere, sebbene eseguano un’attività simile, sono mirati a un insieme di librerie molto diverso.

Per molte persone che lavorano con node.js, il vantaggio principale di bower è la gestione delle dipendenze che non sono affatto javascript. Se stanno lavorando con le lingue che compilano in javascript, npm può essere utilizzato per gestire alcune delle loro dipendenze. tuttavia, non tutte le loro dipendenze saranno moduli node.js. Alcuni di quelli che compilano in javascript possono avere strane mangling specifiche del linguaggio sorgente che rendono il loro passaggio compilato in javascript un’opzione inelegante quando gli utenti si aspettano codice sorgente.

Non tutto in un pacchetto npm deve essere javascript rivolto all’utente, ma per i pacchetti di librerie npm, almeno parte di esso dovrebbe essere.

Bower e Npm sono gestori di pacchetti per javascript.

pergolato

Bower è stato creato esclusivamente per lo sviluppo front-end. Usa un albero delle dipendenze piatto, che richiede solo una versione per ogni pacchetto, riducendo il carico della pagina. Mira principalmente a un carico di risorse minimo. Ha meno contributori e quindi il processo di sviluppo è lento.

Bower ha un file di configurazione chiamato bower.json. In questo file possiamo mantenere la configurazione di Bower come le dipendenze di cui abbiamo bisogno e dettagli sulla licenza, descrizione, nome e così via. Bower è adatto per pacchetti front-end come jquery, angular, reactjs, brace, knockout, backbone e così via.

npm

Npm è più comunemente usato per gestire i moduli Node.js, ma funziona anche per il front-end. Usa albero delle dipendenze annidato e albero delle dipendenze piatto. È popolare e ha molti contributori. Quindi la sua nuova versione ha sempre caratteristiche interessanti.

Npm ha un file di configurazione chiamato package.json. In questo file possiamo mantenere la configurazione per Npm come le dipendenze di cui abbiamo bisogno e dettagli sulla licenza, descrizione, nome e così via. Npm fornisce Dipendenze e DevDependencies. Le dipendenze scaricheranno e manterranno i file front-end come Jquery, Angular e così via. DevDependencies scaricherà e manterrà strumenti di sviluppo come Grunt, Gulp, JSHint e così via.

Questo ovviamente non funziona bene sul front-end, perché abbiamo bisogno di jQuery nei nostri progetti. Abbiamo bisogno di una sola copia di jQuery, ma quando un altro pacchetto richiede jQuery, scaricherà ancora un’altra copia di jQuery. Questo è uno dei principali inconvenienti di Npm.

Nota chiave: il motivo per cui molti progetti usano entrambi è che usano Bower per i pacchetti front-end e Npm per gli strumenti di sviluppo. Moltiplicando il gestore di pacchetti nel tuo progetto rendi più difficile il tuo stream di lavoro. Npm 3 accoppiato con browserify o webpack è la strada da percorrere ora.