node.js forever-monitor does not use child directory on linux

Problem

I am trying to run a node script that launches other scripts in a child directory ./host using forever-monitor.

On windows this works

var child = new (forever.Monitor)('host.js', {
  max: 1,
  silent: false,
  options: [],
  cwd:"./host"
});

On linux I get

/home/ec2-user/test/node_modules/forever-monitor/node_modules/broadway/node_modules/eventemitter2/lib/eventemitter2.js:283
          throw arguments[1]; // Unhandled 'error' event
                         ^
Error: Target script does not exist: host.js
    at /home/ec2-user/test/node_modules/forever-monitor/lib/forever-monitor/monitor.js:144:26
    at process._tickCallback (node.js:415:13)
    at Function.Module.runMain (module.js:499:11)
    at startup (node.js:119:16)
    at node.js:901:3

If I change the first line to var child = new (forever.Monitor)('./host/host.js', { I now get

Error: Cannot find module '/home/ec2-user/test/host/host/host.js'

if I use child = new (forever.Monitor)('/home/ec2-user/test/host/host.js', { it runs, but I would rather not hard code the directory.

I'm using: forever-monitor 1.2.3

How do I get this to work on linux?

Edit - adding examples of the above problem with changes to the names of the directories and script, maybe the /host/host.js is causing some confusion. Using /childDir/script.js instead.

The parent script is running as /home/ec2-user/test/parentScript.js

It calls the child script /home/ec2-user/test/childDir/script.js using forever-monitor.

The first example at the top works perfectly in Windows but on Linux it is ignoring the cwd option and throws Error: Target script does not exist: script.js

If I add the directory to the script call (Same thing happens using sourceDir.)

var child = new (forever.Monitor)('./childDir/script.js', {

cwd is now added to the call making it skip the directory the script is in and not finding the script.

Error: Cannot find module '/home/ec2-user/test/childDir/childDir/script.js'

So the possibilities I see are.

  1. There is a bug when running on linux that makes cwd only fire if forever-monitor detects a directory change.
  2. There is a bug when running on both linux and windows where cwd is not intended to modify the path to the script being called, but on windows #1 is not happening and it always adds to the script path.
  3. I completely mis-understanding how this is supposed to work.

I assume one of these options should work on both windows and Linux. What is the correct way to do this?

var child = new (forever.Monitor)('script.js', {
  max: 1,
  silent: false,
  options: [],
  cwd:"./childDir"
});

or (assuming cwd is not supposed to modify the script source directory)

var child = new (forever.Monitor)('script.js', {
  max: 1,
  silent: false,
  options: [],
  sourceDir:"./childDir",
  cwd:"./childDir"
});
Problem courtesy of: Diver

Solution

Set the sourceDir option instead of the cwd option and you should get the results you are trying to achieve. The cwd is used for the eventual call to child_process.spawn while the sourceDir is used for looking up where the child script is located. Keep in mind that you will want to use a combination of __dirname and path.resolve() to normalize the path.

Edit:

You run your script like so:

/home/user$ node startup.js

Which sets the cwd for the node process running startup.js as /home/user. So if you run the command above with host.js in that directory with a startup.js file looking like below:

// startup.js
var child = new (forever.Monitor)('host.js', { 
  max: 1,
  silent: false,
  options: []
});

it has a cwd of /home/user and since host.js is in that directory, all is good.

If you start it like

/home/user/some/other/path$ node /home/user/startup.js

Then your cwd for the startup.js script is /home/user/some/other/path and therefore can't find host.js in its cwd. So in this instance we have to define the sourceDir to the location of host.js as /home/user

Solution courtesy of: srquinn

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.