Skip to content

Instantly share code, notes, and snippets.

@jim-clark
Last active October 17, 2020 06:10
Show Gist options
  • Save jim-clark/057ea10528823b9eccc2d1040b5c857f to your computer and use it in GitHub Desktop.
Save jim-clark/057ea10528823b9eccc2d1040b5c857f to your computer and use it in GitHub Desktop.

Click to view this presentation.




Intro to Node.js


Learning Objectives


  • Explain the Use Case for Node.js

  • Use Node.js to Execute JavaScript

  • Create and Use Node Modules

  • Use NPM to Install External Packages


Roadmap


  • Setup
  • What is Node.js?
  • Why the Enthusiasm for Node.js?
  • Using Node to Execute JavaScript
  • Node Modules
  • Our First Module
  • NPM - Node Package Manager
  • Essential Questions
  • Node.js Module Practice

Setup


  • Get inside of today's folder in the class repo, then:

     $ mkdir first-node
     $ cd first-node
     $ touch main.js
     $ code .

What is Node.js?



What is Node.js?


  • Node.js is a runtime environment for executing JavaScript outside of the browser!

  • Created in 2009 by Ryan Dahl with Joyent, Inc.

  • Uses the same V8 JavaScript Engine used in the Chrome browser to compile JS programs into machine code.


What is Node.js?


  • Node's runtime environment for JS is different than that in the browser, primarily because:

    • It doesn't have a browser's DOM or Web APIs.
    • Node has low-level networking and file system APIs that browser JS does not (for security reasons).
  • In addition to being used to build high-performance web applications, Node is also a great tool for building command-line tools.


What is Node.js?


  • Node is an open source project governed by the Node.js Foundation with board representation from companies such as:
    • PayPal
    • Microsoft
    • Google
    • GoDaddy
    • IBM
    • Red Hat
    • Intel

What is Node.js?


  • Node is very "lightweight", i.e., only low-level "core" modules for networking, filesystem access, etc. are baked-in.

  • Node's functionality is extended via open source libraries called packages.

  • Node's package ecosystem is the largest open source ecosystem in the world.


Node's REPL


  • REPL is an acronym for Read-Evaluate-Print-Loop.

  • Programming languages such as Python and Ruby also have REPLs.

  • To start Node's interactive REPL we just type node in Terminal.


Node's REPL

  • In the REPL we can write JS and even load Node modules, which we're going to learn about in this lesson:

     > 10 + 5
     15
     > function sayHello() {
     ... console.log('Hello');
     ... }
     undefined
     > sayHello()
     Hello
     undefined
     > const http = require('http');
     undefined
     > http
     [ a large JS object representing Node's 'http' module ]
  • Press control-c twice to exit REPL.


Why the Enthusiasm for Node.js?


Why the Enthusiasm for Node?


  • First and foremost, performance - businesses can handle more traffic with less hardware!

  • Secondly, developer synergy. Developers can use JavaScript on both client & server, thus becoming a full-stack dev is more obtainable and companies can better utilize their developer resources across the front and back-ends.


Why the Enthusiasm for Node?

  • The improvements in server performance and developer productivity result in businesses saving money.

  • Businesses saving money results in wide adoption:


Why the Enthusiasm for Node?


Most importantly, wide adoption of Node.js results in strong demand for Node developers!


Why is Node.js so Performant?


Why is Node so Performant?

  • First, it's important to understand how time consuming ("expensive") Input/Output operations are:


Why is Node so Performant?

  • Node's Asynchronous / Event-driven design enables
    non-blocking Input/Output:


Why is Node so Performant?


  • A typical Node server is capable of supporting tens of thousands of concurrent connections!

  • For more information regarding perfomance, check the references at the end of this presentation.


Asynchronous Programming Model


  • High-performance, non-blocking I/O operations must be designed as asynchronous methods.

  • Therefore, a Node developer will use callback functions and/or promises extensively.


❓ Review Questions - What is Node.js?


  1. Is Node.js a programming language?

  2. What is the primary reason why Node/Express applications are so performant?

  3. Is...
    const el = document.getElementById('my-list');
    a valid JavaScript statement in a Node app?


Now that you've learned
how awesome Node is,
let's see how it
runs JavaScript programs


Using Node to Execute JavaScript


  • Let's type the following JavaScript in main.js:

     const multiply = (a, b) => a * b;
     	
     let n = multiply(5, 8);
     	
     console.log(n);

Using Node to Execute JavaScript


  • Press ctrl + backtick to open the integrated terminal in VS Code and type the following to execute main.js:

     $ node main
     40

    Note how you don't need to include the ".js" file extension.

  • Yes, running a Node app is that easy!


So far, so good!
Now let's learn about
Node Modules


Node Modules


  • Modules in Node allow us to modularize and reuse code in a Node app.

  • Node itself comes with several core modules, such as the http and fs modules.

  • There are thousands of open-source modules available.


Node Modules


  • Let's use the core fs module to create a file. Replace the code in main.js with this:

     const fs = require('fs');
     console.log(typeof fs);
     
     fs.writeFile('./hello.txt', 'Hello!', function() {
       console.log('done creating file');
     });
  • We can see that the fs module "exports" an object that has methods such as writeFile.


Node Modules


  • Okay, now let's see how we can create our own modules.

  • In a Node application, every JavaScript file is a module!

  • A Node app's modules (files) can be put in any folder within the project.

  • This allows us to create modules inside of aptly named folders, such as models, routes, controllers, views, etc.


Node Modules


  • A module is "loaded" into a Node app using the require function we just used to load the fs module.

  • Whatever functionality the module "exports" is returned by the require function.

  • How does a module "export" its functionality? Let's create a module and see...


Node Modules


  • Let's create a file/module named days-of-week.js: touch days-of-week.js

  • Okay, each Node module has a variable inside of it named module that holds an object containing information about that module.

  • Let's see what the module object it looks like:

     // days-of-week.js
     
     console.log(module);

Node Modules


  • Even the file we run using node is a module, so let's type
    node days-of-week and check out what's logged.

  • We're getting an inside look at how Node implements its module system...


Node Modules


  • Each module is uniquely identified by its fully qualified filename. This allows modules to be named the same, as long as they exist in different folders.

  • The property on module that we're really interested in though is exports. What value is it initialized to?


Node Modules


  • So, this is a key point to remember...
    Whatever value is assigned to module.exports, is what the require function returns!

  • Let's verify this by assigning a string to it:

     // days-of-week.js
     
     module.exports = 'SEI';
  • Now let's require the module inside of main.js...


Node Modules

  • Replace the code in main.js with this:

     // main.js
     
     let daysOfWeek = require('./days-of-week');
     console.log(daysOfWeek);

    Then type node main

  • Note that when we require our app's custom modules, we need to provide a relative path - always starting with either a . or ..

  • It is convention to name the variable the same as, or similar to, the name of the module being required.


Node Modules - Practice


  • You Do: Instead of exporting a string, change days-of-week.js to export the following array instead:

     ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
  • Run main.js to check it out.


Node Modules


  • Since modules are about code reuse, they can be required an unlimited number of times throughout the application.

  • However, the code in the module only runs the first time the module is required.
    Allow me demo this for you.


Node Modules


  • Remember how module.exports was initialized to an object by default?

  • This is because exporting multiple pieces of functionality by creating properties on module.exports is very common.

  • Let's try it out:

     module.exports.weekdays = 
     	['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
     
     module.exports.getWeekday = function(dayNo) {
     	if (dayNo < 0 || dayNo > 6) dayNo = 0;
     	return exports.weekdays[dayNo];
     };

Node Modules


  • Now let's test it in main.js:

     let daysOfWeek = require('./days-of-week');
     
     let day = daysOfWeek.getWeekday(5);
     console.log(day);

    Fr should be logged out.

  • Questions?


Node Modules


  • Node also provides a "shortcut" variable named exports that references that very same object that module.exports does.

  • You can try it by removing module. to create this line of code:
    exports.weekdays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];

  • IMPORTANT: It is not possible to assign functionality to the exports shortcut variable because it will stop referencing module.exports.


Node Modules


  • One last thing about modules, any variables declared within a module are local to the module - they do not pollute the global scope.

  • BTW, the global scope in a Node application is represented by an object named global, unlike the browser's ________ object.


❓ Review Questions - Modules


  1. What are modules used for in Node?

  2. How many modules can be defined in a single file?

  3. What is the special object we use in our module to attach or assign functionality to?

  4. How many times can we require a module in our program?

continued on next slide...


Questions - Modules (cont.)


  • Why won't the following code work as intended?

     // add.js module
     exports = function (x, y) { return x + y };

    and

     // use the add.js module
     const add = require('./add');
     let sum = add(5, 10);

Now that you've created and used your own modules, let's see how we can install open-source packages and use the modules they contain


NPM - Node Package Manager


  • Node uses a package management system to distribute open-source packages called Node Package Manager (npm).

  • Usually a package distributes a Node module, however, sometimes the package distributes a CLI instead of a module we would use in our program.


NPM - Node Package Manager


  • Node programs use a package.json file that tracks the installed modules that the app depends upon.

  • Tracking an application's dependencies in package.json removes the necessity to push the app's node modules to the projects GitHub repo - this saves MASSIVE file storage and bandwidth.


NPM - Node Package Manager


  • If you start a Node app from scratch, the first thing you should do is create the package.json file by entering the following command:

     $ npm init
  • It's okay to accept all of the default settings. To accept the defaults without being prompted, you can run the command as follows:

     $ npm init -y

NPM - Node Package Manager

  • Now, let's use npm to download and install a package:

     $ npm install request
  • There is now a node_modules folder that contains a folder for the request module and its many dependencies.

  • There's also a new package-lock.json file that npm uses to track dependencies and unlike package.json, should not be edited.

  • Note: it's highly recommended that node_modules be added to your .gitignore file.


NPM - Node Package Manager

  • We can now require the request module in main.js and make HTTP requests:

     // Don't specify path when module is in node_modules
     const request = require('request');
     request(
     	'http://jsonplaceholder.typicode.com/users',
     	function(err, res, body) {
     		console.log(body);
     	}
     );
  • Type node main to try it out.


NPM - Node Package Manager


  • Let's examine the request() call a little closer...

  • Why did a callback have to be provided?

  • Note the first parameter in the callback is err.
    This "error-first" callback signature is prevalent throughout Node.


NPM - Node Package Manager

  • Examining the packages.json file reveals that it's structured something like this:

     {
       "name": "first-node",
       "version": "1.0.0",
       "description": "",
       "main": "index.js",
       "scripts": {
         "test": "echo \"Error: no test specified\" && exit 1"
       },
       "author": "Jim Clark <[email protected]>",
       "license": "MIT",
       "dependencies": {
         "request": "^2.88.0"
       }
     }

NPM - Node Package Manager


  • The package.json is used to install a project's dependencies.

  • Installing dependencies is necessary after cloning a repo or when using starter code for a lesson.

  • To demonstrate this, first delete the node_modules file, then...


NPM - Node Package Manager (cont.)


  • Now we can install our app's dependencies like this:

     $ npm install

    Witness the return of node_modules!


Conclusion


  • In the next lesson, you will use one of the most popular Node modules, Express, that turns Node into a capable web server.

  • Questions?

  • There are a couple of practice exercises following...


πŸ’ͺ Practice - Modules #1

Create two separate modules:

A module named "random" that has a function assigned to the module.exports and returns a random number, as an integer, between two numbers provided, inclusive, as arguments; so that we could use it in our program like this:

const random = require('./utilities/random');
for (let i = 0; i < 10; i++) {
	console.log( random(100, 200) );
}

πŸ’ͺ Practice - Modules #2


A module named "circle" that exports two functions:

  • area: Computes the area of a circle (radius squared X Pi), with the radius provided as an argument.

  • circumference: Computes the circumference of a circle (radius X 2 X Pi), with the radius provided as an argument.

  • Hint: This is JS, so Math.PI is available.

     const circle = require('./utilities/circle');
     console.log( circle.area(50) );  // 7853.98...
     console.log( circle.circumference(75) );  // 471.23...

References


NodeJS Homepage

Node Package Manager

Blocking/Non-Blocking, Async/Sync

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment