Getting Started: Cordova apps

Installing the Node.js for Mobile Apps Cordova plugin

$ cordova plugin add nodejs-mobile-cordova

Requirements

  • Cordova 7.x (Cordova 8.x is currently not supported)
  • iOS 11 or higher
  • Android API 21 or higher

When building an application for the Android platform, make sure you have the Android NDK installed and the environment variable ANDROID_NDK_HOME set, for example:

$ export ANDROID_NDK_HOME=/Users/username/Library/Android/sdk/ndk-bundle

Supported Platforms

  • Android (ARMv7a, x86)
  • iOS (ARM64)

Usage

This shows how to build an iOS app that exchanges text messages between the Cordova layer and the Node.js layer. For a description of the available APIs see the Cordova bridge API reference.

In macOS, using Terminal:

$ cordova create HelloCordova
$ cd HelloCordova
$ cordova platform add ios
$ cordova plugin add nodejs-mobile-cordova
$ cordova plugin add cordova-plugin-console

You can either manually create the ./www/nodejs-project/ folder, the ./www/nodejs-project/main.js file and edit ./www/js/index.js or use the provided helper script to do it automatically. The helper script copies a more extended sample compared to the one provided with the manual steps.


Set up project files using the helper script

If you choose to use the helper script, you will be asked to overwrite the existing ./www/js/index.js file:

$ ./plugins/nodejs-mobile-cordova/install/sample-project/copy-sample-project.sh
$ overwrite www/js/index.js? (y/n [n]) y

The script creates the ./www/nodejs-project/ folder and adds two files: - ./www/nodejs-project/main.js - ./www/nodejs-project/package.json

The changes in ./www/js/index.js are needed to invoke Node.js for Mobile Apps from Cordova.


Set up project files using the manual steps

If you want to set up the project manually, first create the project folder for the Node.js files:

$ mkdir www/nodejs-project

Then, with your editor of choice (we use VS Code in this example) create the main.js script file:

$ code www/nodejs-project/main.js

Add the following code to main.js and save the file:

const cordova = require('cordova-bridge');

cordova.channel.on('message', function (msg) {
  console.log('[node] received:', msg);
  cordova.channel.send('Replying to this message: ' + msg);
});

Edit the cordova script file www/js/index.js:

$ code `./www/js/index.js`

Append the following code at the end of the file:

function channelListener(msg) {
    console.log('[cordova] received:' + msg);
}

function startupCallback(err) {
    if (err) {
        console.log(err);
    } else {
        console.log ('Node.js Mobile Engine Started');
        nodejs.channel.send('Hello from Cordova!');
    }
};

function startNodeProject() {
    nodejs.channel.setListener(channelListener);
    nodejs.start('main.js', startupCallback);
    // To disable the stdout/stderr redirection to the Android logcat:
    // nodejs.start('main.js', startupCallback, { redirectOutputToLogcat: false });
};

Search for the onDeviceReady event and in the event handler add a call to startNodeProject():

  onDeviceReady: function() {
      this.receivedEvent('deviceready');
      startNodeProject();
  },

Save the changes to the www/js/index.js file to complete the manual steps of setting up the project files.


After the project files have been created, either manually or using the helper script, open the Cordova app project in Xcode:

$ open platforms/ios/HelloCordova.xcodeproj

Switch to Xcode:

  • select HelloCordova to view the project settings
  • in the General settings:
    • in the Signing section select a team to sign the app
    • in Deployment Info section select Deployment Target 11.0 or higher

Go back to Terminal to build the Cordova app

$ cordova build ios --device

Switch to Xcode:

  • select a target device for the project
  • run the project
  • enlarge the Console area and scroll to the bottom

If you created the project following the manual steps, the output will look like this:

2017-10-02 18:49:18.606100+0200 HelloCordova[2182:1463518] Node.js Mobile Engine Started
[node] received: Hello from Cordova!
2017-10-02 18:49:18.690132+0200 HelloCordova[2182:1463518] [cordova] received: Replying to this message: Hello from Cordova!

If you used the helper script, the output will look like this:

2018-02-26 09:18:21.178612+0100 HelloCordova[1089:957630] Node.js Mobile Engine started
2018-02-26 09:18:21.385605+0100 HelloCordova[1089:957630] [cordova] MESSAGE from Node: "main.js loaded"
2018-02-26 09:18:21.385760+0100 HelloCordova[1089:957630] [cordova] "STARTED" event received from Node
2018-02-26 09:18:21.385831+0100 HelloCordova[1089:957630] [cordova] "STARTED" event received from Node with a message: "main.js loaded"
[node] MESSAGE received: "Hello from Cordova!"
[node] MYEVENT received with message: "An event from Cordova"
2018-02-26 09:18:21.392035+0100 HelloCordova[1089:957630] [cordova] MESSAGE from Node: "Message received!" - In reply to: "Hello from Cordova!"

Node Modules

Node modules can be added to the project using npm. The Node modules have to be installed in the ./www/nodejs-project/ folder and a package.json file needs to be added to the folder.

If you used the helper script to install the sample project, the package.json file is already present and you can proceed adding the desired Node modules.

If you don't know how to create the package.json file, just copy the sample one from ./plugins/nodejs-mobile-cordova/install/sample-project/www/nodejs-project/package.json. Then proceed with the installation of the Node modules you want to add to your Node.js project:

$ cd www/nodejs-project/
$ npm install module-name

Rebuild your Cordova project so that the newly added Node modules are added to the Cordova application.

On Android, the plugin extracts the project files and the Node modules from the APK assets in order to make them available to the Node.js for Mobile Apps engine. They are extracted from the APK and copied to a working folder (context.getFilesDir().getAbsolutePath() + "/www/nodejs-project/") when the application is launched for the first time or a new version of the application has been installed.

Warning

Given the project folder will be overwritten after each application update, it should not be used for persistent data storage.

To expedite the process of extracting the assets files, instead of parsing the assets hierarchy, a list of files file.list and a list of folders dir.list are created when the application is compiled and then added to the application assets. On Android 6.x and older versions, this allows to work around a serious perfomance bug in the Android assets manager.

Native Modules

On Linux and macOS, there is support for building modules that contain native code.

The plugin automatically detects native modules in ./www/nodejs-project/ by searching for .gypfiles. It's recommended to have the build prerequisites mentioned in nodejs-mobile for Android and iOS. For Android it's also recommended that you set the ANDROID_NDK_HOME environment variable in your system.

Building native modules for Android can take a long time, since it depends on building a standalone NDK toolchain for each required architecture. The resulting .node binaries are then included in the final application in a separate asset path for each architecture and the correct one will be chosen at runtime.

While the plugin tries to detect automatically the presence of native modules, there's a way to override this detection and turn the native modules build process on or off, by creating the www/NODEJS_MOBILE_BUILD_NATIVE_MODULES_VALUE.txt file and setting its contents to 1 or 0 respectively. E.g., from the root path of your project:

echo "1" > www/NODEJS_MOBILE_BUILD_NATIVE_MODULES_VALUE.txt
cordova run android
echo "1" > www/NODEJS_MOBILE_BUILD_NATIVE_MODULES_VALUE.txt
cordova run ios

Native Modules Sample

There's a sample that can be downloaded from the samples repo that showcases the use of the sha3 and sqlite3 native modules in Cordova.