node.js child process doesn't work in node webkit

空扰寡人 提交于 2019-12-05 19:21:46

I am assuming your code in question is executed via the node-main entry point of node-webkit: https://github.com/rogerwang/node-webkit/wiki/Node-main

If any exception happens (there) which is not catched in your application will crash.

Sadly at the moment the breakpad feature for getting crashdumps is not working on OSX: https://github.com/rogerwang/node-webkit/issues/2518

How to prevent Node-Webkit from crashing immediately

Wrap the code in try/catches to prevent the crash and get information why the crash occurs.

try {

    the_child_process = child_process.spawn(pathToBin, args);

} catch (err) {

    global.console.log( "Error while trying to start child process: " + JSON.stringify(err) );
}

This is a general advice for a situation like you are experiencing to track down the real cause for the issue.

How to include a binary with your node-webkit app

There are a few things involved.

  1. Including the binaries inside your app.nw

    This should be self explanatory - but there is one caveat which caused me some trouble: Make sure the binary is marked as executable via chmod 755. If you are using grunt you might like grunt-chmod. Now your binaries are part of your app's package and you can execute them by knowing the absolute path.

  2. Resolve the path to the binary at runtime even when packaged. The following piece of code is my solution for selecting the right binary for the current platform assuming your tool is multi platform. Also it assumes your binaries are ordered in a certain folder structure. Alternatively select the right binary in your build process and use always the same path.

    var arch = process.arch;
    var platform = process.platform;
    // this will return the root path of your app-package at runtime
    var rootDir = process.cwd(); 
    var isWin = false;
    
    var execPath = rootDir;
    
    // some base path is appended
    execPath = path.join(execPath, 'path', 'to', 'bin');
    
    // select folder for current platform
    switch (platform) {
        case 'darwin':
            execPath = path.join(execPath, 'mac');
            break;
        case 'linux':
            execPath = path.join(execPath, 'lin');
            break;
        case 'win32':
            execPath = path.join(execPath, 'win');
            isWin = true;
            break;
        default:
            global.console.log("unsupported platform: " + platform);
            return null;
    }
    
    // select folder for current processor architecture
    switch (arch) {
        case 'ia32':
            execPath = path.join(execPath, 'x86');
            break;
        case 'x64':
            execPath = path.join(execPath, 'x64');
            break;
        default:
            global.console.log("unsupported architecture: " + arch);
            return null;
    }
    
    // add executable filename
    execPath = path.join(execPath, 'node');
    
    if (isWin) {
        execPath = execPath + ".exe";
    }
    
    global.console.log("Path to your binary: " + execPath);
    
    return execPath;
    
  3. Resolve the paths which are fed to your binary as arguments eventually. This was also a bit confusing because all paths were treated as relative to the app's package root path. My node-main file resides in a folder in my app package so I thought I should reference files relative from there, but this was not the case.

    app package root
    |--- package.json     <- node-webkit package.json
    |
    |--- client           <- here my sources for the frontend reside
    |
    |--- server           
    |----|--- node_modules  <- server runtime dependencies
    |----|--- src           <- server source code
    |----|----|--- server.js  <- this is my node server file to execute via node
    |
    |--- node-webkit      <- node webkit code and dependencies
    |----|--- bin           <- a directory with my deployed binaries
    |----|--- node-main.js  <- this is my node main file
    

To invoke a node binary with my server file the following line led to success:

    child_process.spawn(absPathToNodeBin, "server/src/server.js");

This is my experience:

var child_process = nw.require('child_process');
//exec
var exec = child_process.exec;
var ret = exec('cat *');

//spawn
var sp = child_process.spawn;
var sr = sp('cat *');
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!