node.js - node - update npm




Qual è la differenza tra dipendenze, devDependencies e peerDependencies nel file npm package.json? (7)

Ad esempio, la mocha sarebbe normalmente una devdependency, poiché il test non è necessario in produzione, mentre espresso sarebbe una dipendenza.

Questa documentazione risponde molto male alla mia domanda. Non ho capito quelle spiegazioni. Qualcuno può dire in parole più semplici? Forse con esempi se è difficile scegliere parole semplici?

EDIT ha anche aggiunto peerDependencies , che è strettamente correlato e potrebbe causare confusione.


Ci sono alcuni moduli e pacchetti solo necessari per lo sviluppo, che non sono necessari nella produzione. Come lo dice nella documentation :

Se qualcuno sta pianificando di scaricare e utilizzare il modulo nel proprio programma, probabilmente non vorranno né dovranno scaricare e creare il test esterno o il framework della documentazione che si utilizza. In questo caso, è meglio elencare questi elementi aggiuntivi in ​​un hash devDependencies.


Quando provi a distribuire un pacchetto npm, devi evitare di usare le dependencies . Invece è necessario considerare di aggiungerlo in peerDependencies o rimuoverlo dalle dependencies .


Riepilogo delle importanti differenze comportamentali:

  • dependencies sono installate su entrambi:

    • npm install da una directory che contiene package.json
    • npm install $package su qualsiasi altra directory
  • devDependencies sono:

    • installato anche su npm install su una directory che contiene package.json , a meno che non si passi il flag --production (andare su risposta di Gayan Charith ).
    • non installato su npm install "$package" su qualsiasi altra directory, a meno che non gli --dev opzione --dev .
    • non sono installati in modo transitorio.
  • peerDependencies :

    • prima della 3.0: sono sempre installati se mancanti e generano un errore se più versioni incompatibili della dipendenza verrebbero utilizzate da diverse dipendenze.
    • atteso a partire dal 3.0 (non testato): dare un avvertimento se manca l' npm install , e si deve risolvere manualmente la dipendenza manualmente. Durante l'esecuzione, se manca la dipendenza, si verifica un errore (citato da @nextgentech )
  • Transitività (menzionata da Ben Hutchison ):

    • dependencies sono installate in modo transitorio: se A richiede B e B richiede C, allora C viene installato, altrimenti B non può funzionare, e nemmeno A.

    • devDependencies non sono installati in modo transitorio. Ad esempio, non abbiamo bisogno di testare B per testare A, quindi le dipendenze di testing di B possono essere tralasciate.

Opzioni correlate non discusse qui:

devDependencies

dependencies devono essere eseguite, devDependencies solo per lo sviluppo, ad esempio: unit test, CoffeeScript to JavaScript transpilation, minification, ...

Se hai intenzione di sviluppare un pacchetto, lo scarichi (ad esempio tramite git clone ), vai alla sua radice che contiene package.json ed esegui:

npm install

Dato che hai la sorgente vera e propria, è chiaro che vuoi svilupparla, quindi per impostazione predefinita sono entrambe le dependencies (dato che ovviamente devi eseguire lo sviluppo) e vengono installate anche le dipendenze di devDependency .

Se invece sei solo un utente finale che vuole solo installare un pacchetto per usarlo, lo farai da qualsiasi directory:

npm install "$package"

In questo caso, normalmente non si vogliono le dipendenze di sviluppo, quindi si ottiene solo ciò che è necessario per utilizzare il pacchetto: dependencies .

Se in questo caso vuoi davvero installare i pacchetti di sviluppo, puoi impostare l'opzione di configurazione di dev su true , possibilmente dalla riga di comando come:

npm install "$package" --dev

L'opzione è false di default poiché si tratta di un caso molto meno comune.

peerDependencies

(Testato prima del 3.0)

Fonte: https://nodejs.org/en/blog/npm/peer-dependencies/

Con dipendenze regolari, è possibile avere più versioni della dipendenza: è semplicemente installato all'interno dei node_modules della dipendenza.

Ad esempio, se dependency1 e dependency2 dipendono entrambe da dependency3 in diverse versioni, l'albero del progetto sarà simile a:

root/node_modules/
                 |
                 +- dependency1/node_modules/
                 |                          |
                 |                          +- dependency3 v1.0/
                 |
                 |
                 +- dependency2/node_modules/
                                            |
                                            +- dependency3 v2.0/

I plugin sono tuttavia pacchetti che normalmente non richiedono l'altro pacchetto, che è chiamato l' host in questo contesto. Anziché:

  • i plugin sono richiesti dall'host
  • i plugin offrono un'interfaccia standard che l'host si aspetta di trovare
  • solo l'host sarà chiamato direttamente dall'utente, quindi deve esserci una sua versione.

Ad esempio, se il dependency1 e dependency2 dipendono da dependency3 , l'albero del progetto sarà simile al seguente:

root/node_modules/
                 |
                 +- dependency1/
                 |
                 +- dependency2/
                 |
                 +- dependency3 v1.0/

Ciò accade anche se non si menziona mai dependency3 nel file package.json .

Penso che questa sia un'istanza del modello di progettazione di Inversion of Control .

Un esempio prototipico di dipendenze peer è Grunt, l'host e i suoi plugin.

Ad esempio, su un plugin Grunt come https://github.com/gruntjs/grunt-contrib-uglify , vedrai che:

  • grunt è una peerDependency
  • l'unica require('grunt') è sotto tests/ : non è effettivamente utilizzata dal programma.

Quindi, quando l'utente utilizzerà un plugin, richiederà implicitamente il plugin dal Gruntfile aggiungendo una grunt.loadNpmTasks('grunt-contrib-uglify') , ma è grunt che l'utente chiamerà direttamente.

Questo non funzionerebbe se ogni plugin richiedesse una versione Grunt diversa.

Manuale

Penso che la documentazione risponda abbastanza bene alla domanda, forse non sei abbastanza familiare con il nodo / altri gestori di pacchetti. Probabilmente lo capisco solo perché conosco un po 'di Ruby Bundler.

La linea chiave è:

Queste cose verranno installate quando si esegue il collegamento npm o l'installazione npm dalla radice di un pacchetto e possono essere gestite come qualsiasi altro parametro di configurazione di npm. Vedi npm-config (7) per ulteriori informazioni sull'argomento.

E poi sotto npm-config (7) trovare dev :

Default: false
Type: Boolean

Install dev-dependencies along with packages.

Una semplice spiegazione che mi ha reso più chiaro è:

Quando si distribuisce l'app, è necessario installare i moduli nelle dipendenze o l'app non funzionerà. I moduli in devDependencies non devono essere installati sul server di produzione poiché non si sta sviluppando su quella macchina. link


Vorrei aggiungere alla risposta la mia opinione su queste spiegazioni delle dipendenze

  • dependencies sono usate per l'uso diretto nella tua base di codice, cose che di solito finiscono nel codice di produzione, o pezzi di codice
  • devDependencies sono utilizzate per il processo di compilazione, strumenti che ti aiutano a gestire come andrà a finire il codice finale, moduli di test di terze parti, (ad esempio materiale per il webpack)

dipendenze
Dipendenze che il tuo progetto deve eseguire, come una libreria che fornisce funzioni chiamate dal tuo codice.
Sono installati in modo transitorio (se A dipende da B dipende da C, l'installazione di npm su A installerà B e C).
Esempio: lodash: il tuo progetto chiama alcune funzioni di lodash.

devDependencies
Dipendenze di cui hai bisogno solo durante lo sviluppo o il rilascio, come i compilatori che prendono il tuo codice e lo compongono in javascript, framework di test o generatori di documentazione.
Non sono installati in modo transitorio (se A dipende da B dev-dipende da C, l'installazione di npm su A installerà solo B).
Esempio: grunt: il tuo progetto usa grunt per costruirsi.

peerDependencies
Dipendenze in cui il progetto si aggancia, o modifica, nel progetto principale, di solito un plugin per qualche altra libreria o strumento. È solo inteso come un controllo, facendo in modo che il progetto genitore (il progetto che dipenderà dal tuo progetto) abbia una dipendenza dal progetto a cui ti colleghi. Quindi, se crei un plugin C che aggiunge funzionalità alla libreria B, allora qualcuno che crea un progetto A dovrà avere una dipendenza da B se ha una dipendenza da C.
Non sono installati (a meno che npm <3), vengono controllati solo per.
Esempio: grunt: il tuo progetto aggiunge funzionalità a grunt e può essere utilizzato solo su progetti che usano grunt.

Questa documentazione spiega molto bene le dipendenze dei peer: https://nodejs.org/en/blog/npm/peer-dependencies/

Inoltre, la documentazione di npm è stata migliorata nel tempo e ora offre spiegazioni migliori dei diversi tipi di dipendenza: https://github.com/npm/npm/blob/master/doc/files/package.json.md#devdependencies





npm