[Asar] Limitations on Node API: spawn a child


#1

Hello,

I’m currently developing an electron app that has, at some point, to convert an HTML file into a PDF file. For this purpose, I use the native node module html-pdf which is based on phantomjs.

It works well when the application is not packed but when it is under asar, there is an uncaught exception because html-pdf cannot spawn a child process.

The stack error

internal/child_process.js:302 Uncaught Error: spawn ENOTDIR

exports._errnoException @ util.js:890
ChildProcess.spawn @ internal/child_process.js:302
exports.spawn @ child_process.js:379
PdfExec @ /Users/graphfx/html2pdf/html2pdf.asar/node_modules/html-pdf/lib/…:87
PdfToFile @ /Users/graphfx/html2pdf/html2pdf.asar/node_modules/html-pdf/lib/…:83
convert @ index.html:35
onclick @ index.html:19

I suppose that is due to the asar Limitations on Node API but I really need to pack my app in asar due to the 260 character path length limit on Windows.

I have also tried using the option --unpack-dir 'node_modules' when building the asar package but the problem persists.

Reproduce the error

git clone https://github.com/Graphfx/html2pdf
cd html2pdf
npm install
npm run asar-pack
npm run start-asar

Does someone know how solve this problem?

Thank you very much,
:evergreen_tree: Graphfx


#2

I meet similar problem when pack it with webpack,
After number of hours of digging, I found the problem is at {node_modules}/phantomjs-prebuilt/lib/phantomjs,

exports.exec = function () {
  var args = Array.prototype.slice.call(arguments)
  return spawn(exports.path, args) 
}

it spawn the path, i think you can add some log here to see if the path is correctly pointing to ‘{phantomjs lib}/phantom/bin/phantomjs’,

i solved this by put __dirname to global at the main.js (the start point of electron) and use it to compose the path.

  var location = require('./location')
  var rootpath = global && global.rootPath?(global.rootPath + "/node_modules/phantomjs-prebuilt/lib"):__dirname;
  console.log('phantomjs: ', rootpath);
  exports.path = path.resolve(rootpath, location.location)

I think __dirname may return empty after pack, I hope that can help you.