How to Use any npm Module With NativeScript
In this article, we take a look at using NativeScript in conjunction with npm to help take your web application to the next level.
Join the DZone community and get the full member experience.
Join For FreeWould you like to reinvent the wheels of a car or just drive the darn thing? Exactly.
The ginormous npm registry hosts hundreds of thousands of ready-to-go modules you can drop into your app. From left-padding to decent date handling, and from e-mail address validation to Amazon's AWS SDK. It's all available on npm waiting for you to "npm install" them.
It's also where all NativeScript plugins and even NativeScript itself are distributed.
Sounds Good, I'll Install all Those Modules!
Woah! Slow down, soldier. While NativeScript works with JavaScript (either transpiled from TypeScript or used directly) and npm modules are written in JavaScript as well, you can't simply install any module and expect it to work.
Originally npm modules were designed to work inside a dedicated runtime environment: Node. This means modules sometimes expect to be running inside the Node runtime and use built-in Node modules for instance access to the filesystem or to perform cryptographical functions.
What About Browsers? They use npm Modules, Right
Excellent question. They sure do. And this is where polyfills (or shims) come in. You may have heard of Browserify for instance - (among other things) it looks for a browser declaration in an npm module's package.json and swaps out anything in main and dependencies that's also in browser. Let me show you an example. This is the relevant part of package.json of aws-sdk:
browserify bits of AWS SDK package.json
The module author shipped browser-friendly versions of their JavaScript code with the plugin, and Browserify will simply swap the default implementation with the browser implementation when building for the browser.
Furthermore, many built-in modules that ship with Node have been polyfilled with browser versions as well, so Browserify is able to "fix" the vast majority of npm modules out there and allows them to run inside a browser.
So, let's apply what we've learned here!
A (Partial) Solution
What Browserify does for a browser, we can do for the NativeScript runtime. However, we don't want to impose a tool like Browserify or Webpack on you and your project (and we need a bit more flexibility as well), so the nativescript-nodeify plugin was made as a special purpose tool to swap out built-in Node modules from anything in your dependency tree by NativeScript compatible implementations.
Limitations
As much as it's true NativeScript is not a Node runtime, it's also true NativeScript is not a Browser. So not all browser polyfills may work inside the NativeScript runtime. And that's why we need to take it a step further than blindly swapping in browser-compatible modules. For instance, stream-http, a popular polyfill for Node's native HTTP module, uses global.location.protocol.search which is not a 'thing' in NativeScript.
That's where NativeScript-specific polyfills are needed. Like this one for randombytes, this one for xml2js, or this one for fs.
The nativescript-nodeify plugin knows which polyfills work best with NativeScript, but like the stream-http example above there will always be edge cases where a little more work is required.
How do I use the Plugin?
You can install dependencies as normal, and this plugin as well, then at build time a hook installed by this plugin will scan and modify your modules as it sees fit to make them {N}-compatible.
As an example, look what happens when you install node-uuid by running npm install node-uuid --save. This module uses Node's built-in crypto library on this line, which doesn't work in a browser nor NativeScript. So let's require the module in our app and see what happens at runtime:
node-uuid-without-nodeify.js
Crash! Sad!
Let's install the plugin by running tns plugin add nativescript-nodeify and run the exact same code again:
node-uuid-with-nodeify.js
No crash! Better still, you get that random UUID you longed for all your life!
Conclusion
If you encounter an npm module that's not immediately NativeScript compatible, add the nativescript-nodeify plugin and rebuild your app.
If there's still a problem at runtime open an issue on GitHub to see if we can figure it out together and enhance NativeScript's npm support even further!
Published at DZone with permission of Eddy Verbruggen, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
What Is Envoy Proxy?
-
Operator Overloading in Java
-
From On-Prem to SaaS
-
Essential Architecture Framework: In the World of Overengineering, Being Essential Is the Answer
Comments