Node.js

Node.js provides server-side functionality in familiar Javascript syntax and an asynchronous model. To be clear, Node.js is not a programming language. It adds features to Javascript that allow developers to write server-side code in familiar front-end language.

If you've already learned some Node in the past, GitHub's Learning Lab Intermediate NodeJS Course might be worth a try.

How It Works

As an interpreted language (like Python), Javascript requires a runtime engine to be run. How Node js functions as a server side language is its runtime engine allows it to interact with a server. In the browser, a Javascript engine provides access to Web Platform APIs and the window HTML (DOM). Node uses Google's V8 Javascript engine instead to access files, send data, and provide other server capabilities. The V8 engine powers Chrome, but there are other engines out there:

  1. Firefox uses SpiderMonkey
  2. Safari uses JavaScriptCore
  3. IE uses who on 🌍 cares

The Chrome V8 Javascript engine provides C++ bindings for Javascript. The V8 Engine then passes events and data between the server and client.

Let's take a small example. Javascript has no concept of accessing system files, but in Node.js, we gain this functionality through modules. We'll get to modules later, but here's a small example of what you can do with Node.js using the built in filesystem module fs.

Alternatively, you can run this in the node console. In your terminal, typing node creates a shell utilizing a Read Evaluate Print Loop (REPL)

What this means is that as expressions are evaluated, their return value is printed in the console. You can invoke the REPL by just typing node in your terminal. Then, you can test what expressions are doing. Which is useful for debugging expressions and playing around with Javascript.

/* Enter the number 4, then press enter */
4 // <Enter>
++_ // Increment the previous expression by 1

You'll notice that the return value is printed below each statement executed:

v = "Vim"
// => 'Vim'
e = "Emacs"
// => 'Emacs'
console.log("I'm a pro since I use ", v)
// => I'm a pro since I use Vim

You can exit the REPL by pressing ^D or ^C^C.

The process variable, only accessible to you in Node, not in the browser. process is a list of current tasks that Node is executing.

Module System

Modules in Nodejs are essentially Javascript libraries. There are quite a few built-in libraries available by default in Nodejs, including (thanks to W3 Schools for the rundown):

Name Description
assert Provides a set of assertion tests
buffer To handle binary data
child_process To run a child process
cluster To split a single Node process into multiple processes
crypto To handle OpenSSL cryptographic functions
dgram Provides implementation of UDP datagram sockets
dns To do DNS lookups and name resolution functions
domain Deprecated. To handle unhandled errors
events To handle events
fs To handle the file system
http To make Node.js act as an HTTP server
https To make Node.js act as an HTTPS server.
net To create servers and clients
os Provides information about the operation system
path To handle file paths
punycode Deprecated. A character encoding scheme
querystring To handle URL query strings
readline To handle readable streams one line at the time
stream To handle streaming data
string_decoder To decode buffer objects into strings
timers To execute a function after a given number of milliseconds
tls To implement TLS and SSL protocols
tty Provides classes used by a text terminal
url To parse URL strings
util To access utility functions
v8 To access information about V8 (the JavaScript engine)
vm To compile JavaScript code in a virtual machine
zlib To compress or decompress files

Package management with NPM

The Node Package Manager (NPM) is the default package manager for Node.js. It has a very frequently used command.

--save yourself the effort

If you see a line like the one below in package documentation, ignore the --save argument. It does nothing. It used to do something, but it doesn't anymore.

npm install PACKAGE --save

Before NPM v5.0.0, it was necessary to add --save after package name because it will save the installed package to package.json file in the dependency section. If you are using a recent version of NPM, save yourself some effort, and just type

npm install PACKAGE

By default, npm will now add the installed package to the dependency list in the package.json file.

To learn more, visit the official npm install documentation.

Killing the fund

As of npm version 6.13.0, npm now displays this message after installing a package usingnpm install:

13 npm install packages are looking for funding run `npm fund` for details

If you support the JavaScript community in other ways (such as by making a wiki), you may prefer not to see this message every single time you install a package using npm. To remove it, you could include a --no-fund flag every time you run npm install, but it's easier to add it to your config file.

This will add fund=false to your ~/.npmrc(https://docs.npmjs.com/files/npmrc) file, preventing you from seeing the message in future package installations.

Importing Modules

The best documentation to learn more about module imports is the Typescript article Modules

The Core

Nodejs requires a few critical components that allow it to provide its functionality. These objects are part of what separate Nodejs applications from vanilla Javascript code:

1. Global Objects
2. Timer Methods
3. Sockets and Streams
4. Utilities
5. Events

Global Objects

There are three primary global objects available in Nodejs. They are:

  1. global
  2. process
  3. Buffer

Each of these objects are in a Node application's namespace, meaning a require statement is not required (bad pun intended).

Variables and required objects are accessible within the application's namespace. This access is restricted to the variables within the application, meaning you are unable to change the value of variables in other other modules. This prevents accidental collisions when code from another module runs.

The process object provides access to the Node installation, the three methods of standard I/O (stdin, stderr, stdout), and application memory usage.

The Buffer object handles binary data. You can read any type of data through a buffer, including a file, input stream, or network connection. A Buffer object take up to two parameters:

Timers

Timers in Nodejs allow programmers to delay and schedule execution of functions. The timer module includes the functions:

Sockets and Streams

There are four major types of streamed connections in Nodejs:

  1. TCP - net module
  2. HTTP - http module
  3. UDP/Datagram Socket - dgram module
  4. Readline/Child_Process - readline, child_process modules

Using a TCP connection, we can recieve messages from client's standard input on the server program. The process is used directly here to access standard I/O streams.

Working with I/O

The .pipe(<stream>) is used to send the ouput of one stream to another.

Reading and Writing

Node's documentation has a great article about reading files

The readline module allows the reading of standard I/O streams line by line during program execution. When the programmer is done reading a stream, they must be closed. The REPL is implemented by piping your terminal input stdin, executing Javascript commands and piping stdout back to your terminal.

Using system streams with child_process

Using the child_process module, a Node application can make system calls and recieve input from standard I/O. We do this in Node by defining a child process and redirecting its input and output by defining functions for whenever specific input is recieved.

For example, let's take the command ls:

You can specify how the function interacts with I/O by using the .on() method

Specifying how ls() interacts with stdin, stdout, and stderr:

ls.stdout.on('data', (data) => {
  console.log(`The output of ls is ${data}`)
})

ls.stderr.on('data', (data) => {
  console.log(`ls exited with error ${data}`)
})

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`)
}

The program below illustrates an elaborate way to execute the command: ls | grep "fork"

Utilities

The utilities object enables inheritance in Node. An object can be inherited by another object using the inherits function:

util.inherits(<source-object>, <target-object>)

Events & EventEmitter

As mentioned previously, event based programming is fundamental to the Node philosophy. The events module allows programmers to define actions for events much like try/catch blocks in Java and C++ or try/except blocks in Python. This method of programming puts the programmer in an event driven mindset to focus on all the events that a program must handle. Node modules are written to minimize the amount of boilerplate code written and shift focus to the actions.

Here are the steps to define an event:

  1. require: require('events')
  2. instantiate
  3. define the callback
  4. define the event

JavaScript

Data Types

JavaScript has primitive data types, which are immutable

  1. Number
  2. String
  3. Boolean
  4. Null
  5. Undefined
  6. Symbol

JavaScript also has some built-in objects

  1. Array
  2. Date
  3. RegExp
  4. Map & WeakMap
  5. Set & WeakSet

Specifying Integer Type

Number Properties

Special Characters

Code Description
\n newline
\r carriage return
\t horizontal tab
\' single quote
\$ dollar sign
\\ back-slash
\b backspace
\f form feed
\v vertical tab
&grave; grave symbol

String Substitutions

null and undefined

Objects

UTF-8

A variable can be defined using normal letters, as well as UTF-8 characters

Arrow Functions

Arrow functions allow us to give a function an identifier.

// Create a function 'squareIt' accepting an input 'x' and returning 'x' squared
const squareIt = (x) => x * x

// After 'squareIt' has been written, we can now call the identifier and give it input
squareIt(10) // '100'

Equality '==' vs. '==='

The identity operator === will compare both types and values between two variables. JavaScript objects are compared by reference, not by value. An object is equal to itself, but not equal to a different object with the same value.

It's really complicated so keep that link under your pillow, you'll need it, trust me.

There are also some edge cases worth noting:

JavaScript Arrays

The Mozilla Javascript Documentation for Arrays will explain it better than I can.

The "in" operator

The in operator evaluates to true if the left-side value is the name of a property of the right-side object. This results in some counterintuitive logic at times, an example is provided below:

// Arrays
let trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']
0 in trees        // returns true (array index 0 exists)
3 in trees        // returns true (array index 3 exists)
6 in trees        // returns false (array index 6 does not exist)
'bay' in trees    // returns false (you must specify the index number, not the value at that index)
'length' in trees // returns true (length is an Array property)
Symbol.iterator in trees // returns true (arrays are iterable, works only in ES2015+)

// Predefined objects
'PI' in Math          // returns true

// Custom objects
let mycar = {make: 'Honda', model: 'Accord', year: 1998}
'make' in mycar  // returns true
'model' in mycar // returns true
const data = [7, 8, 9]
"0" in data // true: array has an element "0"
1 in data // true: numbers are converted into strings
7 in data // false: no 7th element in this array

GitHub Package Registry

Add the following two lines to your ~/.npmrc

//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
registry = https://npm.pkg.github.com

Add the read:packages and write:packages permissions to your GITHUB_TOKEN environment variable in the GitHub tokens page

Install a Package

To add this Package registered on the GitHub NPM Registry, enter the following command

npm install @codertocat/hello-world-npm

Alternatively, you can add the package as a dependency to the project's package.json

{
  "name": "testjs",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "@codertocat/hello-world-npm": "^1.0.2"
  }
}

Publish a Package

Add the following to your package's package.json

{
  "publishConfig": {
    "registry":"https://npm.pkg.github.com/"
  }
}

Files

Express

The base place to learn Express is the GitHub Learning Lab Introduction to Node with Express

And you're done! You're now hosting a website over HTTPS 🥳

MongoDB


The crypto package

Utility functions for cryptography exist in JavaScript, but they're rather poorly documented. Neither "Learning JavaScript" or "JavaScript: The Definitive Guide" referenced this package even once in the collective 2,000 pages between the two of those books. A bit odd, maybe I'll find out why one day and post an update here.

Hashes

In the future, I want to explore how to use the Cipher and ### Verify classes, as well as the methods below:

Subcommands

prefix

Print the local prefix

npm prefix

/Users/tommy/Developer/project

You can use npm prefix -g to print the local prefix to standard out.

Source: The official npm documentation