Intro to Nodejs

Scott Moss

Frontend Masters

What is Nodejs?

  • Open source runtime
  • Built on Chrome's V8 JavaScript engine
  • Created by Ryan Dhal in 2009
  • Evolved since creation to allow developers to build almost anything

tldr; Environmentย to run JavaScript outside a browser

What can I create with Nodejs?

  • Tooling (build, automation, etc)
  • API's (REST, Realtime, etc)
  • CDNs
  • Shareable libraries
  • Desktop applications ๐Ÿ’ฏ๐Ÿ˜Ž๐ŸŽ‰๐Ÿ‘Œ๐Ÿพ
  • IOT
  • Pretty much anything because node is on everything now

tldr; Pretty much anything a scripting and server language like python or ruby can, but with JavaScript

Installing Nodejs

From Nodejs source

  • the easiest way to install
  • limits your options for have many versions of Nodejs
  • Can cause permission errors

tldr; Use NVM

Using NVM (node version manager)

  • recommended
  • allows you to run many versions of Node whenever

Running Nodejs code

Interactive REPL

  • Great for trying things out, think console on the browser
  • Just type the node command with no args and begin

tldr; REPL for playing around, cli for everything else

CLI Executable

  • Use to execute your node apps

ย 

node path/to/your/file.js

Exerciseย 1

  1. โœ… install Nodejs on your machine
  2. โœ… Verify your installation
  3. โœ… Use the Node REPL and write some JavaScriptย 
  4. โœ… Use the node CLI executable against a .js fileย 

Browser vs Nodejs

Browser

Nodejs

  • Build Interactive apps for the web
  • DOM
  • Window
  • Fragmentation
  • optional modules (es6)
  • Cannot access filesystem
  • Async
  • Build server side apps and scripts
  • Nope, no GUI (can virtualize)
  • No window, but does have a global
  • Versioned, so no fragmentation
  • Required modules (commonjs +)
  • Can access filesystem
  • Async
  • No browser based APIs

Globals

  • process - has information about the environment the program is running in

  • requireย - function to find and use modules in current module

  • __dirname - the current directory path

  • module - information about current module, methods or making module consumable

  • global - like window, its the "global" object. Almost NEVER use this

  • .... many more

tldr; Nodejs gives you helpful globals, but just like the browser, you should not create your own

What are modules?

tldr; Encapsulated code


var module1 = (function(exports, require, module, __filename, __dirname){
  // your node js code in a file
})

var module2 = (function(exports, require, module, __filename, __dirname){
  // your node js code in another file
})

Modules in Nodejs

NodeJs uses commonJs for its module system.

tldr; CommonJs

There are other module systems out there like:

  • ESM (ecmascript modules) *new standard
  • AMD (pretty much dead)
  • ... others, but don't matter at all

Creating modules

All your Nodejs code are modules.

tldr; Regular code, just export it

As the author, you decide how and what to expose from your modules, to other modules.

You do this with the module global object provided you by the Nodejs runtime

Using modules

The Nodejs runtime injects another global, require.

tldr; require

This function takes a relative path to the module that you want to consume, and synchronously loads it by returning whatever the target module exported.

Exerciseย 2

  1. โœ… fork the repo
  2. โœ… check out to start branch
  3. โœ… check the README on how to run test (will talk later about that command)
  4. โœ… fix and convert the 3 js files in the exercises/modules/browser to Nodejs JavaScript and place them in exercises/modules/node
  5. โœ… ensure all tests pass by running test command again

Shipped modules

  • fs - fileSystem module to interacting with files on a machine
  • http - low level-ish module for creating network based programs, like APIs
  • path - useful for manipulating path strings and handling differences across many OS's
  • ... many more

tldr; Nodejs ships with a bunch of helpful modules already

Remote modules

Nodejs has grown a bunch, and a bunch of that growth is due to its community and the ability to share modules and consume them at will.ย 

tldr; download and use other modules from the internets ๐Ÿ™€

You can slap together an app really fast by reusing public modules. Which are the same as the modules you make, but packaged for downloading

This sounds nice, but now you have to be aware of malicious code. Also, you need a system to help with the management of remote modules (downloading, publishing, updating, etc)

Three module types, one require

Custom local modules

tldr; modules you created are always relative paths. ".js" is implied

var lib = require('../rel/path/to/lib') // Always have to use a "." first

Remote modules

var lib = require('lib') // the same name you used to install it with npm

Shipped modules

var fs = require('fs') // internal module, remote module with same name takes it

NPM

  • Ships with Nodejs
  • Allows you to publish, download, and update modules
  • Uses package.json file in your Nodejs project to determine dependencies
  • Stores remote modules in the node_modules folder
  • ... whole bunch of other stuff
  • oh, there are other tools that aim to do the same, arguably better too ๐Ÿš€

tldr; CLI to manage remote modules

Exerciseย 3

  1. โœ… checkout to start branch
  2. โœ… install all remote modules (hint: use npm)
  3. โœ… Check the README on how to run your CLI
  4. โœ… Fix the CLI so that the "new" command works by saving contacts to contacts.json
  5. โœ… Fix the CLI so that the "list" command works by listing all contacts and allowing you to select one, the prints out the selected contact

You'll be creating a CLI program that saves and retrieves contacts from and address book. The program is partially there, however, you must install some remote modules, and use the fileSystem to get some things to work.

Async code

Nodejs is single threaded and event based. Just like the browser.ย 

tldr; Nodejs is single threaded and async like the browser, but you'll probably do more async things

Unlike the browser, your nodejs app will be shared by all clientsย 

You now have consider CPU intensive tasks that block the single thread (while loops)

Async patterns

callback pattern

tldr; async / await is legit

// callback takes error as first arg, and result as second
doAsyncThing((error, result) => {})

promises

doAsyncThing()
  .then(result => {})
  .catch(error => {})

async / await

const run = async () => {
  const results = await doAsyncThing() // must return a promise
  console.log('hello')
}

Error handling

Any thrown or unhandled errors will cause the process to crash and exit

tldr; Errors kill your app, just like the browser

Your app may have errors that should not cause a crash, so you must handle accordingly

Servers

A server's job is to handle a request from some sor of client (browser, mobile app, another server, etc)

tldr; one server, handling many requests from clients

Without considering scaling, one server instance will handle many client requests. Compared to a client app where that code only cared about itself on the host machine

Nodejs has built in and community packakes for build all types of servers (API's, static, realtime. etc)

Exerciseย 4

  1. โœ… install all remote modules (hint: use npm)
  2. โœ… Check the README on how to run your server
  3. โœ… refactor the sync file reading code to be async with a callback, promise, or async await
  4. โœ… prevent the server from crashing when an assets is not found. Instead, respond with a 404 status code
  5. โœ… create some sort of router logic to handle incoming requests for assets

    ย 

You'll be refactoring and fixing a simple static asset server. The server uses blocking sync code and crashes whenever a request comes in that is asking for an asset that is not found. Neither of those are desirable. You'll also have to teach the server how to server the assets it has in the assets folder.

ย 

Debugging

Level 1

Use console.log to log your way through fixing your app. In production, record your logs

tldr; just like chrome

Level 2

Use the node inspector when starting your app and debug just like you would an browser app in chrome

Level 3

Text editor integration offers the most seamless experience.

Testing

Before you can test your code, make sure it is testable. As long as you can export what you want to test, you should be able to test it. There are other concerns specific to what libraries and frameworks you use

tldr; export your modules and use a testing framework

You can test pretty much anything in Nodejs. Browser apps, API's, CLI's, scripts, tools, etc. Your test themselves will be executed in Nodejs, so they have the ability to pretty much do anything.

Anatomy of tests

  • Your code to be tested
  • Test Suite - responsible for helping organize your tests, provide hooks, and overall environment
  • Assertion library - does the actual comparisons in your test
  • Mocks + Spies - tools to help you test your code without testing other code or actually running your code (mock out api calls, check to see if an internal function was called)

tldr; many tools for the same job

Types of tests

  • unitย 
  • integration
  • end-to-end
  • UI
  • snapshot
  • performance
  • ... so many more

tldr; everything can be tested with node

Exerciseย 5

  1. โœ… checkout to start branch
  2. โœ… check the README on how to execute this program and run test
  3. โœ… there are 3 bugs, find them and fix them
  4. โœ… write some unit test with Jest to make sure those bugs stay fixed. Refactor the code if you have to

You have to debug and track down some issues in a small app. Use your logging and inspector to find them. Try and fix them, once you do, write some test to make sure it stays fixed ๐Ÿ‘Œ๐Ÿพ๐Ÿ˜Ž๐Ÿ’ฏ

Sharing modules

Sharing your modules are easy. Just a few things you have to check:

tldr; push code to github, publish to NPM

  • add node_modules to gitignore
  • declare remote modules as devDependencies if you only need them to develop with (jest)
  • think about how your app will be used and what dependencies the host app might have, you don't want to include another version (although NPM tries to fix this for you)
  • is this private or public?

Deploying your servers

Each cloud provider has is own method of deploying your apps on their platforms. Most of them have some integration with Github or a CLI to assist.

tldr; follow cloud provider instructions, and never hard code secrets

Few things to remember

  • remove secrets and use environment vars
  • setup a CI flow for your app
  • make sure you are developing with the same version of node your are deploying to

Exerciseย 5

Deploy one of the exercises to heroku (server) or npm (cli)

Made with Slides.com