Puis-je installer un paquet NPM à partir d'un fichier javascript s'exécutant dans Node.js ? Par exemple, j'aimerais avoir un script, appelons-le "script.js" qui d'une manière ou d'une autre (...en utilisant NPM ou non...) installe un package habituellement disponible via NPM. Dans cet exemple, j'aimerais installer "FFI". (npm install ffi)
Réponses
Trop de publicités?pacote est le paquet que npm utilise pour récupérer les métadonnées des paquets et les tarballs. Il dispose d'une API publique et stable.
Une autre option, qui n'a pas été mentionnée ici, est de faire un fork et de lancer le CLI directement à partir de ./node_modules/npm/bin/npm-cli.js
Par exemple, vous voulez être en mesure d'installer des modules de nœuds en exécutant script sur une machine qui n'a pas NPM installé. Et vous VOULEZ le faire avec CLI. Dans ce cas, il suffit d'installer NPM dans votre node_modules localement tout en construisant votre programme ( npm i npm
).
Alors utilisez-le comme ceci :
// Require child_process module
const { fork } = require('child_process');
// Working directory for subprocess of installer
const cwd = './path-where-to-run-npm-command';
// CLI path FROM cwd path! Pay attention
// here - path should be FROM your cwd directory
// to your locally installed npm module
const cli = '../node_modules/npm/bin/npm-cli.js';
// NPM arguments to run with
// If your working directory already contains
// package.json file, then just install it!
const args = ['install']; // Or, i.e ['audit', 'fix']
// Run installer
const installer = fork(cli, args, {
silent: true,
cwd: cwd
});
// Monitor your installer STDOUT and STDERR
installer.stdout.on('data', (data) => {
console.log(data);
});
installer.stderr.on('data', (data) => {
console.log(data);
});
// Do something on installer exit
installer.on('exit', (code) => {
console.log(`Installer process finished with code ${code}`);
});
Ensuite, votre programme pourrait même être empaqueté dans un fichier binaire, par exemple avec PKG paquet. Dans ce cas, vous devez utiliser --ignore-scripts
option npm, parce que node-gyp nécessaire pour exécuter preinstall scripts.
Je suis l'auteur d'un module qui permet de faire exactement ce que vous avez en tête. Voir live-plugin-manager .
Vous pouvez installer et exécuter pratiquement n'importe quel paquet à partir de NPM, Github ou d'un dossier.
Voici un exemple :
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();
Dans le code ci-dessus, j'installe moment
au moment de l'exécution, le charge et l'exécute. À la fin, je le désinstalle.
En interne, je ne dirige pas npm
cli mais en réalité, ils téléchargent des paquets et s'exécutent à l'intérieur d'un sandbox VM de node.
Une excellente solution de @hexacyanide, mais il s'est avéré que NPM n'émet plus d'événement "log" (du moins à partir de la version 6.4.1). Au lieu de cela, ils s'appuient sur un module autonome https://github.com/npm/npmlog . Heureusement, il s'agit d'un singleton, ce qui nous permet d'accéder à la même instance que celle utilisée par NPM pour les journaux et de nous abonner aux événements des journaux :
const npmlog = require( "npm/node_modules/npmlog" ),
npm = require( "npm" );
npmlog.on( "log", msg => {
console.log({ msg });
});
process.on("time", milestone => {
console.log({ milestone });
});
process.on("timeEnd", milestone => {
console.log({ milestone });
});
npm.load({
loaded: false,
progress: false,
"no-audit": true
}, ( err ) => {
npm.commands.install( installDirectory, [
"cross-env@^5.2.0",
"shelljs@^0.8.2"
], ( err, data ) => {
console.log( "done" );
});
});
Comme vous pouvez le voir dans le code, NPM émet également des mesures de performance sur le fichier process
Nous pouvons donc également l'utiliser pour suivre l'évolution de la situation.
Ajoutant un peu plus à la grande réponse de tarkh . Si vous n'avez pas l'intention d'installer npm CLI explicitement et que vous installez déjà npm via le fichier package.json. Alors le fichier dans le répertoire ./node_modules/npm/bin/npm-cli.js
est le CLI qui peut être utilisé pour exécuter des commandes.
Afin de le rendre globalement disponible, exécutez la commande suivante et ajoutez le binaire au chemin.
ln -sf /usr/app/node_modules/npm/bin/npm-cli.js /usr/bin/npm
En outre, si cela peut aider quelqu'un. Voici comment vous pouvez imiter les npm install
afin d'installer tous les paquets dans le package.json.
const npm = require('npm');
const Bluebird = require('bluebird');
async installDependencies() {
await Bluebird.promisify(npm.load)({
loglevel: 'silent',
progress: false,
});
await Bluebird.promisify(npm.install)(
"/path/to/directory/where/package.json/is",
);
}
- Réponses précédentes
- Plus de réponses