Node.js Logo

Jordan Kasper | @jakerella

What is Node.js?

Node is not "JavaScript" exactly...

"JavaScript" is a trademarked term!

Node is ECMAScript

So what is ECMAScript?

ECMAScript is a Language Specification...

...with various implementations:

  • Mozilla's SpiderMonkey
  • Microsoft's Chakra
  • Adobe's Tamarin (ActionScript)
  • Rhino (early server-side implenentation; written in Java)
  • Chrome's V8

The Node Core

Node builds on V8 with C++ and JavaScript code.

Why Node?

  • Node is fast.
    • Non-blocking I/O
    • JavaScript arms race (V8)
  • One language to rule them all
  • Vibrant Ecosystem (npm)

Node... What is it good for?

APIs

And specifically ones with high concurrency that interact with multiple back ends.

Caveats

  • Have to think in async (Callback Hell)
  • Frameworks and tools are still growing
  • JavaScript "quirks"

Node is Single-Threaded

(But that's ok...)

https://training.strongloop.com/images/threaded.png

https://training.strongloop.com/images/event-loop.png

Using npm

"Node Package Manager"

More than just dependencies!

Project Meta: package.json

/my-project$ npm init

This utility will walk you through creating a package.json
file.  It only covers the most common items, and tries to
guess sane defaults.
...

Press ^C at any time to quit
name: (my-package-name)
    

A Basic package.json


{
    "name": "my-project",
    "version": "1.0.0",
    "description": "This is my project!",
    "main": "main.js",
    "scripts": {
        "test": "echo \"You have no tests!\""
    },
    "author": "John Doe <john@doe.com>",

    "license": "MIT",
    "private": true
}
    

Adding Dependencies

/my-project$ npm install express --save
/my-project$ npm install mocha --save-dev
    
{
    ...,
    dependencies: {
        "express": "^4.12.4"
    },
    devDependencies: {
        "mocha": "^2.3.3"
    }
}
    

Adding Node Dependencies


/my-project$ npm install express --save
    

my-project
  |_ node_modules
    |_ express
    |_ mocha
    |_ bluebird
    ...
  |_ server
    ...

A word on versions...

Node encourages Semantic Versioning (semver)...

  4   .   2   .   1
major   minor   patch

A word on versions...

When adding a dependency in Node:

dependencies: {
    "express": "^4.12.4"
},
    

"^4.12.4" >> 4.12.5, 4.12.6, 4.13.0, 4.14.1, 5.0.0

"~4.12.4" >> 4.12.5, 4.12.6, 4.13.0, 4.14.1, 5.0.0

"4.12.*" >> 4.12.5, 4.12.6, 4.13.0, 4.14.1, 5.0.0

"*" >> ಠ_ಠ

Global Packages

Used for various tooling
(scaffolding, testing, build, deploy, etc)

~$ npm install -g grunt-cli
~/my-project$ grunt build

How do I use module X?

READ THE DOCS.

Doesn't have docs? Use a different module.

Choosing a Module

  1. Documentation
  2. Tests
  3. Project Velcity
  4. Community Involvement

Basic Module Usage

Basic Module Usage

var express = require('express');

var app = express();

app.set('foo', 'bar');
    

Requiring Modules

Modules can live different places:

var filesystem = require('fs'),          // core Node module
    express = require('express'),        // from /node_modules/
    router = require('./app/router.js'), // app file
    config = require('../config/config.json');
    

Building Node Modules

Hello World

// hello-world.js
module.exports = function sayHello( recipient ) {
    console.log( "Hello " + recipient );
};
    
// main.js
var foobar = require('./hello-world');

foobar( 'Everyone!' );
    
$ node main.js
Hello Everyone!
    

Module Exports

Whatever is on the module.exports property becomes
the return value of require('...')!

Module Exports

//answer.js
module.exports = 42;
    
// main.js
var theAnswer = require('./answer.js');

theAnswer === 42; // true!
    

Module Patterns

  • Simple Object API
  • Revealing Module
  • Object Constructors

Simple Object API

// company.js
module.exports = {
    name: "Foo's Widgets",
    sayHello: function() {
        return "Hello " + this.name;
    }
};
    
var api = require('./company');
console.log( api.sayHello() );  // "Hello Foo's Widgets"
    

Why not use a simple Object?

Modules are cached by Node!

Requiring a module twice could yield unexpected results!

Module Caching

module.exports = {
    salary: 50000,
    giveRaise: function(amount) {
        this.salary += amount;
    }
};
var workerOne = require('./worker');
workerOne.giveRaise(10000);
console.log( workerOne.salary );  // 60000

var workerTwo = require('./worker');
workerTwo.giveRaise(10000);
console.log( workerTwo.salary );  // 70000!

Revealing Module Pattern

Revealing Module Pattern

module.exports = function createWorker(options) {
    return {
        salary: options.salary,
        giveRaise: function(amount) {
            this.salary += amount;
        }
    };
};
    
var getWorker = require('./worker');

var workerOne = getWorker({ salary: 30000 });
workerOne.giveRaise(7000);  // workerOne.salary === 37000
    

var workerTwo = getWorker({ salary: 50000 });
workerTwo.giveRaise(5000);  // workerTwo.salary === 55000
    

Object Constructor Pattern

Use JavaScript prototypes and constructor functions to construct objects.

Object Constructor Pattern

var Worker = module.exports = function Worker(options) {
    // ... worker initialization stuff
};

Worker.prototype.giveRaise = function(amount) {
    this.salary += amount;
};
    

What else can Node do?

The Node process

An interface to the current Node system process:

  • Environment variables (process.env)
  • CLI args (process.argv)
  • System Process ID (process.pid)
  • Memory (process.memoryUsage())
  • etc, etc...

HTTP (in 10 lines)

var http = require( 'http' );

var server = http.createServer( function request( req, res ) {
    res.writeHead( 200, {
        'Content-Type': 'text/html'
    } );
    res.end( '<h1>Hello World!</h1>' );
} );

server.listen( 3000, '127.0.0.1', function() {
    console.log( 'The server is up!' );
} );
    

FileSystem

var fs = require( 'fs' );

fs.readFile( 'config.json', function( err, data ) {
    if ( err ) {
        // handle it!
        console.error( err.stack );
        return;
    }

    // `data` is a Buffer, so decode it first...
    console.log( JSON.parse( data.toString('utf-8') ) );
});
    

More Core

  • Child Processes
  • Streams
  • Crypto
  • Cluster
  • Events
  • OS
  • ...

Data Sources

Easy to connect to most database management systems

Native drivers for:

  • Oracle
  • MySQL
  • MSSQL
  • MongoDB
  • DB2
  • Cloudant

MySQL

~/my-app$ npm install mysql --save
    

MySQL Module Usage

var mysql = require('mysql');

var connection = mysql.createConnection({
    host: 'localhost',
    port: 3306,
    // ...
});
connection.connect();
    

connection.query(
    "SELECT * FROM `books` WHERE author='Tolstoy'",
    function(err, rows, fields) {
        if (err) { /* ... */ return; }

        rows.forEach(function(row) { /* ... */ });

        connection.end();
    }
);
    

ORMs and ODMs

sequelize

Mongoose (MongoDB)

Waterline

So it's just...   JavaScript?



YES!

Cool.

Iknowright?

Thank You!

jordankasper.com/intro-to-node

Jordan Kasper | @jakerella