Node.js

Created by Maksym Tarasenko

Agenda

  • Node Basics
  • Modules
  • NPM
  • Async Code / Streams
  • Development & Debug

What is node?

  • v8 javascript engine
  • Event drivin
  • Non-blocking standart libraries
  • C\C++ adons
  • NPM

JavaScript Everywhere

  • Code reuse (minimal)
  • Same programming culture on client and server
  • Lots of JavaScript programmers

Vibrant Community

  • 324,000+ packages on npm
  • Top corporate sponsors
  • Huge wealth of JS code

Sweet Spots

  • Real-time/high concurrency apps (I/O Bound)
  • API tier for single-page apps and rich clients (iOS, Android)
  • Service orchestration
  • Working with document (JSON-style) databases

EVENT LOOP

EVENT LOOP

EVENT LOOP

EVENT LOOP

Event Loop

Modules

  • Prevents pollution of the global scope
  • Module structure
  • module.exports
  • Caching

Modules: require

var module1 = require('module1'); var module1 = require('./node_modules/module1/index.js'); var module2 = require('./module2'); var module3 = require('../module3');

Modules:

exports.log = function(msg) { console.log(msg); } module.exports = function Loger() { this.log = function(msg) { console.log(msg); } };

NPM / Yarn

  • package.json
  • npm init
  • npm install
  • npm publish

package.json (1)

{
	"name": "3_npm_test",
	"version": "1.0.0",
	"description": "test package",
	"main": "main.js",
	"scripts": {
		"test": "echo \"Error: no test\" && exit 1",
		"runMain": "node main.js"
	}
}

package.json (2)

{
	"repository": {
		"type": "git",
		"url": "git+https://github.com/itmoh/node-mentoring.git"
	},
	"keywords": [
		"node"
	],
	"author": "maxim tarasenko",
	"license": "ISC",
	"bugs": {
		"url": "https://github.com/itmoh/node-mentoring/issues"
	},
	"homepage": "https://github.com/itmoh/node-mentoring#readme"
}

Streams

EventEmitter

var EventEmitter = require('events'); var emitter = new EventEmitter(); var listener = (arg) => {console.log(arg);}; emitter.on('test', listener); setTimeout(function() { emitter.emit('test', 'Hello world'); emitter.removeListener('test', listener); emitter.emit('test', 'Hello world'); }, 1000);

Readable Stream

var fs = require('fs'); var readableStream = fs.createReadStream('file.txt'); var data = ''; readableStream.on('data', function(chunk) { data+=chunk; }); readableStream.on('end', function() { console.log(data); });

Writable Streams

var fs = require('fs'); var readableStream = fs.createReadStream('file1.txt'); var writableStream = fs.createWriteStream('file2.txt'); readableStream.on('data', function(chunk) { writableStream.write(chunk); });

duplex, transform streams

a.pipe(b).pipe(a) a.pipe(b).pipe(c)

Pipe

var writableModuleStream = fs.createWriteStream('module.txt'); var stream = fs.createReadStream('data.csv'); stream.on('readable', onFileRead); stream.on('end', function() { writableModuleStream.end(); }); function onFileRead() { var data = stream.read(); if (data && !writableModuleStream.write(data)) { stream.removeListener('readable', onFileRead); writableModuleStream.once('drain', function() { stream.on('readable', onFileRead); onFileRead(); }); } }

fs + http

var http = require('http'), fs = require('fs'); http.createServer(function(request, response) { if (req.method === 'POST') { fs.readFile('./data.csv', 'utf-8', function(err, data) { response.end(data); }); } else res.end('send me a POST\n'); }).listen(3000);

Async Code

  • Node-style
  • Promises (Q)
  • Async
  • Generators(ES6)

Node-style

var someModule = require('./some_module'); someModule.sum({ x: 1, y: 2 }, function(err, result) { if (err) { console.log(err); return; } console.log(result); });

Promises (Q)

var someModule = require('./some_module'); var qSum = Q.denodeify(someModule.sum); Q({ x: 1, y: 2 }) .then(qSum) .then(function(result) { console.log(result); }) .catch(function(error) { console.log(error); });

Async

var async = require('async'); var someModule = require('./some_module'); async.waterfall([ function(callback) { callback(null, { x: 1, y: 2 }); }, someModule.sum, function(result, callback) { console.log(result); }, ], function (err, result) { console.log(err); });

Generators(ES6)

var Q = require('Q'); var co = require('co'); var someModule = require('./some_module'); var qSum = Q.denodeify(someModule.sum); function* test() { try { var result = yield qSum({x: 1, y: 2}); console.log(result); } catch(err) { console.log(err); } }; co(test);

Development & Debug

  • nodemoni, pm2
  • node-inspector, --inspect-brk

Questions?