Getting along with SailsJS and node-webkit

TL;DR: This is a quick example to show you how to use SailsJS and node-webkit together. Grab the code @ GH:
git clone https://github.com/alterx/sailsjs-nodewebkit

I decided to write this article since I couldn't find any source that clearly stated how to integrate both projects. I recommend reading it completely (including references) before coding but then again, that’s your call.

Before we start I’m assuming that you have some previous node-webkit and SailsJS knowledge so I’ll focus in the basic integration rather than explaining how to work with them.

If this is not the case and you have no idea of what i’m talking about it might be a good idea to bookmark this post and head out to http://sailsjs.org and https://github.com/rogerwang/node-webkit so you can take a closer look.

When I stumbled across SailsJS back in 2013 (I think the current version was 0.3.0) I didn't really pay much attention to it since the whole thing wasn't production ready. Still, I bookmarked it (allong with other interesting projects such as Meteor) to check back later. In the first months of 2014 I revisited the page and everything seemed to be more clear, documentation was in good shape and there was a couple of examples to test it out so I jumped in and started poking around.

After some test projects I really wanted to measure the framework’s capabilities in the real world so I decided to use it in a project I was developing for one of my clients.

The action plan was clear: create a REST API, add a couple services, throw in some directives, build for PC/OS X and voilà!

I discovered a great tool for building node-webkit applications. It’s called ‘node-webkit-builder’ [ https://github.com/mllrsohn/node-webkit-builder ] and it’s basically a CLI tool you can use to automate the whole process.

If you have git, node and npm installed pop up a cmd or terminal window and type:

npm install -g node-webkit-builder

After installing the tool I created a test project and created a build. Everything worked like a charm so I started setting up my SailsJS project, added a database, a couple of views and test data. Now I was ready to see how both platforms integrated. I ran:

nwbuild -r path-to-projects-root-folder/ 

And everything seemed to work except by one little detail. Sails wasn't running!

The small example I created before wasn't dynamic at all. It worked because it was plain html/css and a bit of javascript. As soon as I added this intermediate layer (SailsJS) it broke. This boat’s sails weren't lifting.

After some research I found a couple of questions on stack overflow but no one really solved my issue. It seemed like no one was actually using these two tools in conjunction.

I figured out it shouldn't be that hard and started digging into node-webkit’s documentation. I quickly found the ‘window’ object documentation [ https://github.com/rogerwang/node-webkit/wiki/Window ].

EUREKA!

There was a ‘loaded’ event for it, so I created a listener and redirected the page to Sails’ starting point ( localhost:1337 ).

Also, SailsJS provides a nicely crafted app.js file which allows you to start the server just like you start a nodejs app instead of using ‘sails lift’ by merely calling:

node app.js

After this all I needed to do was connect the dots and execute this app.js file after the body was loaded. This was pretty straightforward as you can do it by merely exposing a method to the client side [ https://github.com/rogerwang/node-webkit/wiki/Node-main ].

I added two key-value pairs to the package.json file of my project:

{
'node-main': 'app.js',
'main': 'splash.html'
}

The first one is the same app.js file with a couple of modifications. First, I created an onLoad() function that contains the code we need to execute when body loads and a custom stdin implementation that you are going to need if you use other node modules that require it. We add this as node-webkit doesn't implements it currently.

UPDATE: This stdin statement is no longer true, I removed the code and updated the repository to work with the latest version of node-webkit (it now uses io.js and it’s called nwjs). If you were using node-webkit before don’t forget to run “npm update -g node-webkit-builder” to get the latest version.

(function(){
...
exports.onLoad = function (){
// code to load sails and lift it!
}
});

‘splash.html’ is basically the image/page/splash you’ll show while your applications loads. There’s not much to explain here.

Then, in the actual index.html file (or in this case, homepage.ejs) you need to add:

<body onload="process.mainModule.exports.onLoad()">

That’s it, now that you know how it’s done clone the repository:

git clone https://github.com/alterx/sailsjs-nodewebkit
cd sailsjs-nodewebkit/
npm install
cd ..
nwbuild -r sailsjs-nodewebkit/

-r stands for run, if you omit it node-webkit-builder will create the release ready build. Use:

nwbuild --help

for more details about options you can provide.

If everything worked you should get a native window (OSX, Windows or Linux) with the sailsjs default project homepage. HOORAY!


Disclaimer: I’m not a native English speaker, so feel free to point out grammatical and/or syntactical errors. Every respectful comment is deeply appreciated.

Show your support

Clapping shows how much you appreciated Carlos Vega’s story.