Posso installare un pacchetto NPM da javascript in esecuzione su Node.js?

Posso installare un pacchetto NPM da un file javascript in esecuzione in Node.js? Ad esempio, mi piacerebbe avere uno script, chiamiamolo “script.js” che in qualche modo (… usando NPM o meno …) installa un pacchetto solitamente disponibile tramite NPM. In questo esempio, mi piacerebbe installare “FFI”. (npm install ffi)

È infatti ansible utilizzare npm a livello di programmazione ed è stato delineato nelle versioni precedenti della documentazione. Da allora è stato rimosso dalla documentazione ufficiale, ma esiste ancora sul controllo del codice sorgente con la seguente dichiarazione:

Sebbene npm possa essere utilizzato a livello di programmazione, la sua API è pensata per essere utilizzata solo dalla CLI e non vengono fornite garanzie per quanto riguarda la sua idoneità per altri scopi. Se si desidera utilizzare npm per eseguire in modo affidabile alcune attività, la cosa più sicura da fare è richiamare il comando npm desiderato con argomenti appropriati.

La versione semantica di npm si riferisce alla stessa CLI, piuttosto che all’API sottostante. L’API interna non è garantita per rimanere stabile anche quando la versione di npm indica che non sono state apportate modifiche di interruzione in base al semere .

Nella documentazione originale, il seguente è l’esempio di codice fornito:

var npm = require('npm') npm.load(myConfigObject, function (er) { if (er) return handlError(er) npm.commands.install(['some', 'args'], function (er, data) { if (er) return commandFailed(er) // command succeeded, and data might have some info }) npm.registry.log.on('log', function (message) { ... }) }) 

Poiché npm esiste nella cartella node_modules , è ansible utilizzare require('npm') per caricarlo come qualsiasi altro modulo. Per installare un modulo, ti consigliamo di utilizzare npm.commands.install() .

Se hai bisogno di guardare nella fonte allora è anche su GitHub . Ecco un esempio operativo completo del codice, che equivale npm install senza alcun argomento da riga di comando:

 var npm = require('npm'); npm.load(function(err) { // handle errors // install module ffi npm.commands.install(['ffi'], function(er, data) { // log errors or data }); npm.on('log', function(message) { // log installation progress console.log(message); }); }); 

Si noti che il primo argomento della funzione di installazione è un array. Ogni elemento dell’array è un modulo che npm tenterà di installare.

È ansible trovare un utilizzo più avanzato nel file npm-cli.js sul controllo del codice sorgente.

sì. è ansible utilizzare child_process per eseguire un comando di sistema

 var exec = require('child_process').exec, child; child = exec('npm install ffi', function (error, stdout, stderr) { console.log('stdout: ' + stdout); console.log('stderr: ' + stderr); if (error !== null) { console.log('exec error: ' + error); } }); 

se vuoi avere anche l’output puoi usare:

 var child_process = require('child_process'); child_process.execSync("npm install ffi",{stdio:[0,1,2]}); 

in questo modo puoi guardare l’installazione come se fossi a portata di mano ed evitare brutte sorprese (buffer pieno, ecc.)

in realtà può essere un po ‘facile

 var exec = require('child_process').exec; child = exec('npm install ffi').stderr.pipe(process.stderr); 

Ho avuto un po ‘di tempo cercando di ottenere il primo esempio di lavorare all’interno di una directory di progetto, postando qui nel caso in cui qualcun altro lo trovi. Per quanto ne so, NPM funziona ancora bene caricato direttamente, ma poiché presuppone la CLI, dobbiamo ripeterci un po ‘di configurazione:

 // this must come before load to set your project directory var previous = process.cwd(); process.chdir(project); // this is the part missing from the example above var conf = {'bin-links': false, verbose: true, prefix: project} // this is all mostly the same var cli = require('npm'); cli.load(conf, (err) => { // handle errors if(err) { return reject(err); } // install module cli.commands.install(['ffi'], (er, data) => { process.chdir(previous); if(err) { reject(err); } // log errors or data resolve(data); }); cli.on('log', (message) => { // log installation progress console.log(message); }); }); 

Sono l’autore di un modulo che consente di fare esattamente quello che hai in mente. Vedi live-plugin-manager .

È ansible installare ed eseguire praticamente qualsiasi pacchetto da NPM, Github o da una cartella.

Ecco un esempio:

 import {PluginManager} from "live-plugin-manager"; const manager = new PluginManager(); async function run() { await manager.install("moment"); const moment = manager.require("moment"); console.log(moment().format()); await manager.uninstall("moment"); } run(); 

Nel codice sopra installo il pacchetto moment in runtime, lo carico ed eseguo. Alla fine lo disinstalla.

Internamente non npm cli ma in realtà scarica pacchetti ed npm all’interno di un nodo sandbox VM.