Create Native NodeJS Modules Fallbacking To Emscripten Ones
This article is outdated and here for historical reasons. It was an interesting journey but you will probably find better tools to do the same thing now.
If you're a frontend developer, you probably already heard about icon fonts. If you use the Gulp build tool, you maybe already used gulp-iconfont. As its maintainer, when I heard about the WOFF2 font format, I really wanted to get it in output of my gulp plugin.
NodeJS C++ add-on: easy! 🔗
Creating a NodeJS add-on was blazing fast. The build system is incredibly well documented and works like a charm.
Typically when creating a native add-on you need to create a wrapper written in C++ that glue the library you want to use to the V8 engine. Mine is pretty simple. It indeed wraps the Google's woff2 project encoding function. This C++ function signature:
const uint8_t *data, size_t length,
uint8_t *result, size_t *result_length
becomes this NodeJS one:
output:Buffer function ttf2woff2(input:Buffer);
Once the wrapper is made, you just have to create a file named binding.gyp that allows you to specify building instruction for the various compilers. We had to struggle a bit with the MacOSX one since I couldn't test by myself.
And that's it! Your module gets compiled at
npm install. In fact, I had to test a few time and correct compilation errors progressively but it was suprisingly fast to get it up and running. For that testing matter I set up a few commands to my
But what about users whose OS can't build it? How to not let them down?
Emscripten for the win! 🔗
Once again, I made some scripts to simplify the build. Basically, it query the
binding.gyp file with miniquery for the C/C++ files to build, remove the
addon.cc one that we do not want and then set it as args to the emcc compiler.
Gracefully fail compilation 🔗
So, now we have our Emscripten build, let's fallback to him when the native NodeJS add-on compilation goes wrong. First, we must ensure that any failure won't impeach the module to install. We're basically doing this by overriding the default installation script to exit with a 0 code whatever result the compiler gives.
It works! But what about browserifying it?
In order to allow
gulp-iconfont users to preview and download the resulting fonts made with it (and to see if it was feasible :p), I made a full frontend font builder. So, I immediately tried to use my shinny new module to also output WOFF2 files.
The fact is that it doesn't work out of the box. Browserify try to add every NodeJS dependencies that appears to be useless when using the Emscripten module on the front-end side.
Chances are that Browserify allows to skip the parsing for some files. Plus a simple trick to fix the Emscripten require, I've finally been able to make the magic happen.
I'm really impressed by how a C/C++ noob like me have been able to do this in the free time of a few days. If you didn't already, you really should have a look at NodeJS native bindings!
Published at vendredi 26 juin 2015 à 17:50:23.