intro to:




iain nash


HackSC Series Fall 2013

Github Talk Repo:

Get started:


Install Node.js


http://nodejs.org/


Why is node so hip?


  • event-driven
  • bridges javascript server + client code
    • allows for non-blocking IO

Because it's fast


 

Because it's easy


javascript is on

the client + the server


easy.

Nonblocking vs Blocking

When making a disk request:

php:

<?php 
$big_file = file_get_contents("huge_file.txt");
// ^ blocks process until done
$rows = count_rows($big_file);
echo "There are $rows rows";
node:

fs.readFile('huge_file.txt', function(file_contents){
// adds nonblocking callback, allowing other operations to continue
callback(file_contents.split("\n").length);
}

speed:



Because I/O operations are
tens of millions times 
slower than processor time

Real-time apps


Because Node.js is non-blocking, its
well-suited for real-time web applications.


app.route('/poll', function(response){
// can wait a LONG time for the response
//  without much processor load, or opening tons of threads
  when('message_sent', function(message){
    response.setOk();
    response.send(message);
  }
}

Most web stacks:

Have to use ajax polling:

have any updates? no
have any updates? no
have any updates? no
(repeat 20x...)
have any updates? yes!

Node.JS


Nonblocking + Lightweight (no threads / forks):

have any updates? ......... (20sec) yes! .......... here you go!
No back + forth = allows for realtime communication.

Server? huh?

Most web programming languages use a webserver,
With Node you run it's own webserver.

Make your first node server!



var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n'); 
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');


Run with: node <filename>.js,

What's going on here?


var http = require('http');
// ^ here we require node's http library, into the http object

http.createServer(function (req, res) {
// ^ this method is a node api method to create a http server

  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n'); 
  // ^ callback when we get a request, to respond to it asynch.

}).listen(1337, '127.0.0.1');
// ^ calls the listen function of the new node http.Server object.

console.log('Server running at http://127.0.0.1:1337/');
// ^ console.log for debugging outputs to stdout, just like web inspectors on the frontend

Let's add some realtime:

var http = require('http')
  , fs   = require('fs')
  , events = require('events')
  , router = require('./router');
// ^ shiny - we're requiring our own local file (./router.js)
var stream = new events.EventEmitter();
var index_html = fs.readFileSync('chatroom.html');
http.createServer(function(req, res){
    var test_route = routes[req.method + ':' + req.url.match(/\/([A-Za-z0-9]*)/)[1]];
	// :-);
	if (!test_route) test_route = routes['GET:404'];
	// if not found, 404;
	test_route(req, res);
	// send to router.
}).listen(1337);

the "router"

module.exports = { // we're exporting these functions
// requiring(this file) - returns the module.exports object.
    // AJAX Long Polling Route
    "GET:poll": function(req, res){
		stream.once('chat', function(message){
			res.writeHead(200, {'Content-Type': 'text/plain'});
			res.end(message);
        });
    },
    // Index.html Page
    "GET:": function(req, res){
	    res.writeHead(200, {'Content-Type': 'text/html'});
	    res.end(index_html);
    },
// continued...

Router - part #2

    // 404 page :( (called by simple router)
    "GET:404": function(req, res){
        res.writeHead(404, {'Content-Type': 'text/plain'});
        res.end('Page Not Found!');
    },
    // Message Post Page
    "POST:message": function(req, res){
        var post_body = '';
        req.on('data', function(data){
            post_body += data;
        });
        req.on('end', function(){
            stream.emit('chat', post_body);
        })
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('ok');
    }
}

sounds hard? 'cause it is:




install express:

npm install express
var express = require('express')
   , app = express();
// express takes care of the routing, and request/response helpers
app.get('/http.txt', function(req, res){
  var body = 'hello world!';
  res.setHeader('Content-Type', 'text/plain');
  res.setHeader('Content-Length', body.length);
  res.end(body);
});
// or have express do more for you:
app.get('/hi.txt', function(req, res){
  res.end('hello world!');
});
app.listen(3000);
    

packages? enter npm



Node Package Manager

usage:

Usage: npm <command>

where <command> is one of:
    init, install, isntall, la, link, list, ll,
    ln, login, ls, outdated, owner, pack, prefix, prune,
    publish, r, rb, rebuild, remove, restart, rm, root,
    run-script, s, se, search, set, show, shrinkwrap, star,
    start, stop, submodule, tag, test, tst, un, uninstall,
    unlink, unpublish, unstar, up, update

npm <cmd> -h     quick help on <cmd>
npm -l           display full usage info
npm faq          commonly asked questions
npm help <term>  search for help on <term>
npm help npm     involved overview

Specify configs in the ini-formatted file:
    /Users/iain/.npmrc
or on the command line via: npm <command> --key value
Config info can be viewed via: npm help config

npm@1.1.70 /Users/iain/.nvm/v0.8.5/lib/node_modules/npm

Package.json

{
    "name": "packagename",
    "version": "0.0.1",
    "private": true,
    "dependencies": {
        "express": "2.5.5",
        "stylus": "0.22.2"
    }
}


Official Documentation:

github.com/isaacs/npm/blob/master/doc/files/package.json.md

or:

 $ npm help json

Not your mom's javascript:

Common style guidelines:

  • 2 spaces for indentation
  • braces on the same line as conditional
  • var comma initialization
  • single quote strings / don't repeat yourself
var fubar = 'hi'
  , thing = "that"
  , object = {
      "bar": "foo"
    , "fubar": "asdf"
    };
if (thing == 'that'){
  do(object);
}

node.js resources

npm packages:

node.js docs:

node.js howtos:

talk repo:

node.js intro

By Iain Nash

node.js intro

  • 3,169