ict.ken.be

Delivering solid user friendly software solutions since the dawn of time.

NodeJs

Categories: Nodejs

Since november 2009 at http://jsconf.com/ europe by Ryan Dahl, because building progress bars into Ruby was just to slow. Written for a data center.

Who is using node

Best tool vs swiss army knife

  • Sharding complexity by separating your code
  • Composition in favor of inheritance
  • Avoid callback hell (http://callbackhell.com/)
  • No nested if-then-else, return early
  • Error-first callback
  • Leverage the ecosystem
  • Develop for the clueless stranger

Error-first callbacks

fs.readFile('/foo.txt', function(err, data) {
    if(err) {
        if(err.fileNotFound) {
            return this.sendErrorMessage('File Does not Exist');
        }
        if(!err.noPermission) {
            return next(err);
        }
    }
    console.log(data);
});

Use async

async.parallel({
    one: function(callback){
        setTimeout(function(){
            callback(null, 1);
        }, 200);
    },
    two: function(callback){
        setTimeout(function(){
            callback(null, 2);
        }, 100);
    }
},
    function(err, results) {
    // results is equal to: {one: 1, two: 2}
});

Testing

  • There are no points for clever tests
  • Test clarity above all else
  • Jasmine all in one testing framework
  • Mocha follows node standard, no mocks, no asserts

Mocha

describe('yourModuleName', function() {
    before(function(){
        // The before() callback gets run before all tests in the suite. Do one-time setup here.
    });
    beforeEach(function(){
        // The beforeEach() callback gets run before each test in the suite.
    });
    it('does x when y', function(){
        // Now... Test!
    });
    after(function() {
        // after() is run after all your tests have completed. Do teardown here.
    });
});

NodeJs Built-In Assertions

assert.equal(life, 42, 'some message');
assert(life === 3, 'some message');

Chai Assertion Library

foo.should.be.a('string');
expect(foo).to.be.a('string');
assert.typeOf(foo, 'string');

Sinon Spies, Stubs and Mocks

var callback = sinon.stub();
callback.withArgs(42).returns(1);

Mockery Require Mocking

before(function() {
    mockery.enable();
    mockery.registerAllowable('async');
    mockery.registerMock('../some-other-module', stubbedModule);
});
after(function() {
    mockery.deregisterAll();
    mockery.disable();
});

Rewire Require DI

var rewire = require("rewire");
var myModule = rewire("../lib/myModule.js");
myModule.__set__("path", "/dev/null");

Modules

Type example (preferred)

var privateStaticVariable = true;

module.exports = User;
function User(n) {
    this._privateVariable = true;
    this.name = n;
}
User.prototype.sayHi = function() {
    console.log('Hi, My name is ' + this.name);
};

var User = require('User');
var alice = new User('Alice');
alice.sayHi(); // "Hi, My name is Alice"

Slower, but real private variable (avoid)

module.exports = User;
function User(n) {
    var privateVariable = true; 
    this.publicVariable = n;     
    this.toggle = function toggle() {
        privateVariable = !privateVariable;
    }
}

Running multiple node versions

Using EcmaScript 2015 (ES6)