Node.js: JavaScript Beyond the Browser @ Trustious

This week’s Trustious talk was given by Saher El-Neklawy (engineering lead at Trustious) and was about node.js. Here is a summary of the material covered. Don’t hesitate to ask questions or share your own insights in the comments section. Enjoy!

Saher 4

What is node.js?

Node.js allows you to (wait for it) run JS on the server! This is a technology that is significantly changing the playing field. The punch line is that node.js allows the wealth of existing JS libraries to work on the server side. This expands the server side possibilities beyond the traditionally available python and ruby libraries. A good source for getting started with node.js is here.

Let’s show you how cool is that!

In its current state, Trustious is running on Ruby on Rails on the server side and using angularJS on the browser. We will give you an example of how we used some Javascript functionalities on the server side to avoid repetition (i.e keeping the feature DRY), and an example of how the ability to run JS on the server can be used to simulate a browser to do exciting stuff!

An example of using node.js – Previewing Articles

When building articles on Trustious (like this), we wanted to have a simple editor for writers that offers a preview of the article. For that, we opted for the JS markdown compiler Showdown. This allows us quick and easy preview without going back to the server.

The challenge now is that we wish to serve HTML when viewing the actual article as opposed to serving markdown and compiling it to HTML on the client side using our JS markdown compiler. Why? Serving the HTML directly is faster in rendering, since there is no wait for JS processing. One solution is to have another server side markdown compiler library. That isn’t cool because having a separate library to compile the stored markdown for the article would lead to inconsistencies with the preview, and will require us to duplicate any customization work done to markdown compilation.

The solution we took is to compile the markdown using Showdown (remember that is a JS library) on the server. This was made possible through node.js

How can I talk to node.js from in a ruby application?

Since we are serving the HTML of the articles through a Ruby on Rails application, we need to execute the JS script that compiles the markdown. But how to send the markdown to the script, and read the resulting HTML?

The solution comes through the standard input stream STDIN and the standard output stream STDOUT. There are other approaches but the main reason we opted for this approach is its speed, and robustness to race conditions.

Ruby has the open3 module. You can send and receive data through the standard streams for a process you run. This is identical to bash pipes. So if you have the command foo.sh, you can communicate with it as follows:

data_out, status = ::Open3.capture2("foo.sh", stdin_data: "test")

This will send test to the the standard output stream of foo.sh and store the standard output stream content in data_out.

The ruby code above is equivalent to the following in bash:

echo "test" | foo.sh

Therefore, given the following JS script which uses Showdown to compile some markdown from standard output:

//md2html.js

var Showdown = require(__dirname + '/showdown.js', 'utf8');
var converter = new Showdown.converter();

var content = '';
process.stdin.resume();

process.stdin.on('data', function(buf) { content += buf.toString(); });
process.stdin.on('end', function() {
  console.log(converter.makeHtml(content));
});

If the script is stored in script/md2html.js, a rails helper may be written as follows:

def format_markdown(markdown)
  require 'open3'
  output, status = ::Open3.capture2("node #{Rails.root.join('script/md2html')}", stdin_data: markdown)
  output
end

With this we have the same markdown compilation both server and client side.

On a side note for the Vim inclined, you can use the same script to convert the markdown content of the current buffer to HTML ( this is how this post was written ;) ). This can be done as follows: :%!node script/md2html

An example of using node.js – Headless Browsers

Headless browsers have grown popular recently, especially phantomJS. These allow you to run a full browser environment, without starting up a graphical interface. This is is very useful if you need to run a browser environment on a server where graphical environments are not available. It turns out that headless browsers are often scripted in javascript, and are therefore (you guessed it) available through node.js.

Pre-Rendering HTML Server Side

At Trustious, we use headless browsers (running server side through node.js) to pre-render HTML templates that would naturally be rendered client side using angularJS. Why do we do that? To serve content above the fold quickly as pre-filled HTML without having to wait for the JS to load up client side. Don’t tell anyone, but that brings about an appreciable speed advantage! We will hopefully make time to describe the details behind the technique in a future post. For now you can get a glimpse of it as mentioned by Twitter and airbnb.

CSS Regression

We also use headless browsers (running server side through node.js) to provide visual regression tests for the state of the various Trustious pages. The concept here is this: After deploying new code, take a screen shot of every page with and without the new code then subtract the images to see if there are any unwanted changes. This allows flexibility and through testing of CSS without the hassles of Selenium. You can find out more about CSS regression here.

We do CSS regression through a tool chain called wraith. Wraith compares visual snapshots of an HTML and can be scripted to your website’s need via JavaScript through phantomJS. Some tip and tricks about how to use wraith, especially with pages that require the user to sign-in will, hopefully, be discussed in a future post.

If you are interested to know more or have questions about how this can work with your project, do not hesitate to contact us.

One thought on “Node.js: JavaScript Beyond the Browser @ Trustious”

  1. Congratulations on finally, the first technical post. Keep ’em coming. Interesting content. Especially the CSS testing workflow you are using.

    I think the writing style for this one is a bit too amateur for a technical post. For example in the first paragraph: “Node.js allows you to *?*(wait for it)*?* run JS on the server!”. Most developers who are familiar with Node would have left the page at this point and definitely missed out on the worthy CSS testing work mentioned at the bottom. Keep moving forward. I missed you guys.

    Greetings from Berlin.

Leave a Reply