4
votes

I am trying to make executable of my node app with https://github.com/zeit/pkg npm package. I tried but not able to understand the given document completely or I'm doing something wrong.

After installing with the command 'npm install -g pkg' I have put the entry point in package.json file like:

"bin": "app.js"

I'm running this cmnd:

pkg .

After this where I'll get the executable file that I can run. I tried running the file it creates with proj_name-win on windows but it's not working. Can anybody explain me the steps to make executable and what I'm doing wrong?

3

3 Answers

2
votes

I did a couple of things.

First make sure that the required files in all of your development folders is added into the package.json file under the key name of pkg and scripts. If assets include them as well

"pkg": {
     "scripts" : [
          "src/client/websocket/packets/handlers/*.js",
          "src/client/websocket/packets/handlers/Ready.js",
          "src/client/actions/*.js",
          "src/client/actions/ActionsManager.js"
        ]
    }

Like so. If you have assets apart from script files, then add them as assets key.

Second pkg server.js --config package.json were server.js is my index file/starting file

In case of errors, were certain packages are missing or so and so, then copy the same package from the corresponding places (mostly this will be from node_modules) and paste it alongside the executable.

1
votes

Please add the below code to work with pkg :

package.json

"main": "app.js",
"scripts": {
"start": "npm start"
 },
"bin" : "$DIR\node_modules\npm\cli.js"

Then run command pkg .

Note :

1) You can also directly package app.js (in case if you dont have any other assets to add in pkg) by command :

pkg app.js

2) It will create executables in your current working directory.

3) You can also give entrypoint in "bin" :

Example :

package.json

"main": "app.js",
"scripts": {
"start": "npm start"
 },
"bin" : "./bin/my-bin.js"

bin/my-bin.js

#!/usr/bin/env node

var join = require('path').join
var childProcess = require('child_process');
var args = process.argv.slice(2);

 args.unshift(__dirname + '/../'); 

childProcess.exec('npm start', (err, stdout) => {
if (err) console.log(err);
console.log(stdout);
})

Then, in current working directory,

run

pkg .
-1
votes

I found this example the most helpful (it includes the ability in package.json to dynamically bring in scripts and assets too): https://github.com/asaf050/loopback-pkg-ready

I found these somewhat helpful too: http://thecodebarbarian.com/standalone-express-apis-binaries-with-pkg https://mrlithium.blogspot.com/2017/11/compiling-nodejs-app-into-exe-using-pkg.html

Basically, "pkg ." should work fine if your package.json is set up properly. Note that it will build all 3 os's if you don't specify "-t latest-win-x64". You can also specify node specific options when running the server (e.g. --options expose-gc). So a package might look like this: pkg -t latest-win-x64 . --options expose-gc

If you just use ".", then that should be the directory where your package.json is, and your package.json needs to have the bin and main entries, like you specified. I'm not sure why the bin is needed since it's looks the same as main. You can also specify the main file when calling pkg, like this: pkg -t latest-win-x64 ./server/server.js --options expose-gc

Again, "-t" and "--options" are optional, all you need is to call "pkg ." or "pkg ./app.js" to build the package.

Can you post the error message you receive? Rather than clicking the .exe, call if from command line to get the logs, or output to a log file. For me, the reason it was not running was due to static file and dynamic module loading, which it specified in the build and when running the .exe.