Getting to NodeJS

So recently I thought I should really give a go at Nodejs. Like most web developpers, I am tired of having to develop two parallel codebases on client and server side. I recently found out that Javascript is actually quite cool and powerful, so I started experimenting.

If you want to go straight to the solution, see below at the ‘Quick workaround’ paragraph.

Now, with proper use of Ajax / JSON and JQuery, you can get to a stage where 90% of the work happens on the client, and the server is just there to serve db requests (hardly producing html). That’s cool, but there are a few catches:

    • A lot of what I do is geared towards Chrome. I don’t even dare trying my website on Firefox, let alone on IE. On my smartphone the page looks sort of okayish, but the HTML5 canvas which I am heavily relying on looks like it was drawn by a 3y old

. You have little control on the kind of software your user is using, whilst if you pick a nodejs server your code will run as you expect it.

  • The more happens on the client, the more you leave the door open to abuses (i.e. users firing up the Chrome Javascript console and running instructions to the server). Obviously if your server filters the requests that shouldn’t be too much of an issue but still, it is one thing more to worry about
  • Most importantly, leaving all your code freely accessible to download by every user might not be great if you have some code you do not want to share. Minify partially solves that issue, but still, if it’s on your servers only there’s way less chance people steal your code

Anyhow, I started playing with node, it all looks cool until I thought, ‘ok, how do I integrate my existing code into this?’, which is the absolute requirement and potential show-stopper. After lots of reading / Googling I was going to give up. I tried looking at requireJS which looked like some sort of quiz for people with a 170 IQ. I then came across a post which change my life. Or my day shall we say…

In Sharing a javascript base class between node… the author gives a very simple trick to have scripts work both on client and server. Interestingly enough it is two years old…

To make it complete, let me run you through the complete solution I got out of it. It’s super down-to-earth and perhaps Javascript experts will think it’s retarded, but this all works. I’ve got around 10 JS files in my projects which are interrelated, and this solved my issue. It took me 15 minutes to modify my files and I can now run command-line scripts with the same code, and I am confident I will be able to make server-side scripts out of them as well.

Quick workaround

I will assume you’ve got nodejs installed. It’s a quite straightforward download anyway.

Step 1

Create a ‘node_utils.js’ with the following code

exports.import_global = function(module)
{
    console.log('Importing ', module, '...');
    var mod = require(module)
    for ( key in mod )
        global[key] = mod[key] // this copies the function to the global scope
}

The benefit of import_global vs require is that this will put all the imported functions in the global scope. This might be considered super bad practice, but in the meantime this is exactly how things happen on client-side Javascript

Step 2

Add the proper imports in each of your legacy scripts. This may be a bit trial and error, and pray for not having circular references (not sure how node deals with it…)

// NODE.JS Compatibility
NODEJS_MODE = typeof window == 'undefined'
if ( NODEJS_MODE )   // this will be false on client-side JS
{
	var import_global = require("./node_utils.js").import_global;  // boilerplate code

        // now do your imports
	import_global('../lib/js/complex.js')
	import_global('./step.js')
	import_global('./utils.js')
}

/*
**
** this is your legacy client-side code
**
** e.g.
** function somefunction()
** {
**    ...
** }
**
*/

// NODE.JS Compatibility
if ( NODEJS_MODE )
{
	exports.somefunction = somefunction;
}

Step 3

A cool thing to know is that node-inspector allows you to debug node pretty much the same way as client-side Javascript. That is if you’re using Chrome or a webkit-compatible browser.

Well I hope this will be helpful for you as much as it was for me. Could be that in one weeks time I will think this was stupid, but I couldn’t help sharing this.

Remarks

  • If you have JQuery code, you may have trouble integrating it as is. It looks like this is something requireJS is dealing with. In my case, my scripts were written in such a way that there is a fair amount of (rather tricky) code that is completely DOM-agnostic (it’s mostly graphical libraries that calculate coordinates of various shapes), so I am fine. I would think that DOM code should not be invoked in nodeJS scripts, but it might be easier said than done if your code is monolithic.
  • At some point I got shivers when I realized that I had stuff like this in my legacy code
    Array.prototype.Table = function() 
    {
         /* ... */
    }
    

    But turns out this is not an issue – I just wrote the usual

    exports.Table = Array.prototype.Table
    

    and my modified scripts work both on client and nodeJS, where I can write stuff like

    a = [1,2,3].Table();
    
Advertisements

2 thoughts on “Getting to NodeJS

  1. I really appreciate this post. I have been looking everywhere for this! Thank goodness I found it on Bing. You have made my day! Thank you again

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s