Serialport Spring Update
When Node v0.12 was end of lifed we were able to drop a lot of the legacy code behind. It allowed me to rewrite the streams layer with streams 3. We were always compatible with streams 2 but it was a custom stream implementation. It also prompted me to split out the bindings layer and make a promise based api for lower level operations. This shook out a lot of bugs and made the code, and testing a lot easier. (And since then bindings are being used on their own!)
Today we say goodbye to Node 6. It’s reached it’s end of life and is no longer supported. This means we can now take advantage of newer features brought to us in Node 8. This includes speed and stability, some great language features, and most notably for serialport, N-API.
N-API is an ABI compatibility layer binary modules for NodeJS. This means an @serialport/bindings build for NodeJS 8 will work on 10, 12 and hopefully into the future. Right now serialport builds 30 versions of our binary bindings. I’ll be frank. It’s slow, flaky and it sucks. On my other projects the CI finishes before I can check github, but on serialport it takes about 40 minutes. Our test suite takes less than 10s. With N-API we can drop the number of builds to 6 (64 and 32 bit builds for Windows, Darwin and Linux). But it’s not just good for developing serialport, it’s good for everyone who uses it. In theory, electron will “just work”, and we can easily bundle the 6 builds in the npm package itself removing the need for downloading anything during install.
I had a call with the N-API working group yesterday where they guided my hand a bit. The biggest takeaway is that I can’t use node’s libuv, as while it might be ABI stable (not a guarantee?) node isn’t guaranteed to use the save version of libuv in the future.
The steps as I see it;
- We can consider node-addon-api vs the c function calls.
- We can replace all use of uv_work_t with napi_async_work
- We have to rewrite serialport not use use uv_poll_t on Darwin and Linux
- We can keep prebuild which we use for publishing and downloading the binaries is already N-API aware, so we need to tell it we are now N-API compatible.
- From there we can look into bundling the binaries on publish (harder than it sounds).
When all binary packages are using N-API users will have a lot less trouble using them. I’m excited for this future.
Other things I’m thinking about:
- My two failed typescript ports (changing everything at once is hard)
- Changes to the api that bring a better cross platform experience but are breaking changes
- A build step that works with lerna
- async iterator interface
- new bindings interface similar to web-serial