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:

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
one of the most ancient module systems, initially implemented by the library require.js.
the module system created for Node.js server.
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

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!

Node.js Fundamentals
By Alex Albu
Node.js Fundamentals
- 619