99

I have a standalone Node script called compile.js. It is sitting inside the main folder of a small Express app.

Sometimes I will run the compile.js script from the command line. In other scenarios, I want it to be executed by the Express app.

Both scripts load config data from the package.json. Compile.js does not export any methods at this time.

What is the best way to load up this file and execute it? I have looked at eval(), vm.RunInNewContext, and require, but not sure what is the right approach.

Thanks for any help!!

6
  • 1
    have you considered var exec = require('child_process').exec; exec('node <path>/compile.js', ...) ? Commented Mar 25, 2014 at 21:51
  • Would nodejs.org/api/process.html#process_process_execargv fit your needs? Commented Mar 25, 2014 at 21:52
  • 1
    why not simply require() it? Commented Mar 25, 2014 at 21:52
  • @dandavis, "Compile.js does not export any methods at this time." Commented Mar 25, 2014 at 21:53
  • @dandavis I actually think require might work, except that the script has something async going on. Maybe there's a version of require that has a callback? Commented Mar 25, 2014 at 21:58

3 Answers 3

85

You can use a child process to run the script, and listen for exit and error events to know when the process is completed or errors out (which in some cases may result in the exit event not firing). This method has the advantage of working with any async script, even those that are not explicitly designed to be run as a child process, such as a third party script you would like to invoke. Example:

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');
});

Note that if running third-party scripts in an environment where security issues may exist, it may be preferable to run the script in a sandboxed vm context.

Sign up to request clarification or add additional context in comments.

3 Comments

And if you want to add arguments to the node js script you're calling: var process = childProcess.fork(scriptPath, ['arg1', 'arg2']);
if you want to run synchronously for simple tasks you also have the child_process.execFileSync(file[, args][, options]). see nodejs.org/api/…
the on exit is not being triggered, even if I do process.exit(0) on child process. Any idea?
25

Put this line in anywhere of the Node application.

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

In some_code.js file

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

Comments

9

Forking a child process may be useful, see http://nodejs.org/api/child_process.html

From the example at link:

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' });

Now, the child process would go like... also from the example:

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

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

But to do simple tasks I think that creating a module that extends the events.EventEmitter class will do... http://nodejs.org/api/events.html

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.