以编程方式在节点REPL中使用npm

时间:2013-12-28 17:14:08

标签: node.js npm read-eval-print-loop

我正在尝试以编程方式使用npm模块来安装模块。将以下代码放在file.js中:

var npm = require('npm');

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

工作正常:

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

但是,在节点解释器中运行相同的代码会导致以下错误消息:

$ 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)

两种替代方案都安装了模块。当我在REPL中运行npm.commands.install时,是否必须设置任何特殊变量?

编辑:npm(1.3.22),节点(v0.10.24)

1 个答案:

答案 0 :(得分:2)

REPL上未设置

require.main。如果从Node.js脚本中查看它,它看起来像这样:

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

我猜npm使用filename属性(可能还有其他)来解析路径等。你可以通过设置所有正确的属性在REPL会话期间伪造它;您还可以查看npm CLI source,了解如何设置和/或使用此数据。