Utilizzo di npm per installare o aggiornare i pacchetti richiesti proprio come bundler per rubygems


88

Adoro Bundler , è fantastico nella gestione delle dipendenze. Adoro npm , installare i pacchetti del nodo è facile! Ho un'app nodejs e mi piacerebbe essere in grado di specificare le dipendenze delle mie app e installarle / aggiornarle facilmente ovunque io distribuisca la mia app. Questa non è una libreria che sto rilasciando, è un'app web a tutti gli effetti.

Sono a conoscenza del npm bundlecomando, ma sembra semplicemente sovrascrivere la directory in cui sono installati i pacchetti.

Sono abituato a usare il bundler in questo modo:

# Gemfile
gem "rails", "3.0.3"

Installa rails v3.0.3 e qualsiasi altra gemma richiesta sulla macchina host solo se non esiste già

> bundle install

Come posso ottenere qualcosa di simile con npm?


la mia risposta non è quello che volevi sapere?
Alfred

Risposte:


147

A partire da npm 1.0 (che ora è quello che ottieni di default se segui i passaggi nel file README), "bundle" non è più una cosa segregata - è solo "come funziona".

Così:

  1. Metti un package.jsonfile nella radice del tuo progetto
  2. Elenca i tuoi dipendenti in quel file

    { "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" : { "express" : "1.0.0" } }
  3. npm install Dato che lo chiami senza argomenti e non in modalità globale, installerà solo tutti i tuoi deps localmente.

  4. require("express") e sii felice.

2
Durante la produzione, consiglio vivamente di cambiare la your_app/node_modulesdirectory locale in un collegamento simbolico al di fuori della directory dell'app. Non si desidera dover scaricare, creare e installare ogni dipendenza ogni volta che si distribuisce.
Daniel Beardsley,

Ok. cosa succede se dimentico di aggiornare il mio package.json? C'è un modo per forzare NPM a cercare non package.json ma pacchetti che sto usando nel mio codice?
Pono

4
Questo non è del tutto corretto. NPM installerà tutte le dipendenze per quanto sopra my-projectin ./node_modules/my-project/node_modules. Non sono sicuro che esista un modo conveniente per installare tutte le dipendenze in ./node_modules Qualcuno?
Daniel Beardsley

@DanielBeardsley Non credo sia così che funziona npm. Se vedi quel comportamento e puoi riprodurlo, pubblica un problema sulla pagina gitHub di npm.
isaacs

2
D'accordo con @DanielBeardsley. Soffro di quel comportamento anche con npm 1.1.70
graffic

10

Modifica: si applica solo alle versioni npm <1.0


Era abbastanza difficile capirlo, ma NPM lo rende possibile .

Hai bisogno di tre componenti

  1. Una sottodirectory nel tuo repository (cioè deps/)
  2. Un package.jsonfile nella directory sopra che elenca le dipendenze
  3. Un index.jsfile nella directory sopra che richiede le tue dipendenze

Esempio

Immagina che express sia la tua unica dipendenza

deps / package.json

nota: incrementa la versione # ogni volta che modifichi le dipendenze

{
  "name": "myapp_dependencies",
  "version": "0.0.1",
  "engines": {
    "node": "0.4.1"
  },
  "dependencies":{
    "express": "2.0.0beta2"
  }
}

deps / index.js

export.modules = {
  express: require('express')
  //add more
}

Ora dovresti essere in grado di installare le tue dipendenze usando npm. Potresti persino rendere questa parte del tuo processo di distribuzione

cd deps
npm install

Quindi all'interno del codice della tua app puoi accedere alla tua versione specifica di express in questo modo:

var express = require('myapp_dependencies').express;

Grazie, questo è il metodo migliore che ho visto finora. Tuttavia, il file require('express')in deps / index.js non importerebbe semplicemente l'ultima versione Express e non necessariamente quella che abbiamo installato? Sono un noob di nodeJS quindi per favore abbi pazienza.
adamJLev

No, questa è la magia di npm install, aggiunge collegamenti simbolici all'interno della directory del pacchetto installato alle versioni corrette dei pacchetti dipendenti. Quando è richiesto il pacchetto delle dipendenze, require('express')controlla prima la directory locale e trova il collegamento simbolico alla versione corretta di express.
Daniel Beardsley,

5

Dovresti leggere questi due articoli dal blog Isaacs (autore npm). Penso che siano davvero bravi e credo di dirti come raggiungere il tuo obiettivo:

  1. http://blog.izs.me/post/1675072029/10-cool-things-you-probably-didnt-realize-npm-could-do
  2. http://foohack.com/2010/08/intro-to-npm/

Credo che il collegamento # 1 (punto # 11) spieghi questo:

11: raggruppa tutte le tue dipendenze nel pacchetto stesso

Quando usi il comando npm bundle, npm inserirà tutte le tue dipendenze nella cartella node_modules nel tuo pacchetto. Ma non finisce qui.

Se vuoi dipendere da qualcosa che non è nel registro, puoi farlo. Basta fare questo:

npm bundle install http://github.com/whoever/wwhat/tarball/master Questo installerà il contenuto di quel tarball nel bundle, quindi puoi elencarlo come una dipendenza e non proverà a installarlo quando il tuo pacchetto viene installato.

Questo è utile anche se hai il tuo fork di qualcosa e preferisci non cambiare il nome.

In effetti, puoi eseguire quasi tutti i comandi npm nel bundle. Per vedere cosa c'è dentro, puoi fare npm bundle ls. Per rimuovere qualcosa, fai cosa npm bundle rm. E, naturalmente, puoi installare più versioni e attivare quella che desideri.


Questo è utile, anche se non era quello che stavo cercando. Forse ho bisogno di aggiungere chiarimenti. Sto cercando un modo per installare o aggiornare automaticamente (sul computer di destinazione) i pacchetti NPM da cui dipende la mia app ogni volta che la distribuisco. Sembra che npm bundlesia usato per raccogliere tutte le tue dipendenze in una directory specifica diversa da quella predefinita. Probabilmente troverò la mia soluzione che funziona in modo simile a bundle install( bundlerper ruby)
Daniel Beardsley

1
Solo una nota, dalla npmversione 1.0+, npm bundleè stata rimossa. Invece, usa semplicemente il npm installcomando senza il nome del pacchetto, leggerà il pacchetto.json e tirerà giù i pacchetti richiesti.
Arthur Maltson,

2

A partire dalla versione 1.1.2 di Npm, c'è un nuovo comando npm shrinkwrapche crea un npm-shrinkwrapped.jsonfile, analogo a Gemfile.lock. È importante crearne uno, per prevenire la decomposizione del software (vedere la logica di Bundler ). Soprattutto perché Nodejs ha una comunità in rapida evoluzione.

Mentre bundle installcrea Gemfile.lockautomaticamente un , npm installnon lo creerà npm-shrinkwrapped.json(ma lo userà quando esiste). Quindi devi ricordarti di usare npm shrinkwrap.

Leggi una guida completa su http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/


2

Mi sembra che la soluzione più semplice sia usare un package.jsonfile con il privateflag (aggiunto a npm solo il mese scorso) impostato su true. In questo modo, puoi eseguire npm installo npm bundleacquisire le dipendenze del tuo progetto, ma impedisci a chiunque di pubblicare accidentalmente il tuo progetto non pubblico.

Ecco un esempio package.json:

{
"name": "yourProject"
,"version": "1.0.0"
,"dependencies": { "express" : ">=2.1.0" }
,"private": true
}

L'esecuzione npm installverrà installata expresssul sistema locale se non esiste già; l'esecuzione npm publishdà un errore a causa del "private": true.

Tu e il tuo team potete utilizzare internamente il tag della versione per tenere traccia dei cambiamenti di dipendenza nel tempo: ogni volta che modificate una dipendenza, modificate la versione. Per vedere quale versione hai installato, usa npm ls installed.


Penso che non dovresti citare truee che funziona solo perché le stringhe sono valori veritieri (cioè !!"false" === true).
Camilo Martin

1

Pubblica anche la tua app con npmed elenca le sue dipendenze nel tuo file package.json.

Quando qualcuno usa npmper installare il tuo pacchetto, npmsi occuperà di risolvere le sue dipendenze.

Specifiche dei pacchetti: http://wiki.commonjs.org/wiki/Packages/1.0


Sì, ma questa è un'app Web non opensource. Se hai un'idea che non implica la pubblicazione dell'app, modifica la tua risposta o creane un'altra.
Daniel Beardsley

1
Quindi pubblica un pacchetto come "myapp-dependencies" che i tuoi utenti possono utilizzare npmper installare prima di installare la tua app. Non penso che ci sia nessun altro gemequivalente per node.js.
Dan Grossman
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.