Install programmatically a NPM package providing i

2019-01-22 09:39发布

问题:

I found how to install npm packages programmatically and the code works fine:

var npm = require("npm");
npm.load({
    loaded: false
}, function (err) {
  // catch errors
  npm.commands.install(["my", "packages", "to", "install"], function (er, data) {
    // log the error or data
  });
  npm.on("log", function (message) {
    // log the progress of the installation
    console.log(message);
  });
});

If I want to install the first version of hello-world package, how can I do this in the NodeJS side, using npm module?

I know that I can use child process, but I want to choose the npm module solution.

回答1:

NPM NodeJS API is not well documented, but checking the code helps up.

Here we find the following string:

install.usage = "npm install"
              + "\nnpm install <pkg>"
              + "\nnpm install <pkg>@<tag>"
              + "\nnpm install <pkg>@<version>"
              + "\nnpm install <pkg>@<version range>"
              + "\nnpm install <folder>"
              + "\nnpm install <tarball file>"
              + "\nnpm install <tarball url>"
              + "\nnpm install <git:// url>"
              + "\nnpm install <github username>/<github project>"
              + "\n\nCan specify one or more: npm install ./foo.tgz bar@stable /some/folder"
              + "\nIf no argument is supplied and ./npm-shrinkwrap.json is "
              + "\npresent, installs dependencies specified in the shrinkwrap."
              + "\nOtherwise, installs dependencies from ./package.json."

My question is about the version, so we can do: hello-world@0.0.1 to install 0.0.1 version of hello-world.

var npm = require("npm");
npm.load({
    loaded: false
}, function (err) {
  // catch errors
  npm.commands.install(["hello-world@0.0.1"], function (er, data) {
    // log the error or data
  });
  npm.on("log", function (message) {
    // log the progress of the installation
    console.log(message);
  });
});

I didn't test, but I am sure that we can use any format of the install.usage solutions.

I wrote a function that converts the dependencies object in an array that can be passed to the install function call.

dependencies:

{
   "hello-world": "0.0.1"
}

The function gets the path to the package.json file and returns an array of strings.

function createNpmDependenciesArray (packageFilePath) {
    var p = require(packageFilePath);
    if (!p.dependencies) return [];

    var deps = [];
    for (var mod in p.dependencies) {
        deps.push(mod + "@" + p.dependencies[mod]);
    }

    return deps;
}


回答2:

As I'm doing this kind of implem A LOT for my work I wrote a simple, yet efficient, nodeJS module to handle the process easily.

Github repository of npmi

or

npm install npmi


回答3:

I'm the author of module that allow to do 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.

To install a specific version just use:

  await manager.install("moment", "2.20.1");


回答4:

When I'm writing an app that has dependencies I use the package.json file and include it in the directory with my app. It looks maybe a bit like this.

{
     "name": "MyApp",
     "description": "My App.",
     "version": "0.0.1",
     "dependencies": {
        "express": "3.4.3",
        "socket.io": "0.9.16"
     }
}

I think you can use similar format to install with NPM from command line. With package.json you just do npm install -d (assuming the -d stands for "dependencies")

You're question is about doing it programatically. Have you tried simple adding a second argument like ("npm@version #")?

If I were doing it programmatically I might try something like this:

   var pjson = require('./package.json');

That way I can maintain version control and use the simplicity of the package.json file.

I added some more info in the comments, in case you haven't looked yet, here are the docs for npm install. https://npmjs.org/doc/cli/npm-install.html

I've been unable to dig up any other specific information on your specific case, perhaps there is no method to install by version programmatically, but that wouldn't make sense, it has to be doable.



标签: node.js npm