Node.JS

Fundamentals

We expect cooperation from all participants to help ensure a safe environment for everybody.

We treat everyone with respect, we refrain from using offensive language and imagery, and we encourage to report any derogatory or offensive behavior to a member of the JSLeague community.

We provide a fantastic environment for everyone to learn and share skills regardless of gender, gender identity and expression, age, sexual orientation, disability, physical appearance, body size, race, ethnicity, religion (or lack thereof), or technology choices.

We value your attendance and your participation in the JSLeague community and expect everyone to accord to the community Code of Conduct at all JSLeague workshops and other events.

Code of conduct

Whoami

Alexandru Albu

Trainer @JSLeague

frontend developer @8yo

design: photoshop, illustrator

development: javascript. python, sql, mongo

devops: docker

and gaming and basketball

Overview

Node.JS Fundamentals

Node.JS Fundamentals

Day 1 Agenda

Node.js Framework

Installation and setup

Modules and npm

The Callback pattern

Error handling

File System

Buffers

Streams

Day 2 Agenda

Events

Threads

ExpressJS Middlewares

Exposing publicly APIs

Data Persistency

Day 3 Agenda

Continuous communication

Securing Web APIs

Unit testing

Building the App

Ready for Production

Node.JS Fundamentals

09:30 - 10:00 Meet && Greet
10:00 - 10:30 NodeJS Framework
10:30 - 11:00 Installation && Setup
11:00 - 11:15 Short break
11:15 - 12:00 Modules && NPM
12:00 - 13:00 Lunch break
13:00 - 13:30 The Callback pattern
13:30 - 14:00 Error handling
14:00 - 14:30 File System
14:30 - 15:00 Buffers
15:00 - 15:15 Short break
15:15 - 16:15 Streams
16:15 - 17:30 Review && Q&A

Day 1

Node.JS Fundamentals

09:30 - 10:10 Events
10:10 - 11:00 Threads
11:00 - 11:15 Short break
11:15 - 11:40 ExpressJS Middlewares
11:40 - 12:00 Exposing publicly APIs (I)
12:00 - 13:00 Lunch break
13:00 - 13:20 Exposing publicly APIs (II)
13:20 - 15:00 Data persistency (I)
15:00 - 15:15 Short break
15:15 - 16:30 Data persistency (II)
16:30 - 17:30 Review && Q&A

Day 2

Node.JS Fundamentals

09:30 - 10:30 Continuous communication
10:30 - 11:15 Securing web APIs
11:15 - 11:30 Short break
11:30 - 12:00 Unit testing (I)
12:00 - 13:00 Lunch break
13:00 - 14:00 Unit testing (II)
14:00 - 15:00 Building the app
15:00 - 15:15 Short break
15:15 - 16:30 ​Ready for production
16:30 - 17:30 Review && Q&A && Goodbye's

Day 3

Node.JS Framework

Node.JS Fundamentals

Node.JS Fundamentals

Node.JS Fundamentals

Node.JS Fundamentals

Installation && Setup

Node.JS Fundamentals

Node.JS Fundamentals

Download directly from:

https://nodejs.org/en/download/

 

or download it with a package manager:

https://nodejs.org/en/download/package-manager/

 

or on unix systems via NVM:

https://github.com/nvm-sh/nvm

Node.JS Fundamentals

EXERCISE TIME : #STEP-0

Modules && NPM

Node.JS Fundamentals

Node.JS Fundamentals

What is a Module in Node.JS ?

Module in Node.js is a simple or complex functionality organized in single or multiple JavaScript files which can be reused throughout the Node.js application.

Node.JS Fundamentals

AMD

one of the most ancient module systems, initially implemented by the library require.js.

 

CommonJS

the module system created for Node.js server.

 

UMD

one more module system, suggested as a universal one, compatible with AMD and CommonJS.

Node.JS Fundamentals

// main.js
const Square = require('./square.js');
const mySquare = new Square(2);
console.log(`The area of mySquare is ${mySquare.area()}`);

// square.js
// Assigning to exports will not modify module, must use module.exports
module.exports = class Square {
  constructor(width) {
    this.width = width;
  }

  area() {
    return this.width ** 2;
  }
};

Node.JS Fundamentals

What is NPM ?

  • NPM stands for Node Package Manager
  • Online repository for open-source NodeJS projects
  • Command-line utility for the online repository

Node.JS Fundamentals

Node.JS Fundamentals

package.json

 

name

version

main

scripts

dependencies

devDependencies

license

 

https://docs.npmjs.com/files/package.json

Node.JS Fundamentals

node_modules

Node.JS Fundamentals

Node.JS Fundamentals

EXERCISE TIME : #STEP-1 && #STEP-2

The callback pattern

Node.JS Fundamentals

Node.JS Fundamentals

Node.JS async

how does it handle flow?

callbacks!!!

Node.JS Fundamentals

function processData () {
  var data = fetchData ();
  data += 1;
  return data;
}

Node.JS Fundamentals

function processData (callback) {
  fetchData(function (err, data) {
    if (err) {
      console.log("An error has occurred. Abort everything!");
      return callback(err);
    }
    data += 1;
    callback(data);
  });
}

Node.JS Fundamentals

function asyncOperation ( a, b, c, callback ) {
  // ... lots of hard work ...
  if ( /* an error occurs */ ) {
    return callback(new Error("An error has occurred"));
  }
  // ... more work ...
  callback(null, d, e, f);
}

asyncOperation ( params.., function ( err, returnValues.. ) {
  //This code gets run after the async operation gets run
});

Node.JS Fundamentals

Node.JS Fundamentals

EXERCISE TIME : #STEP-3

Error handling

Node.JS Fundamentals

Node.JS Fundamentals

Operational errors

vs.

Programming errors

Node.JS Fundamentals

Error Object

 

throw new Error(<some error here>)

Node.JS Fundamentals

NodeJS Error Classes

 

AssertionError

RangeError

SystemError

etc.

Node.JS Fundamentals

try {
  doAction(); // do some things
 	
  throw 'myException'; // generates an exception
}
catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
} finally {
  // do not break gracefully
}

try... catch... finally

Node.JS Fundamentals

const fs = require('fs');

function errorFirstCallback(err, data) {
  if (err) {
    console.error('There was an error', err);
    return;
  }
  console.log(data);
}

fs.readFile('/some/file/that/does-not-exist', errorFirstCallback);
fs.readFile('/some/file/that/does-exist', errorFirstCallback);

Error first callbacks

Node.JS Fundamentals

// THIS WILL NOT WORK:
const fs = require('fs');

try {
  fs.readFile('/some/file/that/does-not-exist', (err, data) => {
    // Mistaken assumption: throwing here...
    if (err) {
      throw err;
    }
  });
} catch (err) {
  // This will not catch the throw!
  console.error(err);
}

Node.JS Fundamentals

EXERCISE TIME : #STEP-4

File system

Node.JS Fundamentals

Node.JS Fundamentals

const fs = require('fs');

Node.JS Fundamentals

Async vs. Sync

Node.JS Fundamentals

const fs = require('fs');

fs.unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});

Async

Node.JS Fundamentals

const fs = require('fs');

try {
  fs.unlinkSync('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (err) {
  // handle the error
}

Sync

Node.JS Fundamentals

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  console.log('renamed complete');
});

fs.stat('/tmp/world', (err, stats) => {
  if (err) throw err;
  console.log(`stats: ${JSON.stringify(stats)}`);
});

Concurrency

Node.JS Fundamentals

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  
  fs.stat('/tmp/world', (err, stats) => {
    if (err) throw err;
    console.log(`stats: ${JSON.stringify(stats)}`);
  });
});

Concurrency avoided

Node.JS Fundamentals

Async doesn't mean Promise

fs.promises.<command>

Node.JS Fundamentals

EXERCISE TIME : #STEP-5

Buffers

Node.JS Fundamentals

Node.JS Fundamentals

Why?

While Node.JS works great with binary data as strings, it can sometimes have unforeseen side effects.

Buffers also give a performance improvement.

Node.JS Fundamentals

var buffer = Buffer.alloc(8);
// This will print out 8 bytes of zero:
// <Buffer 00 00 00 00 00 00 00 00>

var buffer = Buffer.from([ 8, 6, 7, 5, 3, 0, 9]);
// This will print out 8 bytes of certain values:
// <Buffer 08 06 07 05 03 00 09>

var buffer = Buffer.from("I'm a string!", "utf-8");
// This will print out a chain of values in utf-8:
// <Buffer 49 27 6d 20 61 20 73 74 72 69 6e 67 21>

Creating Buffers

Node.JS Fundamentals

// Create a size 16 empty buffer
const buffer = Buffer.alloc(16)

// Add string to buffer
buffer.write("Hello", "utf-8")
// returns 5 - number of bytes written to the buffer

// Add another string to buffer
buffer.write(" world!", 5, "utf-8")
// returns 7

Writing to Buffers

Node.JS Fundamentals

buffer.toString('utf-8')
// 'Hello world!\u0000�k\t'

buffer.toString("utf-8", 0, 12)
// 'Hello world!'

Reading from Buffers

Node.JS Fundamentals

EXERCISE TIME : #STEP-6

Streams

Node.JS Fundamentals

Node.JS Fundamentals

What are Streams?

Streams are objects that let you continuously work with data.

Node.JS Fundamentals

Types of Streams:

Writable: streams to which data can be written

Readable: streams from which data can be read

Duplex: streams that are both Readable and Writable

Transform: Duplex streams that can modify or transform the data as it is written and read

Node.JS Fundamentals

const readable = getReadableStreamSomehow();

// When receiving data
readable.on('data', (chunk) => {
  console.log(`Received ${chunk.length} bytes of data.`);
});

// End event
readable.on('end', () => {
  console.log('There will be no more data.');
});

Readable Streams

Node.JS Fundamentals

const myStream = getWritableStreamSomehow();

myStream.write('some data');
myStream.write('some more data');

myStream.end('done writing data');

Writable Streams

Node.JS Fundamentals

EXERCISE TIME : #STEP-7

Events

Node.JS Fundamentals

Node.JS Fundamentals

Much of Node.JS architecture is build around Events.

Event driven architecture

Node.JS Fundamentals

const EventEmitter = require('events');

// create a new event emitter
const myEmitter = new EventEmitter();

// listening to an event
myEmitter.on('customEvent', () => {
  console.log('customEvent was received!')
})

// firing an event
myEmitter.emit('customEvents')

Working with Events

Node.JS Fundamentals

const EventEmitter = require('events');

// create a new event emitter
const myEmitter = new EventEmitter();

// listening to an event
myEmitter.on('customEvent', (...params) => {
  console.log('customEvent was received!')
  console.log('we also have params: ', params)
})

// firing an event
myEmitter.emit('customEvents', "value1", {"value2": 2});

Sending params

Node.JS Fundamentals

const EventEmitter = require('events');

// create a new event emitter
const myEmitter = new EventEmitter();

// listening to an event async
myEmitter.on('customEvent', () => {
  console.log('customEvent was received async!')
})

// listening to an event sync
myEmitter.on('customEvent', () => {
  setImmediate(() => {
   	console.log('customEvent was received sync!')
  });
})

// firing an event
myEmitter.emit('customEvent');

Async vs Sync

Node.JS Fundamentals

const EventEmitter = require('events');

// create a new event emitter
const myEmitter = new EventEmitter();

// listening to an event
myEmitter.once('customEvent', () => {
  console.log('customEvent was received!')
})

// firing an event
myEmitter.emit('customEvent');

myEmitter.emit('customEvent');

myEmitter.emit('customEvent');

myEmitter.emit('customEvent');

Handling events once

Node.JS Fundamentals

const EventEmitter = require('events');

// create a new event emitter
const myEmitter = new EventEmitter();

// listening to an event
myEmitter.on('error', (err) => {
  console.error(err)
})

// firing an event
myEmitter.emit('error', new Error());

Handling error events

Node.JS Fundamentals

const EventEmitter = require('events');
const express = require('express')

const eventEmitter = new EventEmitter();

const app = express();

// set event emitter on express app
app.set('eventEmitter', eventEmitter);

// access it from any module of the application
console.log(app.get('eventEmitter'));

ExpressJS Event handling

Node.JS Fundamentals

EXERCISE TIME : #STEP-8

Threads

Node.JS Fundamentals

Node.JS Fundamentals

JavaScript by design is single threaded.

Node.JS Fundamentals

const {
  Worker, isMainThread, parentPort, workerData
} = require('worker_threads');

if (isMainThread) {
  module.exports = function parseJSAsync(script) {
    return new Promise((resolve, reject) => {
      const worker = new Worker(__filename, {
        workerData: script
      });
      worker.on('message', resolve);
      worker.on('error', reject);
      worker.on('exit', (code) => {
        if (code !== 0)
          reject(new Error(`Worker stopped with exit code ${code}`));
      });
    });
  };
} else {
  const { parse } = require('some-js-parsing-library');
  const script = workerData;
  parentPort.postMessage(parse(script));
}

Node.JS Fundamentals

EXERCISE TIME : #STEP-9

ExpressJS Middlewares

Node.JS Fundamentals

Node.JS Fundamentals

Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.

Node.JS Fundamentals

Call the next middleware function in the stack.

End the request-response cycle.

Make changes to the request and the response objects.

Execute any code.

Node.JS Fundamentals

Application level

Router level

Third party

Built-in

Error handling

Node.JS Fundamentals

var express = require('express')
var app = express()

app.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})

app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
})

app.use('/user/:id', function (req, res, next) {
  console.log('Request URL:', req.originalUrl)
  next()
}, function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
})

Application level

Node.JS Fundamentals

var express = require('express')
var app = express()
var router = express.Router()

// a middleware function with no mount path. 
// This code is executed for every request to the router
router.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})

// a middleware sub-stack shows request info 
// for any type of HTTP request to the /user/:id path
router.use('/user/:id', function (req, res, next) {
  console.log('Request URL:', req.originalUrl)
  next()
}, function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
})

Router level

Node.JS Fundamentals

var express = require('express')
var app = express()

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

Error handling

Node.JS Fundamentals

Built-in

  • express.static serves static assets such as HTML files, images, and so on.
  • express.json parses incoming requests with JSON payloads.
  • express.urlencoded parses incoming requests with URL-encoded payloads.

Node.JS Fundamentals

var express = require('express')
var app = express()
var cookieParser = require('cookie-parser')

// load the cookie-parsing middleware
app.use(cookieParser())

Third party

Exposing publicly APIs

Node.JS Fundamentals

Node.JS Fundamentals

var express = require('express')
var app = express()

// respond with "hello world" when a GET request is made to the homepage
app.get('/', function (req, res) {
  res.send('hello world')
})

Basic route

Node.JS Fundamentals

var express = require('express')
var app = express()

// GET method route
app.get('/', function (req, res) {
  res.send('GET request to the homepage')
})

// POST method route
app.post('/', function (req, res) {
  res.send('POST request to the homepage')
})

Route methods

Node.JS Fundamentals

app.get('/', function (req, res) {
  res.send('root')
})

app.get('/about', function (req, res) {
  res.send('about')
})


app.get('/ab*cd', function (req, res) {
  res.send('ab*cd')
})

app.get('/ab(cd)?e', function (req, res) {
  res.send('ab(cd)?e')
})

app.get(/.*fly$/, function (req, res) {
  res.send('/.*fly$/')
})

Route paths

Node.JS Fundamentals

app.get('/users/:userId/books/:bookId', function (req, res) {
  res.send(req.params)
})

Route params

Node.JS Fundamentals

Response methods

Method Description
res.download() Prompt a file to be downloaded.
res.end() End the response process.
res.json() Send a JSON response.
res.jsonp() Send a JSON response with JSONP support.
res.redirect() Redirect a request.
res.render() Render a view template.
res.send() Send a response of various types.
res.sendFile() Send a file as an octet stream.
res.sendStatus() Set the response status code and send its string representation as the response body.

Node.JS Fundamentals

app.route('/book')
  .get(function (req, res) {
    res.send('Get a random book')
  })
  .post(function (req, res) {
    res.send('Add a book')
  })
  .put(function (req, res) {
    res.send('Update the book')
  })

app level router

Node.JS Fundamentals

var express = require('express')
var router = express.Router()

// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
  console.log('Time: ', Date.now())
  next()
})
// define the home page route
router.get('/', function (req, res) {
  res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
  res.send('About birds')
})

module.exports = router

router module

Data persistency

Node.JS Fundamentals

Node.JS Fundamentals

Node.JS Fundamentals

ORMs

Node.JS Fundamentals

Sequelize connection

const { Sequelize } = require('sequelize');

// Option 1: Passing a connection URI
const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname') 
// Example for postgres

// Option 2: Passing parameters separately
const sequelize = new Sequelize({
  dialect: 'postgres',
  storage: 'path/to/database.sqlite'
});

// Option 2: Passing parameters separately (other dialects)
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'postgres'
});

Node.JS Fundamentals

Sequelize test connection

try {
  await sequelize.authenticate();
  console.log('Connection has been established successfully.');
} catch (error) {
  console.error('Unable to connect to the database:', error);
}

Node.JS Fundamentals

Sequelize model

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:');

const User = sequelize.define('User', {
  // Model attributes are defined here
  firstName: {
    type: DataTypes.STRING,
    allowNull: false
  },
  lastName: {
    type: DataTypes.STRING
    // allowNull defaults to true
  }
}, {
  // Other model options go here
});

// `sequelize.define` also returns the model
console.log(User === sequelize.models.User); // true

Node.JS Fundamentals

Sequelize queries

// Create a new user
const jane = await User.create({ firstName: "Jane", lastName: "Doe" });
console.log("Jane's auto-generated ID:", jane.id);

// Find all users
const users = await User.findAll();

// Where clauses
const users = await UserfindAll({
  where: { lastName: "Doe" }
})

// Operators
const { Op } = require("sequelize");
Users.findAll({
  where: {
    [Op.and]: [
      { firstName: "Jane" }, { lastName: "Doe" }
    ]
  }
});

Node.JS Fundamentals

Mongoose connection

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/test');

Node.JS Fundamentals

Mongoose test connection

const mongoose = require('mongoose');

// mongoose module is singleton
console.log(mongoose.connection.readyState);

Node.JS Fundamentals

Mongoose model

const mongoose = require('mongoose');

const schema = new mongoose.Schema({ 
  firstName: 'string', 
  lastName: 'string' 
});

// // The first param defines also the collection name
const User = mongoose.model('User', schema);

Node.JS Fundamentals

Mongoose queries

const mongoose = require('mongoose');

// Create a user
var jane = new User({ firstName: 'Jane', lastName: 'Doe' });
jane.save(function (err) {
  if (err) return handleError(err);
  // saved!
});

User.create({ firstName: 'Jane', lastName: 'Doe' }, function (err, small) {
  if (err) return handleError(err);
  // saved!
});

Tank.insertMany([{ lastName: 'Doe' }], function(err) {
	// handle error here
});

// Find a user
User.find({ lastName: 'Doe' })
  	.where('createdDate')
  	.gt(oneYearAgo)
  	.exec(callback);

Node.JS Fundamentals

EXERCISE TIME : #STEP-10

Continuous communication

Node.JS Fundamentals

Node.JS Fundamentals

The WebSocket API is an advanced technology that makes it possible to open a two-way interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply.

Node.JS Fundamentals

WebSocket

Node.JS Fundamentals

const socket = new WebSocket('ws://localhost:3000');

socket.onopen(() => {
  socket.send('Hello!');
});

socket.onmessage(data => {
  console.log(data);
});

WebSocket connection

Node.JS Fundamentals

const socket = io('ws://localhost:3000');

socket.on('connect', () => {
  // either with send()
  socket.send('Hello!');

  // or with emit() and custom event names
  socket.emit('salutations', 'Hello!', { 'mr': 'john' });
});

// handle the event sent with socket.send()
socket.on('message', data => {
  console.log(data);
});

// handle the event sent with socket.emit()
socket.on('greetings', (elem1, elem2, elem3) => {
  console.log(elem1, elem2, elem3);
});

socket.io connection client

Node.JS Fundamentals

const io = require('socket.io')(3000);

io.on('connect', socket => {
  // either with send()
  socket.send('Hello!');

  // or with emit() and custom event names
  socket.emit('greetings', 'Hey!', { 'ms': 'jane' });

  // handle the event sent with socket.send()
  socket.on('message', (data) => {
    console.log(data);
  });

  // handle the event sent with socket.emit()
  socket.on('salutations', (elem1, elem2, elem3) => {
    console.log(elem1, elem2, elem3);
  });
});

socket.io connection server

Node.JS Fundamentals

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});

express.js with socket.io

Node.JS Fundamentals

EXERCISE TIME : #STEP-11

Securing web APIs

Node.JS Fundamentals

Node.JS Fundamentals

Why?

Node.JS Fundamentals

helmet

npm install --save helmet

Middleware collection of security headers

Node.JS Fundamentals

const express = require("express");
const helmet = require("helmet");

const app = express();

// This...
app.use(helmet());

// ...is equivalent to this:
app.use(helmet.contentSecurityPolicy());
app.use(helmet.dnsPrefetchControl());
app.use(helmet.expectCt());
app.use(helmet.frameguard());
app.use(helmet.hidePoweredBy());
app.use(helmet.hsts());
app.use(helmet.ieNoOpen());
app.use(helmet.noSniff());
app.use(helmet.permittedCrossDomainPolicies());
app.use(helmet.referrerPolicy());
app.use(helmet.xssFilter());

using helmet

Node.JS Fundamentals

secure cookies

npm install --save express-session cookie-session

Session storage in production is best done with a database provider

Node.JS Fundamentals

whitelisting

npm install --save cors

Requests origin white/black listing

Node.JS Fundamentals

const express = require('express')
const cors = require('cors')

const app = express()

app.use(cors())

using cors

Node.JS Fundamentals

audit

npm audit

NodeJS tool to check for security vulnerabilities

Node.JS Fundamentals

Node.JS Fundamentals

EXERCISE TIME : #STEP-12

Unit testing

Node.JS Fundamentals

Node.JS Fundamentals

Node.JS Fundamentals

// Load express module with `require` directive
const express = require('express')
const app = express()

// Define request response in root URL (/)
app.get('/', function (req, res) {
  res.send('Hello World')
})

// Launch listening server on port 8080
app.listen(8080, function () {
  console.log('App listening on port 8080!')
})

Basic Express App

Node.JS Fundamentals

const chai = require('chai');
const chaiHttp = require('chai-http');
const app = require('../app.js');

const expect  = chai.expect;

chai.use(chaiHttp)

it('Should fetch data', (done) => {
    chai.request(app)
	.get('/')
	.end((err, res) => {
	    if(err) done(err);
      		
	    expect(res).to.have.status(200);
	    expect(res).to.be.an('object');
	    expect(res.body).to.deep.equals('Hello World');
	})
});

Basic test

Node.JS Fundamentals

// package.json
"scripts": {
  "test": "mocha ./**/*.test.js"
}

// terminal
npm test

Running tests

Node.JS Fundamentals

EXERCISE TIME : #STEP-13

Building Node.JS applications

Node.JS Fundamentals

Node.JS Fundamentals

Node.JS Fundamentals

const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  }
};

webpack simple configuration file

Node.JS Fundamentals

const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')

module.exports = {
  entry: {
    server: './app.js',
  },
  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/',
    filename: '[name].js'
  },
  target: 'node',
  node: {
    // Need this when working with express, otherwise the build fails
    __dirname: false,   // if you don't put this is, __dirname
    __filename: false,  // and __filename return blank or /
  },
  externals: [nodeExternals()], // Need this to avoid error when working with Express
}

webpack express configuration file

Node.JS Fundamentals

EXERCISE TIME : #STEP-14

Production ready

Node.JS Fundamentals

Node.JS Fundamentals

Set NODE_ENV=production

Add gzip with compression

Availability through pm2

Dockerize delivery

Node.JS Fundamentals

EXERCISE TIME : #STEP-15

Q&A

Node.JS Fundamentals

Thank you!