2. It is no secret I think
Node.js is the future in
web development, and
today I will tell you
why.
3. Node.js is ...
Fast
Event Driven
Non-Blocking
Implemented in V8
Serverside
Awesome
(But not just for servers, more later)
Fun to code in, easy to use.
5. def contents = new File('foo.txt').getText()
println contents
println 'something else' All of these events
happen in sequence
Most operations in other languages are blocking
6. Node.js on the other hand utilizes callbacks to make operations more
asynchronous
fs.readFile('foo.txt', function(err, contents){
console.log(contents);
});
console.log('something else')
“something else” will get
executed while the file is
being read.
Code like this can allow the program to return to the event loop right away
and do other tasks.
7. The Traditional “Hello World” App
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World.');
res.end();
}).listen(80, function(){
console.log('server running on port 80');
}); /* server started */
9. $ git clone http://github.com/ry/node.git
$ cd node
$ ./configure && make && sudo make install
Installation
It's really that easy given you're on linux, OSX, or cygwin
(although cygwin can sometimes be a little flakey).
Sorry, no windows support (yet).
Not too keen on using the bleeding edge?
$ git clone http://github.com/ry/node.git
$ cd node
$ ./configure && make && sudo make install
$ wget http://nodejs.org/dist/node-v0.2.4.tar.gz
$ tar zxvf node-v0.2.4.tar.gz
$ cd node
$ ./configure && make && sudo make install
10. The Traditional “Hello World” App
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World.');
res.end();
}).listen(80, function(){
console.log('server running on port 80');
}); /* server started */
Now let's
modularize this a
bit...
11. var http = require('http'),
greeter = require(__dirname + 'greeter');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(greeter.greet('World');
}).listen(80, function(){
console.log('server running on port 80');
}); /* server started */
exports.greet = function (name) {
return 'Hello ' + name + '.';
}
greeter.js
In this example I've created a new module to be used from the main
script. Modularization is a major part of writing any application so let's
delve deeper into how node.js modules are constructed.
app.js
12. Common.js Modules
Node.js implements common.js 1.0 modules with some amount of flexibility.
Every script in node.js has a module global variable, which contains various
details about the module:
id – an identifier for this module, usually the
location on the file system
exports – an array of variables exported for
use externally. Everything else is
encapsulated within the script
parent – the module that included this
module. undefined for the top level module
99.99% of the
time
module.exports
is all you will
use.
13. Everything not assigned to exports (or any other node.js global objects) is
only visible within the scope of the module (Not unlike the revealing
module pattern in client
side js)
More Examples:
function sayGreeting(name) {
return 'Hello ' + name + '.';
}
exports.greet = sayGreeting;
module.exports = {
add: function(a,b){ return a+b; },
multiply: function(a,b){ return a * b}
}
Here, sayGreeting is not visible
outside of the module except
through greet.
var math = require('math'),
add = require('math').add;
math.add(2,2) == add(2,2);
14. More on require()
Looks in require.paths to resolve modules
Add to it:
require.paths.unshift(__dirname + '/lib');
(in case you didn't
realize, __dirname is
the dir of the current
script)Can also be called asynchronously
require('fs', function(fs){
// do something with the fs module here.
});
Exported variables can be referenced directly and even instantiated
var emitter = new(require('events').EventEmitter);
15. Events“Time is a sort of river of passing events, and strong is its current; no sooner is a thing
brought to sight than it is swept by and another takes its place, and this too will be
swept away.”
- Marcus Aurelius
16. EventEmitter
allows the firing and listening
of events within node.js.
Objects that allow
attachment of event
listeners use EventEmitter
under the hood.
17. var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();
emitter.on('pricechange', function(old, new){
console.log(old + ' changed to ' + new);
});
emitter.emit('pricechange', 12.99, 10.99);
emitter.emit('pricechange', 15.99, 17.99);
In Action
18. Keep In Mind...
Event emitters don't interact with each other
var events = new(require('events').EventEmitter);
var events2 = new(require('events').EventEmitter);
events2.on('test', function(msg){
console.log(msg);
});
events.on('test', function(msg){
console.log(msg);
});
events.emit('test', 'some message');
Here the events2 callback will never get
called. That is because the callback is
assigned to a different EventEmitter
instance.
19. EventEmitter is best used “mixed in” with an object to let clients
respond to different events that happen
var EventEmitter = require('events').EventEmitter;
function User(name){
this.name = name
}
// This is one of many ways to inherit from another object
User.prototype.__proto__ = EventEmitter.prototype
var user = new User('Jim');
user.on('login', function(){
console.log('user ' + this.name + ' has logged in');
});
user.emit('login');
20. Events are really a great way to let clients use your module
and respond to different events it might fire without having
to be too concerned about the details.
Let's take a turn back towards modules.
Sure, creating a module is easy, but how
can you share modules with others?
Or take advantage of existing
modules?
21. NPMNode
Package
Manager
Ruby has gem to install manage packages, node.js has npm
Install: https://github.com/isaacs/npm
http://npmjs.org
Simple install: curl http://npmjs.org/install.sh | sh
Browse packages: http://npm.mape.me
In addition to being a kick ass package management system it also makes
it very easy to bundle dependencies with a project for deployment.
npm bundle ./vendor
23. Express.js
Get it: npm install express
Very simple and elegant routing syntax for building applications
Supports a variety of template engines out of the box: jade, haml.js, ejs.
http://expressjs.com
Commandline tool (express) to quickly create a skeletal project structure
25. Connect.js
Middleware for building web applications and more specifically web
application frameworks. Think of it as a framework's framework. ;)
(for example, express uses connect under the hood)
Need sessions, json-rpc, routing? Connect is for you!
https://github.com/senchalabs/connect
npm install connect
Connect addons: oauth, openid, etc
26. WebSockets
WebSockets have a lot of popularity in node.js due to the early adoption and ease of use
Two real contenders: websocket-server and socket.io
Websocket-server – implements the specs
Socket.IO – uses it's own non-spec API on top of websockets, but works with all sorts of
fallback mechanisms using a client side library
http://socket.io
https://github.com/miksago/node-websocket-server
npm install websocket-server
npm install socket.io
27. WebWorkers
Implements the WebWorkers API as a mechanism for interprocess
communication
Start up a script in a separate process, send and receive messages to it
https://github.com/pgriess/node-webworker
https://github.com/cramforce/node-worker
29. Clustering
The answer: node.js doesn't have any built in support for clustering
However, there is much work afoot that will help depending on your needs.
node-event-stream - https://github.com/miksago/node-
eventstream
Uses websockets to replicated events between servers
node-amqp-events –
uses amqp to replicate events between servers
There also many modules for storing sessions in various NoSQL databases
to make them appear replicated across server instances
30. Warning
API is subject to change
In fact examples
you find online are
probably outdated.
The channel and
mailing list can
help.