Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building for clients with Node.js

Paul Serby
February 22, 2012

Building for clients with Node.js

How clock build websites for their clients in node.js

Paul Serby

February 22, 2012
Tweet

More Decks by Paul Serby

Other Decks in Technology

Transcript

  1. Overview About us Why node.js Our approach - code examples

    Client projects Pain points - code examples Did we make the right decision?
  2. Crockford on JavaScript - Act III: Function the Ultimate -

    http://bit.ly/xooF1h Module Pattern Pseudo-classical inheritance - “This was the inheritance scheme that was designed for the language, and I really don't care for it at all. I don't think it looks very good.”
  3. var EventEmitter = require('events').EventEmitter; exports.createKitten = function() { var dead

    = false , energy = 0 , kitten = new EventEmitter(); function eat() { deadCheck(); energy += 10; } function run() { deadCheck(); if (energy > 1) { energy -= 1; } else { die(); } } function die() { kitten.emit('died', self); deadCheck(); dead = true; } function deadCheck() { if (dead) { throw new Error('You are dead'); } } kitten.eat = eat; kitten.run = run; return self; }; var util = require('util') , events = require('events'); function Kitten() { events.EventEmitter.call(this); } function deadCheck(kitten) { if (kitten.dead) { throw new Error('You are dead'); } } util.inherits(Kitten, events.EventEmitter); Kitten.prototype.energy = 0; Kitten.prototype.dead = 0; Kitten.prototype.eat =function() { deadCheck(this); this.energy += 10; }; Kitten.prototype.run =function() { deadCheck(this); if (this.energy > 1) { this.energy -= 1; } else { this.die(); } }; Kitten.prototype.die = function () { this.emit('died', this); deadCheck(this); this.dead = true; }; exports.Kitten = Kitten;
  4. var serviceLocator = require('service-locator').createServiceLocator() , foo = 'bar'; serviceLocator.register('foobar', foo);

    console.log(serviceLocator.foobar); // bar serviceLocator.register('logger', console); serviceLocator.logger.log('Hello world'); // Hello world http://github.com/serby/service-locator Inversion of Control
  5. Most modules should have exactly 1 export. Module systems should

    be designed around that use case first, not for dozens of exports. substack Separation of concerns if your module exposes more than one function, you might be doing it wrong :) mikeal
  6. Moduleitus exports.createMathLib = function () { var answer = NaN;

    return { sum: function (x, y) { answer = x + y; }, get answer() { return answer; } }; }; var math = require('math-lib').createMathLib() , printer = require('printer').createPrinter(); math.sum(1, 1); printer.setPrefix('The answer is: '); printer.out(math.answer); exports.createPrinter = function() { var prefix = ''; return { setPrefix: function(value) { prefix = value; }, out: function(value) { console.log(prefix + value); } }; }; http://robert.accettura.com/blog/2008/12/16/object-oriented-masturbation/ npm install math-lib npm install printer
  7. function sum(x, y) { return x + y; } console.log('The

    answer is: ' + sum(1, 1)); Sanity
  8. Usage Stats 104,922 Registrations Ran for 1 month Read: 950

    per second at peak 150 reg per second at
  9. var userModel = require('../lib/userModel').createUserModel(); module.exports.findMe = function(user, callback) { userModel.findByEmail(user.email,

    function(error, foundUser) { if (error) { return callback(error); } if (foundUser === null) { userModel.findByName(user.name, function(error, foundUser) { if (error) { return callback(error); } if (foundUser === null) { userModel.findByGithub(user.github, function(error, foundUser) { if (error) { callback(error); } if (foundUser === null) { callback(null, null); } else { callback(null, foundUser); } }); } else { callback(null, foundUser); } }); } else { callback(null, foundUser); } }); };
  10. var userModel = require('../lib/userModel').createUserModel(); module.exports.findMe = function(user, callback) { userModel.findByEmail(user.email,

    function(error, foundUser) { if (error) { return callback(error); } if (foundUser === null) { userModel.findByName(user.name, function(error, foundUser) { if (error) { return callback(error); } if (foundUser === null) { userModel.findByGithub(user.github, function(error, foundUser) { if (error) { return callback(error); } if (foundUser === null) { callback(null, null); } else { callback(null, foundUser); } }); } else { callback(null, foundUser); } }); } else { callback(null, foundUser); } }); };
  11. var userModel = require('../lib/userModel').createUserModel(), step = require('step'); module.exports.findMe = function(user,

    callback){ step( function() { userModel.findByName(user.name, this); }, function(error, result) { if (error || result) { this(error, result); } else { userModel.findByEmail(user.email, this); } }, function(error, result) { if (error || result) { this(error, result); } else { userModel.findByGithub(user.github, this); } }, function(error, result) { callback(error, result); } ); }; Step https://github.com/creationix/step
  12. var userModel = require('../lib/userModel').createUserModel(), async = require('async'); module.exports.findMe = function(user,

    callback){ var foundUser, foundError; async.detectSeries( [ async.apply(userModel.findByEmail, user.email), async.apply(userModel.findByName, user.name), async.apply(userModel.findByGithub, user.github) ], function (fn, cb) { fn(function(error, user) { foundUser = user; foundError = error; cb(foundError || user); }); }, function(result) { callback(foundError, foundUser); } ); }; async https://github.com/caolan/async
  13. var userModel = require('../lib/userModel').createUserModel(); module.exports.findMe = function(user, callback){ var fns

    = [ userModel.findByEmail.bind(this, user.email), userModel.findByName.bind(this, user.name), userModel.findByGithub.bind(this, user.github), function() { return callback(undefined, null); } ]; function detect(error, user) { if (error || user) { return callback(error, user); } fns.shift()(detect); } detect(); }; none
  14. var userModel = require('../lib/userModel').createUserModel(), chain = require('jangle').chain; module.exports.findMe = function(user,

    callback){ chain() .seq(userModel.findByName, user.name) .seq(userModel.findByEmail, user.email) .seq(userModel.findByGithub, user.github) .detect(function(error, returnedUser) { return returnedUser; }) .run(callback); }; jangle https://github.com/serby/flow-control-examples