<ul dir="auto">
<li>Electron version: 1.4.15</li>
<li>Operating system: Windows 10</li>
</ul>
<p dir="auto">I have a simple nodeJS app that has a function to scrape file metadata. Since scraping metadata can be intensive I made the app run this as a child process using fork.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="const metaParser = child.fork(  fe.join(__dirname, 'parse-metadata.js'), [jsonLoad]);"><pre class="notranslate"><code class="notranslate">const metaParser = child.fork(  fe.join(__dirname, 'parse-metadata.js'), [jsonLoad]);
</code></pre></div>
<p dir="auto">When run in main.js the process is successfully created, but immediately exits. I added some logging to parse-metadata.js and found out that parse-metadata.js executed successfully and ran long enough to run the first few lines of code and then exited.</p>
<p dir="auto">How do I get electron to fork parse-metadata.js and keep it alive until the end?</p>
<ul dir="auto">
<li>Electron version: 1.4.14</li>
<li>Operating system: macOS Sierra</li>
</ul>
<h3 dir="auto">Expected behavior</h3>
<p dir="auto">When I fork a process, the process should be able to require native modules compiled for the main electron process and also used by it.</p>
<h3 dir="auto">Actual behavior</h3>
<p dir="auto">Because of ELECTRON_RUN_AS_NODE (if that's the name), the forked process thinks it's node and therefore can't find the appropriate native module binary.</p>
<p dir="auto">Example error:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/private/tmp/kk/node_modules/utp-native/node_modules/node-gyp-build/index.js:28
  throw new Error('No native build was found for runtime=' + runtime + ' abi=' + abi + ' platform=' + platform + ' arch=' + arch)
  ^

Error: No native build was found for runtime=node abi=50 platform=darwin arch=x64
    at Function.load.path (/private/tmp/kk/node_modules/utp-native/node_modules/node-gyp-build/index.js:28:9)
    at load (/private/tmp/kk/node_modules/utp-native/node_modules/node-gyp-build/index.js:13:23)
    at Object.&lt;anonymous&gt; (/private/tmp/kk/node_modules/utp-native/index.js:5:36)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)"><pre class="notranslate"><code class="notranslate">/private/tmp/kk/node_modules/utp-native/node_modules/node-gyp-build/index.js:28
  throw new Error('No native build was found for runtime=' + runtime + ' abi=' + abi + ' platform=' + platform + ' arch=' + arch)
  ^

Error: No native build was found for runtime=node abi=50 platform=darwin arch=x64
    at Function.load.path (/private/tmp/kk/node_modules/utp-native/node_modules/node-gyp-build/index.js:28:9)
    at load (/private/tmp/kk/node_modules/utp-native/node_modules/node-gyp-build/index.js:13:23)
    at Object.&lt;anonymous&gt; (/private/tmp/kk/node_modules/utp-native/index.js:5:36)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
</code></pre></div>
<h3 dir="auto">How to reproduce</h3>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// index.js

const { fork } = require('child_process')

require('utp-native')
console.log('required native dependency from main process')

const ps = fork(`${__dirname}/child.js`)"><pre class="notranslate"><span class="pl-c">// index.js</span>

<span class="pl-k">const</span> <span class="pl-kos">{</span> fork <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'child_process'</span><span class="pl-kos">)</span>

<span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'utp-native'</span><span class="pl-kos">)</span>
<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'required native dependency from main process'</span><span class="pl-kos">)</span>

<span class="pl-k">const</span> <span class="pl-s1">ps</span> <span class="pl-c1">=</span> <span class="pl-en">fork</span><span class="pl-kos">(</span><span class="pl-s">`<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">__dirname</span><span class="pl-kos">}</span></span>/child.js`</span><span class="pl-kos">)</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// child.js

require('utp-native')
console.log('required native dependency from child process')"><pre class="notranslate"><span class="pl-c">// child.js</span>

<span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'utp-native'</span><span class="pl-kos">)</span>
<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'required native dependency from child process'</span><span class="pl-kos">)</span></pre></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$ npm install utp-native
$ npm rebuild --runtime=electron --target=1.4.14 --abi=50 --disturl=https://atom.io/download/atom-shell 
$ electron index.js"><pre class="notranslate">$ npm install utp-native
$ npm rebuild --runtime=electron --target=1.4.14 --abi=50 --disturl=https://atom.io/download/atom-shell 
$ electron index.js</pre></div>
<h3 dir="auto">My temporary hack fix</h3>
<ol dir="auto">
<li>Instead of <code class="notranslate">child_process.fork</code>, use <code class="notranslate">child_process.spawn</code> with <code class="notranslate">process.execPath</code></li>
<li>Unfortunately, in bundled electron applications, <code class="notranslate">process.execPath</code> isn't electron. Therefore, we need to bundle electron in <code class="notranslate">node_modules/</code> and use the <code class="notranslate">.extraFiles</code> option in <code class="notranslate">electron-builder</code> to make sure it's available in the bundled app</li>
<li>Now we get the electron path for <code class="notranslate">.spawn</code> using this approach, which works in development and with bundled applications:</li>
</ol>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let electronPath                                                                                                                                                           
                                                                                                                                                                           
try {                         
  // bundled app                                                                                                                                             
  electronPath = require(path.join(remoteProcess.resourcesPath, '/../node_modules/electron'))                                                                              
} catch (_) {              
  // during developement                                                                                                                                                
  electronPath = require(path.join(app.getAppPath(), '/node_modules/electron'))                                                                                            
}"><pre class="notranslate"><span class="pl-k">let</span> <span class="pl-s1">electronPath</span>                                                                                                                                                           
                                                                                                                                                                           
<span class="pl-k">try</span> <span class="pl-kos">{</span>                         
  <span class="pl-c">// bundled app                                                                                                                                             </span>
  <span class="pl-s1">electronPath</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">.</span><span class="pl-en">join</span><span class="pl-kos">(</span><span class="pl-s1">remoteProcess</span><span class="pl-kos">.</span><span class="pl-c1">resourcesPath</span><span class="pl-kos">,</span> <span class="pl-s">'/../node_modules/electron'</span><span class="pl-kos">)</span><span class="pl-kos">)</span>                                                                              
<span class="pl-kos">}</span> <span class="pl-k">catch</span> <span class="pl-kos">(</span><span class="pl-s1">_</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>              
  <span class="pl-c">// during developement                                                                                                                                                </span>
  <span class="pl-s1">electronPath</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">.</span><span class="pl-en">join</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">.</span><span class="pl-en">getAppPath</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s">'/node_modules/electron'</span><span class="pl-kos">)</span><span class="pl-kos">)</span>                                                                                            
<span class="pl-kos">}</span></pre></div>
<ol start="4" dir="auto">
<li>Also this basically doubles our bundle size, as this includes one more (?) copy of electron.</li>
</ol>
<h3 dir="auto">My proposed fix in electron</h3>
<p dir="auto">Allow to unset the runtime override with an option to <code class="notranslate">child_process.fork</code>. I think <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/sindresorhus/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/sindresorhus">@sindresorhus</a> has requested this before too.</p>