如何从另一个Node.js脚本中运行Node.js脚本


74

我有一个名为的独立Node脚本compile.js。它位于小型Express应用程序的主文件夹中。

有时我会从命令行运行compile.js脚本。在其他情况下,我希望它可以由Express应用程序执行。

这两个脚本都从中加载配置数据package.jsonCompile.js目前不导出任何方法。

加载并执行此文件的最佳方法是什么?我已经看过了eval()vm.RunInNewContextrequire,但不知道什么是正确的做法。

谢谢你的帮助!!


1
您是否考虑过var exec = require('child_process')。exec; exec('node <path> /compile.js',...)?
huocp 2014年


1
为什么不简单地require()呢?
dandavis

@dandavis,“ Compile.js目前不导出任何方法。”
huocp 2014年

我实际上认为@dandavis可能需要工作,除了脚本有异步问题。也许有一个带有回调的require版本?
2014年

Answers:


61

您可以使用子进程来运行脚本,并侦听退出和错误事件,以了解进程何时完成或出错(这在某些情况下可能导致退出事件无法触发)。此方法的优点是可以使用任何异步脚本,甚至包括那些未明确设计为作为子进程运行的脚本,例如您要调用的第三方脚本。例:

var childProcess = require('child_process');

function runScript(scriptPath, callback) {

    // keep track of whether callback has been invoked to prevent multiple invocations
    var invoked = false;

    var process = childProcess.fork(scriptPath);

    // listen for errors as they may prevent the exit event from firing
    process.on('error', function (err) {
        if (invoked) return;
        invoked = true;
        callback(err);
    });

    // execute the callback once the process has finished running
    process.on('exit', function (code) {
        if (invoked) return;
        invoked = true;
        var err = code === 0 ? null : new Error('exit code ' + code);
        callback(err);
    });

}

// Now we can run a script and invoke a callback when complete, e.g.
runScript('./some-script.js', function (err) {
    if (err) throw err;
    console.log('finished running some-script.js');
});

请注意,如果在可能存在安全问题的环境中运行第三方脚本,则最好在沙盒虚拟机上下文中运行该脚本。


8
而且,如果您想向节点js脚本添加参数,请执行以下操作:var process = childProcess.fork(scriptPath,['arg1','arg2']);
泰勒·德登

2
如果您想为简单任务同步运行,还可以使用child_process.execFileSync(file[, args][, options])。看到nodejs.org/api/...
若昂·皮门特尔·费雷拉

exit即使process.exit(0)在子进程上也不会触发on。任何想法?
若奥·皮门特尔·费雷拉

14

将此行放在Node应用程序的任何位置。

require('child_process').fork('some_code.js'); //change the path depending on where the file is.

在some_code.js文件中

console.log('calling form parent process');

1
最后一个简单简短的答案!!谢谢!
AndorNémeth20年

5

分叉子进程可能很有用,请参阅http://nodejs.org/api/child_process.html

从链接的示例中:

var cp = require('child_process');

var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

现在,子进程将像...一样从示例开始:

process.on('message', function(m) {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

但是,要执行简单的任务,我认为创建一个扩展events.EventEmitter类的模块将可以... http://nodejs.org/api/events.html

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.