4

I need to specify a different version of a dependency based on the Node engine. Something like this:

{
  "node": {
    "0.10.x": {
      "zombie": "2.5.1"
    },
    "0.12.x": {
      "zombie": "^3.5.0"
    }
  },
  "iojs": {
    "^3.0.0": {
      "zombie": "^4.0.0"
    }
  }
}

Is this either built-in or is there a module which enables this sort of thing?

1
  • That's what I was thinking but wanted to ask if anyone knew of it first. Commented Aug 26, 2015 at 20:04

1 Answer 1

2

"Yes, but..."

Not built-in, but possible.

Wise to do? ...

:)

// simplifying for the answer, only looking at node versions...

var npm = require("npm");
var semver = require("semver");

if (semver.satisfies(process.version, "0.12.x")){
    npm.load(null, function(){
        installPkg("chalk", "0.5.1");
    })
}

function installPkg(pkg, ver) {
    if(require.resolve(pkg)){
        throw Error("package already installed");
    }
    var semverPkg = pkg + "@" + ver;
    npm.commands.install([semverPkg], function (err, result) {
        if (err) console.log("error loading chalk");
    });
}

Using NPM programatically is a little frustrating because it is not well documented. Semver is super cool when somebody else has done all the work for you, but building the compares/satisfies checks is tedious work.

Also, doing it this way, you probably don't want to try to install every time so you'd now also have to do some kind of startup check to be sure you aren't slowing down your app restart time as it re-installs every package every time..

You could work around that by checking for modules. There are a few ways to handle this one, if you decide to continue down this path.

First, you can use require.resolve() in a heavy-handed way to see if a module is present. (That's what's in the example above.)

Second, you can also use npm.commands.ls which may look a little like this:

if (semver.satisfies(process.version, "0.12.x")){
    npm.load(null, function(){
        npm.commands.ls([], function(err, data,lite){
            // parse the results from ls here, and install or not, etc...
            console.log(lite);
        });
    })
}

So yeah...this isn't technically a solution to the problem because the problem is broad. (Not fishing to get you to accept, just explaining that I feel your pain and have been down a similar road, which is why I previously explored semver and npm in detail.)

The painful bits:

  • parsing with semver is "fun"
  • maintaining a manifest of modules by node version is "fun"
  • using npm programatically is "fun"

Vs:

  • maintain a few different package.json versions
  • write some "DevOps" scripts to handle env-specific installs for you (grunt-node-version?)
  • spend less time looking at source code for npm, semver, etc...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.