Update Appmetrics to run on Node 12

June 18, 2019 devadvin

I recently upgraded a Node.js-addon written in C++ to run on Node.js 12. I started with little understanding of C++ or how to develop Node.js-addons, so I’m sharing what I learned to make the process easier for others faced with similar challenges.

Prior to my upgrade, trying to compile V4 of Node Application Metrics (Appmetrics) on Node.js 12 showed lots of compilation errors. The errors occurred because Node.js 12 runs on a higher version (7.4) of Google’s V8 engine, which has deprecated several functions. Although Google V8 list their deprecations, they do not explain how to upgrade your deprecated code!

In this blog post, I share with you the steps I took to get my code to run error-free and how you can get your own C++ Node.js-addons running on Node.js 12.

To see a summary of the code changes directly, view the GitHub pull request (but see the Caveat below)

Learning by example

I didn’t have a lengthy background working with Appmetrics, C++, or Node.js-addons, so I learned by trying other people’s examples and figuring out what worked and why.

To start with, I updated the syntax of my native C++ code, and got Appmetrics running on Node.js 12. However, now my C++ no longer ran on Node.js 8, since my fixes used syntax that had been introduced after Node.js 8. To get around this, I could have used pre-compiler if-else blocks to run the correct code for Node.js versions 8, 10, and 12 respectively, but that would have been clunky and likely need extending to run on future versions of Node.js.

NAN to the rescue

Then I found Native Abstractions for Node.js (NAN). NAN’s API stays the same across most major versions of Node.js, no matter which version of Google’s V8 engine is running. So, I converted many native C++ types and functions to NAN types and functions, effectively delegating to NAN the job of maintaining compatibility across major versions of Node.js.

In addition to NAN, there is a solution called N-API, which also aims to provide a single API that remains consistent across most major version of Node.js. I used NAN instead of N-API because Google V8’s API resembles NAN much more closely than N-API. I had to get Appmetrics running on Node 12 quickly, so I implemented the easier fix first. By all means check out N-API too.

Conclusion

After a good deal of Googling, experimenting and talking with colleagues, I got Appmetrics to compile on Node.js versions 8, 10, and 12 by converting some native C++ syntax to NAN types and functions. Much of our code is still in native C++, parts of which will probably be deprecated in future versions of Node.js. To get one step ahead of future deprecations, we should resolve deprecation warnings before they become errors – using NAN or N-API.

Caveat

If you view my code changes in this pull request, you’ll see that I’m using Local types rather than the new MaybeLocal types introduced in version 7.4 of Google’s V8 engine (which Node.js 12 runs on).

Overusing Local types is not a best practice, but it was necessary to use them to get Appmetrics running on Node 12 as quickly as possible. However, returning MaybeLocal types would be safer.

The risk is that C++ calls that might internally call back out to user-provided JavaScript can fail. A MaybeLocal<> is a wrapper around Local<> that enforces a check whether the Local<> is empty before it can be used. This allows us to throw an exception on failure instead of abort()ing.

For more information related to this caveat, see:

Thanks to Howard Hellyer, Matt Colegate, Richard Lau, Sam Roberts, and Emily Mitchell.

Previous Article
IBM SDK for Node.js – z/OS Version 8 now available
IBM SDK for Node.js – z/OS Version 8 now available

The release brings many significant improvements to the z/OS JavaScript community including increased perfo...

Next Article
An introduction to the internals of the Model Asset eXchange
An introduction to the internals of the Model Asset eXchange

Take a look at how the Model Asset eXchange works.

×

Want our latest news? Subscribe to our blog!

Last Name
First Name
Thank you!
Error - something went wrong!