Can I install a NPM package from javascript runnin

2019-01-08 04:37发布

Can I install a NPM package from a javascript file running in Node.js? For example, I'd like to have a script, let's call it "script.js" that somehow (...using NPM or not...) install a package usually available through NPM. In this example, I'd like to install "FFI". (npm install ffi)

8条回答
Melony?
2楼-- · 2019-01-08 05:01

it can actually be a bit easy

var exec = require('child_process').exec;
child = exec('npm install ffi').stderr.pipe(process.stderr);
查看更多
倾城 Initia
3楼-- · 2019-01-08 05:11

I had a heck of a time trying to get the first example to work inside a project directory, posting here in case anyone else finds this. As far as I can tell, NPM still works fine loaded directly, but because it assumes CLI, we have to repeat ourselves a little setting it up:

// 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);
    });
});
查看更多
beautiful°
4楼-- · 2019-01-08 05:13

I'm the author of a module that allow to do exactly what you have in mind. See live-plugin-manager.

You can install and run virtually any package from NPM, Github or from a folder.

Here an example:

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();

In the above code I install moment package at runtime, load and execute it. At the end I uninstall it.

Internally I don't run npm cli but actually download packages and run inside a node VM sandbox.

查看更多
趁早两清
5楼-- · 2019-01-08 05:17

yes. you can use child_process to execute a system command

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);
     }
 });
查看更多
够拽才男人
6楼-- · 2019-01-08 05:18

if you want to have output as well you can use:

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

this way you can watch the installation like you do it on hand and avoid bad surprises (buffer full, etc)

查看更多
Juvenile、少年°
7楼-- · 2019-01-08 05:20

pacote is the package that npm uses to fetch package metadata and tarballs. It has a stable, public API.

查看更多
登录 后发表回答