Question

I'm trying to programatically use the npm module to install modules. Putting the following code in a file.js:

var npm = require('npm');

npm.load({ 
    save : true,
    loglevel : 'warn'
}, function (err) {
    if (err) return callback(err);
    npm.commands.install(['async']);
});

works just fine:

$ node file.js
async@0.2.9 node_modules/async
[ [ 'async@0.2.9', 'node_modules/async', '', undefined, 'async@' ] ]

However, running the same code in the node interpreter results in the following error message:

$ node
> var npm = require('npm');
undefined
> npm.load({save : true,loglevel : 'warn'},function(err){if (err) return callback(err);npm.commands.install(['async']);});
undefined
> 
/path/node_modules/npm/lib/utils/lifecycle.js:52
    env.npm_execpath = require.main.filename
                               ^
TypeError: Cannot read property 'filename' of undefined
    at /path/node_modules/npm/lib/utils/lifecycle.js:52:36
    at /path/node_modules/npm/lib/utils/lifecycle.js:128:12
    at Object.oncomplete (fs.js:107:15)

Both alternatives install the module though. Do I have to set any special variable when I'm running npm.commands.install in the REPL?

EDIT: npm (1.3.22), node (v0.10.24)

Was it helpful?

Solution

require.main is not set on the REPL. If you take a look at it from a Node.js script, it looks like this:

{ id: '.',
  exports: {},
  parent: null,
  filename: '/Users/btilley/test.js',
  loaded: false,
  children: [],
  paths:
   [ '/Users/btilley/node_modules',
     '/Users/node_modules',
     '/node_modules' ] }

I'm guessing npm uses the filename attribute (and probably others) to resolve paths and the like. You could probably fake it out during a REPL session by setting all the right attributes; you might also take a look at the npm CLI source to see how sets up and/or uses this data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top