In the last article we have focused on how to use Cordova to build hybrid web applications with Smart Mobile Studio. In this article we focus about writing Node.js command-line tools (like Cordova) itself in Smart Mobile Studio.
When looking at the supplied examples in Smart Mobile Studio you only find a Node.js server example. However, with Node.js you can do far more than that. At its core it’s just a fast and powerful script engine, which can be used for everything a script is capable of. Cordova is just one example.
Other popular examples include Microsoft’s TypeScript, which is a language (compiler) developed with the help of Anders Hejlsberg (one of the creators of Delphi). Another compiler written in Node.js is coffee-script. But there is so much more to discover: build automation, database management, big data, IoT, neuronal networks, image processing – you name it.
The universe of npm
The powerful package manager npm allows to extend the Node.js universe easily. At time of writing there are over 230k packages available! And with Smart Mobile Studio your code can get available for Node.js as well.
For Node.js projects written in Smart Mobile Studio you don’t need much. Just start with a new Node.js project. The project already contains code for a web server. For command-line tools you don’t need this code. You can even remove any unit and just go with the project file. For small tools this is probably already enough.
Hello World
In our case we actually don’t need any unit. Just delete it an head over to the project file (double click on the project’s root, probably called ‘Project1’). There you can delete the entire code as well. For this example we start with something as simple as this:
uses NodeJS.Core;
Console.Log('Hello World')
This will just output ‘Hello World’ to the console. The console object is defined in NodeJS.Core and offers a few other methods we will mention here a bit later.
If you run the project now (F9) you might experience a console window popping up and closing immediately. If this is the case you’re probably using an older version, but it’s not a problem at all. You just need to run Node.JS from the command line then to avoid the window closing right after your script termintates. In newer versions you should see the output in the output message tab.
Right now the tool isn’t very useful, so we improve it slightly by processing some input. You can access arguments supplied to the tool with
Process.argv
The field ‘argv’ of the object ‘Process’ is an array of strings. You can query the number of arguments with
Process.argv.length
And thus the above example can be rewritten to display the number of supplied arguments like this
uses NodeJS.Core;
Console.Log(Process.argv.length);
While it looks pretty simple, you might wonder that it will return 2. The first argument is always the full filename of the Node.js executable. You can find it out by adding:
Console.Log(Process.argv[0]);
Typically it reads something like ‘C:\Program Files\nodejs\node.exe’ if executed in Windows.
The second argument is the full filename of the script. If you haven’t saved the project at this point the argument should read something like this: ‘C:\Users\YourUsername\AppData\Local\Temp\sma????.smart\output\Project 1.js’. So it’s probably time to save. This step is also necessary as we want to run the script from the console in one of the next steps.
Running Node.js on a console
Save it to any path and open a console at this location. Now type:
node output\Project 1.js
or however your project is called. While the name doesn’t matter. It is better for the further steps to pick a name without spaces in it. Something like ‘Project1’ would work fine.
If you execute it now, the second argument should read different now (the full filename of the supplied Node.js script).
If you want, you can have a look at the source code now. It will probably look like this:
var $Application = function() { console.log(process.argv.length); console.log(process.argv[0]); console.log(process.argv[1]); } $Application();
You can get rid of the ‘Application’ main body by un-checking the ‘Use main body’ switch on the ‘Code Generator’ tab of the ‘Project Options’. It then reads only:
console.log(process.argv.length); console.log(process.argv[0]); console.log(process.argv[1]);
If you pass a further argument to the command line you can access this with process.argv[2] and so forth.
You can print a second argument (if supplied) like this:
uses NodeJS.Core;
if Process.argv.length > 2 then Console.Log(Process.argv[2]);
It can be executed with node output\Project1.js “Hello World”
If you leave the quote marks missing Node.js will recognise two additional arguments instead of one.
Bork, bork, bork
Now let’s consider we would want to write a command-line tool that add’s the Muppet show’s swedish chef’s https://en.wikipedia.org/wiki/Swedish_Chef closing words ‘bork bork bork’ to any passed string. For this the code would look like this:
uses NodeJS.Core;
if Process.argv.length > 2 then Console.Log(Process.argv[2] + ', bork, bork, bork');
Or you could want to add ‘, bork’ to each of the supplied words. This will be slightly more complicated. Something like this:
uses NodeJS.Core;
if Process.argv.length > 2 then begin // separate argument into words var Words := Process.argv[2].Split(' ');
// synthesize output string var Output := ''; for var Word in Words do Output += Word + ', bork, ';
// strip last ', ' part if Output.Length >= 2 then Delete(Output, Output.Length - 1, 2);
Console.Log(Output); end;
Similar to this even more complex tasks can be done from this point. In fact everything that is possible with Node.js can be done with Smart Mobile Studio as well. You can even call natively compiled executables or dynamic link libraries, but that’s topic of another article.
When you’re code is ready to be published, you only have to follow a few steps until you’re set.
Publishing
The easiest way is to let npm guide you through the process (with a command-line tool written in the same manner as the code above). Just navigate to the ‘output’ directory and type:
npm init
and you will be guided through the process. Eventually you might want to have this published on your GitHub account, so have it ready when asked.
In addition to this your code needs another important line (at least if you want to run this on Linux as well). For this just paste:
#!/usr/bin/env node
into the first line of your JavaScript code.
In the above example case it has to looks like this:
#!/usr/bin/env node
function Delete(s,i,n) { var v=s.v; if ((i<=0)||(i>v.length)||(n<=0)) return; s.v=v.substr(0,i-1)+v.substr(i+n-1); } var Words = [], Output = {v:""}, a$2 = 0; var Word = ""; if (process.argv.length>2) { Words = (process.argv[2]).split(" "); Output.v = ""; var $temp1; for(a$2=0,$temp1=Words.length;a$2<$temp1;a$2++) { Word = Words[a$2]; Output.v+=Word+", bork, "; } if (Output.v.length>=2) { Delete(Output,Output.v.length-1,2); } console.log(Output.v); }
After you have been guided through the initialization process for an npm package you might have noticed a new file called ‘package.json’ in your repository.
You can already install your new tool with this:
npm install -g
Now it should already be accessible with:
Project1
from the command-line (in any directory!). At this time you might also notice that it was a good choice to pick a name without spaces!
The very last step would be to publish this to the npm registry. Once configured (see https://quickleft.com/blog/creating-and-publishing-a-node-js-module/) it is as simple as:
npm publish
If you later want to update your npm package, you need to advance the version as well. In case you decide for the minor version this can be done with
npm version minor
After this you can republish your package again with
npm publish
Summary
In this article you should have learned about how easy it is to use Smart Mobile Studio to create Node.js command-line tools. Similar to this you can also write packages, which can be used by other Node.js users. Or you could do both: write a package that encapsulates the logic and expose this in a command-line tool.