These past few weeks have been a bit of a challenge. No excuses here, but my main machine was out of commission for a little while. And ultimately, the state of the world certainly made an impact in general feelings of security, in spite of my privilege as a Canadian.
Nonetheless, as they say, on with the show! In the past few weeks I’ve been
doing more study and inquiry into
node-serialport and learning exactly
how they it is built. I have finally published my piece on [Node Streams],
and still continuing to contribute to the repos.
Building Native Modules
I learned a lot about the abstraction layers in
node-serialport. Starting off
'use strict'; const binding = require('bindings')('serialport.node');
The entire stack call to create a serialport in node goes something like this:
- Serialport is created and machine bindings is determined in the entry point.
- Serialport object determines bindings by file [
- Binding is set in Serialport constructor call.
- node-bindings calls machine specific C++ source code
- Every function call will use machine-targetted functions
The first question I had is what exactly is bindings? Well, it turns out that it’s a library used to port native modules more easily in Node.js, which removes the overhead of requiring your C++ files in your header.
const binding = require('./src/linux-binding')
Bindings.js shortens the string to:
const binding = require('bindings')('serialport.node')
The machine specific C++ file is determined by the
binding.gyp file which
is specified by the author of the package.
NaN (Native Abstractions for Node.js) Methods
The native code can be written exactly as one would normally write C++ code. The Node.js Addon documentation does a wonderful outlining exactly how one would go about writing a common “Hello World” program in C++ and running it as a node module.
With respects to the UNIX philosophy of using tools when possible, there have
been packages built to help aid in the process. In particular,
NaN is one
of these libraries and is recommended because it is maintained by the Node
Foundation, which helps support multiple versions of Node.js as changes are
NaN allows you to wrap around your C++ functions so that they can be used and
Node.js classes and their respective functions. Finally, it helps access V8
and libuv function calls that are version specific, so if you write your native
NaN, you do not need to worry about future implementations of Node.js.
This abstraction layer acts as a compatibility layer and handles all the versioning overhead for you. 🎉
A lot of credit is due to this resource here over at Rising Stack on building native modules with Node.js, with great provided examples.
Documentation on Backpressure
Working on a pull request to write a guide on backpressuring! It’s been a great learning experience.
Thank you @addaleax and @mcollina for all their time to help me figure out most of the backpressuring.