Dipendenze opzionali in npm?

19

Ho una domanda simile a questo , ma non esattamente lo stesso.

Vorrei che l'utente della mia app lo installasse con tutte le dipendenze necessarie per il modo in cui vorrebbe usarlo. Quindi, per esempio, se vogliono persistere su MongoDB, verranno installate solo le librerie relative a Mongo, ma se vogliono persistere su Redis, verranno installate solo le librerie relative a Redis. Non voglio farli scaricare e installare librerie che non useranno.

So che posso farlo a scopo di sviluppo con devDependencies , ma questo va oltre. Come dice la risposta nella domanda di cui sopra, questo è più strettamente correlato ai setuptools di% di Co_de di Python e ai profili di extras_require di Clojure. Qualcosa del genere in npm? Mi sento davvero come leiningen dovrebbe essere un profilo devDependencies di un modo più versatile di specificare le dipendenze.

    
posta imiric 07.05.2014 - 17:05
fonte

4 risposte

9

Il modulo di codipendenza potrebbe essere quello che stai cercando, o qualsiasi cosa che faccia qualcosa di simile a:

  • dichiara dipendenze opzionali in package.json che non sono installate automaticamente da npm install , ad esempio optionalPeerDependencies
  • una funzione require personalizzata che conosce optionalPeerDependencies e fa la cosa giusta, incluso il lancio / avviso quando non viene trovato nulla che soddisfi una classe di moduli richiesta (ad esempio né redis , né mongo , né mysql , ecc. sono installati).
  • documenta l'aspettativa che i consumatori di questo modulo installino almeno 1 dei moduli peer opzionali

Una variazione sarebbe se le funzionalità di base del modulo funzionassero senza dipendenze opzionali (ad esempio pattern di plugin), nessun errore / avviso quando non viene trovato nulla che soddisfi una dipendenza peer.

Un'altra variante sta facendo l'elenco sopra mentre si tiene conto delle dipendenze tra produzione e sviluppo, cioè un analogo per dependencies e devDependencies .

Forse combinato con un on-demand richiede in modo tale che i moduli opzionali siano richiesti pigramente, ad esempio:

exports = {
    Core : require('./core'),
    get redis(){ return require('./redis'); },
    get mongo(){ return require('./mongo'); }
}
    
risposta data 18.02.2015 - 06:13
fonte
5

Se vuoi semplici dipendenze opzionali come i plug-in, ad es. se installi foo lo eseguirai colorato ma se non installato, non avrai alcun problema e lo vedrai in grigio, quindi potresti usare optionalDependecies nel package.json :

{
  "name": "watchit",
  "version": "1.2.3",
  "optionalDependencies": {
    "foo": "^2.0.0"
  }
}

E nel codice:

try {
  var foo = require('foo')
  var fooVersion = require('foo/package.json').version
} catch (er) {
  foo = null
}
if ( notGoodFooVersion(fooVersion) ) {
  foo = null
}

// .. then later in your program ..

if (foo) {
  foo.doFooThings()
}

Estratto dalla documentazione di package.json .

    
risposta data 04.04.2018 - 18:18
fonte
1

Quello che faccio è configurare uno script di installazione nel mio package.json, all'interno di scripts , in questo modo:

"install": "node ./my-tools/my-install.js",

Verrà eseguito subito dopo il completamento di npm install . Lo uso principalmente per generare automaticamente un file .env con valori predefiniti.

Lo script my-install.js potrebbe eseguire comandi diversi, creare file, chiedere l'input dell'utente, quindi potresti dire "Vuoi Redis o Mongo?":

const exec = require('child_process').exec;
const readline = require('readline');

// Insert "Ask question script" here
// using readline core module

if ( option == 'mongo' )
  exec('npm install mongoose');

if ( option == 'redis' )
  exec('npm install redis');

Questa è una risposta molto rapida, controlla readline per leggere correttamente l'input dell'utente e processo fotografico per l'esecuzione di comandi e l'elaborazione dell'output, ecc.

Si noti inoltre che lo script di installazione potrebbe essere quello che si desidera (python, bash, ecc.)

    
risposta data 12.09.2016 - 22:22
fonte
1

npm in realtà non è stato progettato per questo, in quanto una delle parti più difficili della gestione delle dipendenze è garantire build veloci e riproducibili che siano facili e relativamente sicuri. Ma credo che ci sia un caso d'uso, e certamente c'era per me. Così ho scritto un pacchetto per fare esattamente quello che stai chiedendo.

Il mio pacchetto è install-subset e può essere installato globalmente con npm install -g install-subset

link

In primo luogo, si creano whitelist e blacklist per i sottoinsiemi di installazione con nome nel pacchetto package.json in questo modo:

"subsets": {
    "build": {
        "whitelist": [
            "babel-cli",
            "dotenv"
        ]
    },
    "test": {
        "blacklist": [
            "eslint",
            "lint-rules",
            "prettier"
        ]
    }
}

Quindi chiamalo con, ad esempio, install-subset test

Questo riscriverà temporaneamente il tuo pacchetto.json per non installare quei pacchetti nella blacklist, quindi lo ripristinerà, che a seconda dei pacchetti può far risparmiare molto tempo e larghezza di banda.

Funziona anche con il filo, è open source e i problemi / PR sono i benvenuti.

In molti casi lo uso sul nostro server ci per ridurre i tempi di costruzione e, durante il nostro ultimo progetto React Native, abbiamo portato la nostra tipica installazione di nuovi sviluppatori da 72 secondi a circa 20 secondi.

    
risposta data 21.08.2017 - 22:35
fonte

Leggi altre domande sui tag