Search code examples
node.jsnpmspawn

Node.js child_process has no access to global modules


I have installed a npm packages globally in my Kubuntu 19.04

$ npm install -g cordova
/home/username/.npm-global/bin/cordova -> /home/username/.npm-global/lib/node_modules/cordova/bin/cordova
+ cordova@9.0.0
updated 1 package in 7.299s

I can access it from shell

$ cordova -v
9.0.0 (cordova-lib@9.0.1)

But I can't access it from a simple node script with spawn:

const { spawn } = require( 'child_process' );
const cmd = spawn( 'cordova', [ '-v' ] );

cmd.stdout.on( 'data', data => {
    console.log( `stdout: ${data}` );
} );

Running it results in the following:

$ node test1.js
events.js:298
      throw er; // Unhandled 'error' event
      ^

Error: spawn cordova ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:267:19)
    at onErrorNT (internal/child_process.js:467:16)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
Emitted 'error' event on ChildProcess instance at:
    at Process.ChildProcess._handle.onexit (internal/child_process.js:273:12)
    at onErrorNT (internal/child_process.js:467:16)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'spawn cordova',
  path: 'cordova',
  spawnargs: [ '-v' ]
}

But when using absolute path:

const { spawn } = require( 'child_process' );
const cmd = spawn( '/home/username/.npm-global/bin/cordova', [ '-v' ] );

cmd.stdout.on( 'data', data => {
    console.log( `stdout: ${data}` );
} );

I get the expected result:

$ node test1.js
stdout: 9.0.0 (cordova-lib@9.0.1)

My script above is just a testcase, since I have problem to add/run cordova specific stuff in vue-cli-plugin-cordova and quasar. I tracked it down, that the global path is the problem.

Update

I think I found the problem, but not sure how to solve it. When setting /bin/bash as shell, it works:

cmd = spawn('cordova', ['-v'], {
    shell: '/bin/bash'
});

Not sure, why this is needed and why the packages vue-cli-plugin-cordova and quasar don't do it.


Solution

  • Ok, after hours of research and tryouts, I have uninstalled node, installed nvm and latest node, set

    nvm use --delete-prefix v13.7.0 --silent >> /dev/null
    

    and added this to ~/.bashrc

    and now everything works