Thursday, May 16, 2013

Compiling a nodejs projects as a single binary

Tuesday, May 14, 2013 4:27 AMCompiling a nodejs projects as a single binaryPlanet DevOpsJEDI - Just Enough Developed Infrastructure

Let's face it, if you write software it's often hard to distribute it: you have the runtime , the modules you depend on and your software itself. Sure you can package that all but packages ofter require you to have root-privileges to install.

Therefore at times it's convenient to have a single file/binary distribution. Download the executable and run it. For ruby project you can convert things into a single jar using Jruby. A good example is the logstash project: download 1 file , run it and you're in business. But you'd still require the java runtime to be installed. (thanks Apple, NOT).

This is a extra of the GO language but I was looking for a similar thing fornodejs. And the following documentation is the closest I could it get: (it works!)

Compiling plain javascript (no external modules)

Enter nexe a tool to compile nodejs projects to an executable binary.

The way it works is: - it downloads the nodejs source of your choice - it creates a single file nodejs source (using sardines ) - it monkey patches the nodejs code to include this single file in the binary (adding it to the lib/nexe.js directory)

Creating a binary is as simple as:

$ nexe -i myproject.js -o myproject.bin -r 0.10.3



Embedding a native module (in the nodejs binary)

Many of these single packaging tools, suffer from the problem of handline native modules.

nexe doesn't handle native modules (yet).

But with a little persistance and creativity, this is what I did to add the pty.jsnative module directly to the nodejs binary

$ tar -xzvf node-v0.8.21.tar.gz  $ cd node-v0.8.21    # Copy the native code in the src directory  # If there is a header file copy/adapt it too  $ cp ~/dev/terminal.js/node_modules/pty.js/src/unix/ src/    # Correct the export name of the module  # Add the node_ prefix to the node_module name  # Last line should read - NODE_MODULE(node_pty, init)    # add node_pty to src/node_extensions.h (f.e. right after node_zlib)  # NODE_EXT_LIST_ITEM(node_pty)    # Copy the pty.js file  $ cp ~/dev/pty.js/lib/pty.js lib/pty.js    # Add the pty.js to the node.gyp  # Somewhere in the library list add pty.js  # Somewhere in the source list add    # Adapt the namings/bindings in lib/pty.js  # 1) replace: var pty = require('../build/Release/pty.node');  #    with: var binding = process.binding('pty');  # 2) replace all references to pty. to binding.    $ make clean  $ ./configure  $ make    

Now you have a custom build node in out/Release/node The filesize was about 10034856 , you can further strip it and 6971192 (6.6M)

Now you need to remove the native dependency from your package.json before you nexe build it

Packaging the file

A single binary now makes it easy to to make a curl installer from it as it only requires you to download file. Remember the caveat of this.

And you can still package it up:


Rant about why it's a good or bad Idea - Secure Nodejs distribution

More info on the process.binding:

Convert nodejs projects to single file/beautifier:

Cross compiling:

No comments:

Post a Comment