Share
Embed
The Illustrated Guide to Node.js - THAT Conference 2024
Node.js is a compelling platform for building all types of applications for startups to enterprises. Node.js strategically unites developers through the universal language of JavaScript. Or TypeScript! Why should you learn Node.js, and where do you start?
You will walk away from this fun introduction to Node.js having learned its strengths and the tools you need to be productive. We will cover a typical workflow of creating and debugging a web application. We'll also look at popular frameworks, libraries, and learning resources to give you the best start.
David Neal
July 30, 2024
Transcript
93 slides
-
Why Node.js? • Rapid innovation & delivery • Developer happiness
• Attract & retain talent • Performance “Why Node.js is Becoming the Go-To Technology in the Enterprise” – nearform.com -
Why Node.js? productivity satisfaction performance lower costs Improved results year-over-year
Node.js Foundation User Survey -
• Backend API for SPAs, Mobile apps, etc. • “Serverless”
computing • Real-time, streaming • WebSockets, push notifications • Chat, IM, social media Node.js Use Cases -
More than just backend • Automation Scripts (DevOps) • CLI
tools (compile with nexe) • Microservices • Internet of Things • Desktop Apps -
DevOps • Small footprint • Cross-platform • Event-driven • OSS
tools • Containers -
Node.js v22 • V8 12.4 • Maglev Compiler • Native
watch mode • Native WebSocket • Mascot -
Install Node.js with NVM Mac or Linux? Use nvm! https://github.com/nvm-sh/nvm
Windows? Install Windows Subsytem for Linux (WSL)! > nvm install 20 -
First Things First! > mkdir myproject > cd myproject >
npm init This utility will walk you through creating a package.json file!!... -
Install Dependencies > npm install axios > npm install !--save-dev
eslint > npm install -D eslint-config-reverentgeek -
const fs = require( "fs" ); !// Built-in Node.js module
const express = require( "express" ); !// Module installed via npm const ApiService = require( "./app/ApiService" ); !// Local module const api = new ApiService( { port: 8888 } ); module-examples.js -
const fs = require( "fs" ); !// Built-in Node.js module
const express = require( "express" ); !// Module installed via npm const ApiService = require( "./app/ApiService" ); !// Local module const api = new ApiService( { port: 8888 } ); module-examples.js -
const fs = require( "fs" ); !// Built-in Node.js module
const express = require( "express" ); !// Module installed via npm const ApiService = require( "./app/ApiService" ); !// Local module const api = new ApiService( { port: 8888 } ); module-examples.js -
const fs = require( "fs" ); !// Built-in Node.js module
const express = require( "express" ); !// Module installed via npm const ApiService = require( "./app/ApiService" ); !// Local module const api = new ApiService( { port: 8888 } ); module-examples.js -
const fs = require( "fs" ); !// Built-in Node.js module
const express = require( "express" ); !// Module installed via npm const ApiService = require( "./app/ApiService" ); !// Local module const api = new ApiService( { port: 8888 } ); module-examples.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Traditional Node-style callback api.methodWithACallback( "bacon", 42, function( err, results ) { if ( err ) { !// Do something with the error console.log( err ); return; } !// Do stuff with results for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } ); callback-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Traditional Node-style callback api.methodWithACallback( "bacon", 42, function( err, results ) { if ( err ) { !// Do something with the error console.log( err ); return; } !// Do stuff with results for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } ); callback-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Traditional Node-style callback api.methodWithACallback( "bacon", 42, function( err, results ) { if ( err ) { !// Do something with the error console.log( err ); return; } !// Do stuff with results for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } ); callback-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Promise-style callback api.methodReturningAPromise( "bacon", 42 ) .then( results !=> { for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } ) .catch( err !=> { console.log( err ); } ); promise-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Promise-style callback api.methodReturningAPromise( "bacon", 42 ) .then( results !=> { for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } ) .catch( err !=> { console.log( err ); } ); promise-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Promise-style callback api.methodReturningAPromise( "bacon", 42 ) .then( results !=> { for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } ) .catch( err !=> { console.log( err ); } ); promise-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Promise-style callback api.methodReturningAPromise( "bacon", 42 ) .then( results !=> { for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } ) .catch( err !=> { console.log( err ); } ); promise-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Async-await callback async function doTheThing() { try { const users = await api.asyncMethodReturningUsers(); const results = await api.methodReturningAPromise( "bacon", 42 ); for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } catch( err ) { console.log( err ); } } doTheThing(); async-await-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Async-await callback async function doTheThing() { try { const users = await api.asyncMethodReturningUsers(); const results = await api.methodReturningAPromise( "bacon", 42 ); for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } catch( err ) { console.log( err ); } } doTheThing(); async-await-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Async-await callback async function doTheThing() { try { const users = await api.asyncMethodReturningUsers(); const results = await api.methodReturningAPromise( "bacon", 42 ); for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } catch( err ) { console.log( err ); } } doTheThing(); async-await-example.js -
const ApiService = require( "./app/ApiService" ); const api = new
ApiService( { port: 8888 } ); !// Async-await callback async function doTheThing() { try { const users = await api.asyncMethodReturningUsers(); const results = await api.methodReturningAPromise( "bacon", 42 ); for ( let i = 0; i < results.length; i!++ ) { !// stuff!!... } } catch( err ) { console.log( err ); } } doTheThing(); async-await-example.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); !// output: 100 C is 212 F temp-example.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); !// output: 100 C is 212 F temp-example.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); !// output: 100 C is 212 F temp-example.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); !// output: 100 C is 212 F temp-example.js -
function convertToCelsius( f ) { return ( f - 32
) * ( 5 / 9 ); } function convertToFahrenheit( c ) { return ( c * ( 9 / 5 ) ) + 32; } const temp = { freezingCelsius: 0, freezingFahrenheit: 32, boilingCelsius: 100, boilingFahrenheit: 212, convertToCelsius, convertToFahrenheit }; module.exports = temp; temperature.js const t = require( "./temperature" ); const c = t.boilingCelsius; const f = t.convertToFahrenheit( c ); console.log( `${ c } C is ${ f } F` ); !// output: 100 C is 212 F temp-example.js -
import { readFile } from "node:fs/promises"; export async function readFileJson(
fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-module-example.js -
import { readFile } from "node:fs/promises"; export async function readFileJson(
fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-module-example.js -
import { readFile } from "node:fs/promises"; export async function readFileJson(
fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-module-example.js -
esm-module-example.js import { readFile } from "node:fs/promises"; export async function
readFileJson( fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-example.js import { readFileJson } from "./esm-module-example.mjs"; const baconFile = new URL( "./bacon.json", import.meta.url ); const bacon = await readFileJson( baconFile ); console.log( bacon ); -
esm-module-example.js import { readFile } from "node:fs/promises"; export async function
readFileJson( fileName ) { const text = await readFile( fileName ); const data = JSON.parse( text ); return data; } esm-example.js import { readFileJson } from "./esm-module-example.mjs"; const baconFile = new URL( "./bacon.json", import.meta.url ); const bacon = await readFileJson( baconFile ); console.log( bacon ); -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { !// log error } } sql-example.js -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { !// log error } } sql-example.js -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { !// log error } } sql-example.js -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { !// log error } } sql-example.js -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { !// log error } } sql-example.js -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { !// log error } } sql-example.js -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { !// log error } } sql-example.js -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { try { const pool = await sql.connect( cnx ); const result = await pool.request() .input( "email", sql.VarChar( 100 ), email ) .query( "select * from accounts where email = @email" ); return result; } catch ( err ) { !// log error } } sql-example.js -
const sql = require( "mssql" ); !// Read from environment
variables const cnx = process.env.SQL_CONNECTION; async function getAccountByEmail( email ) { !!... } module.exports = { getAccountByEmail }; sql-example.js -
Developer tools Package(s) Description eslint lint and format rules for
JavaScript nodemon automatically restarts in dev node:test, jest, mocha test frameworks testdouble, sinon spies, stubs, mocks -
Recommended tools Package(s) Description dotenv loads environment variables from a
.env file fs-extra adds convenient extensions to file system fetch, axios, or got http clients socket.io sockets, real-time commander command-line argument library for building CLIs nexe compile app to a standalone executable -
Integration Strategies • Node.js as proxy, use http client •
nginx • Messaging (e.g. RabbitMQ, ZeroMQ Azure Service Bus)