Skip to content

Instantly share code, notes, and snippets.

@jim-clark
Last active February 3, 2019 05:18
Show Gist options
  • Save jim-clark/2c139ff7a8fd59fcb82d to your computer and use it in GitHub Desktop.
Save jim-clark/2c139ff7a8fd59fcb82d to your computer and use it in GitHub Desktop.

Click to view this presentation.




Intro to NodeJS


Learning Objectives


  • Explain the Use Case for NodeJS

  • Use NodeJS to Execute JavaScript

  • Create and Use Node Modules

  • Use NPM to Install External Packages


Roadmap


  • Transitioning to Unit 3
  • Facts about NodeJS
  • Why the Enthusiasm for Node?
  • Rails or Node?
  • Why is Node so Performant?
  • Using Node to Execute JavaScript
  • NodeJS Modules
  • Our First Module
  • NPM - Node Package Manager

Transitioning to Unit 3


  • In Unit 2, you begun your journey of becoming a full-stack developer.

  • Although we're heading off the Rails, rest assured that much of what you've learned applies to full-stack development as a whole...


Transitioning to Unit 3


The following concepts we've covered in class will continue to serve you well:

  • OOP - Design, Encapsulation of Data (attributes) & Behavior (methods) and Inheritance)
  • HTTP and the Browser-Request/Server-Response Cycle
  • MVC (Model/View/Controller) Architectural Pattern
  • RESTfull Routing & Mapping to Data CRUD
  • Relational Data Modeling
  • Data Manipulation using an ORM such as ActiveRecord
  • Server-side View Templating
  • Authentication & Authorization
  • Deployment

So, We're Going Off the Rails



Unit 3 - Technologies


  • In Unit 3, we will delve into the world of:

    • NodeJS - An operating environment that executes our old friend - JavaScript
    • Express - The most popular web framework for NodeJS
    • MongoDB - A NoSQL, document-based database system
  • The three technologies above account for three of the four technologies involved in the MEAN and MERN Solution Stacks.


Heading for a Train Wreck? - No, but...


  • Learning new technologies is always a challenge.

  • Secondly, Node/Express, unlike with Rails, does not subscribe to the Convention over Configuration methodology, which translates into:

    • More code to write to accomplish even the most basic of tasks
    • Wildly varying ways to structure applications
    • More complexity - thanks to more flexibility
    • Varying degree of modularization of code
  • Basically, Node/Express apps are the...



What is NodeJS?



Facts about NodeJS


  • An open source, cross-platform, runtime environment that executes JavaScript, primarily on the server-side.

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

  • Written primarily in C++, not JS!

  • Uses Google's V8 JavaScript Engine to compile JS programs into machine code.


Facts about NodeJS (cont.)


  • The runtime environment for JS is different in Node than that in the browser, primarily because there is no DOM.

  • Although NodeJS is primarily thought of as a runtime for server-side JavaScript, it is also used extensively for running client-side utility programs.


Node's REPL

  • Let's take a look at Node's interactive Node's REPL (Read-Eval-Print-Loop). Think of Node's REPL as Node's version of Ruby's IRB. Typing node in terminal launches it:
$ node
> 10 + 5
15
> function sayHello() {
... console.log('Hello');
... }
undefined
> sayHello()
Hello
undefined
> var http = require('http');
undefined
> http
[ a large JS object representing Node's 'http' module ]

Press control-c twice to exit REPL.


Facts about NodeJS (cont.)

  • Node is an open source project governed by the NodeJS Foundation with board representation from companies such as:

    • PayPal
    • Microsoft
    • Google
    • GoDaddy
    • IBM
    • Red Hat
    • Intel
  • There is also a Technical Steering Committee independent from the Board.


Facts about NodeJS (cont.)


  • Extremely lightweight. Only low-level "core" modules for networking, filesystem access, etc. are baked-in.

  • Node's functionality is extended via open source libraries called packages. Packages usually contain a module of code that we can require (use) in our own modules, but sometimes a package installs command line interface (CLI) tools.


Facts about NodeJS (cont.)


  • Packages are to Node, as Gems are to Ruby.

  • Packages are managed using a package manager called npm which is installed with Node.

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


Why the Enthusiasm for Node?


Why the Enthusiasm for Node?


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

  • Secondly, developer synergy. Because a developer can use JS on client & server, 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? (cont.)

  • 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? (cont.)

  • Wide adoption of Node results in more demand for Node developers:


Rails or Node?


Why Choose Rails?


  • Quickest path to building an app with full CRUD.

  • Better at working with complex data relationships - ActiveRecord rocks!

  • When full page refreshes aren't an issue.

  • Easier to program because synchronous programming is more straightforward than async programming.


Why Choose Node?


  • JavaScript everywhere!

  • When high performance and high capacity matter.

  • Designed with modern realtime, mobile and Single Page Applications in mind - easier to avoid full page refreshes.


Why is Node so Performant?

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


Why is Node so Performant? (cont.)

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


Why is Node so Performant? (cont.)


  • This technical jargon basically results in a Node server capable of supporting tens of thousands of concurrent connections!

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


Synchronous vs. Asynchronous


Rails (Synchronous Programming)

  • Each line of code must finish before the next line is executed. Sounds logical until you consider if the line of code involves an I/O operation (network, database, or file system call) that your program will spend most of its time waiting until the I/O operation is completed.


Synchronous vs. Asynchronous


NodeJS (Asynchronous Programming)

  • Node is asynchronous and non-blocking, that means that it is designed not wait for those notoriously slow I/O operations to complete before it moves on.

  • Your friend, the callback function, enables this pattern. When our code calls a method involving I/O, we also provide a callback function to be, well, "called back", when the I/O operation is complete.


Questions - What is NodeJS?


  • True or false - Node itself is written in JavaScript.

  • Is NodeJS a programming language?

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

  • Is
    var elem = document.getElementById('my-list');
    a valid JavaScript statement in a Node app?


Now that you've learned the use case for Node, let's see how it can run JavaScript programs


Using Node to Execute JavaScript


Let's see how we can run a JavaScript program in Node:

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

Using Node to Execute JavaScript


Toss in a little JavaScript into main.js:

function multiply(x, y) {
  return x * y;
}

var n = multiply(5, 8);

console.log(n);

Now use Node to run main.js:

$ node main
40

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


Practice (5 mins)
Use Node to Execute JavaScript


  • To practice, and to help get back into the JavaScript "mindset", replace the code in main.js with code that:

    • Defines an empty array named fives.
    • Uses a for loop to loop through the numbers 1 through 100.
    • Within the loop's code block, if the current value of the loop variable is evenly divisible by 5, add it to the fives array.
    • After the loop has completed, console.log the fives array.
  • Use Node to execute your program.


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


NodeJS Modules


  • Modules in Node allow us to organize and reuse JavaScript code.

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

  • There are thousands of open-source modules available.


NodeJS Modules (cont.)


  • In our own programs, we organize our code into modules.

  • Each module will be contained in its own file - there is a one-to-one mapping between a file and a module.

  • You can put your app's custom module files in any folder within your project. This allows us to organize our code inside folders named models, routes, etc.


NodeJS Modules (cont.)



Modules exports Their Functionality

  • Inside of our modules, Node automatically provides a special object named module.exports and a "shortcut" variable that points to module.exports named what else - exports.

  • We can attach our module's functionality to module.exports or exports:

     module.exports.myNumber = 123;
     // same as above
     exports.myNumber = 123;
     
     // add as many properties as you wish
     exports.sayHi = function() { console.log('Hi'); };

Modules exports Their Functionality


  • If we want to assign a single piece of functionality without using a property, be sure to use module.exports:

     module.exports = function() { console.log('Hi'); };
     // Below will not work due to breaking the object reference
     // exports = function() { console.log('Hi'); };
  • Now, a var that requires this module references the function!


Using the require Method


  • Wherever and whenever we need to use our custom module, we just require the module file, without the file extension, using a relative path.

  • Note that the module is loaded only once, even if it is "required" multiple times.


Using the require Method (cont.)


  • require basically "turns into" whatever module.exports is. This is true whether we "attach" properties the original module.exports or exports object, or assign to it a function, array or whatever:

     // my-module attached a myNumber property to module.exports
     var myMod = require('./my-module');
     console.log(myMod.myNumber);  // outputs 123
     
     // module.exports was assigned a sayHi function
     var sayHi = require('./my-module');
     console.log( sayHi() );  // outputs 'Hi'

Modules - Remember This


requires(...)

Equals whatever

module.exports

Is set to!!!


Our First Module


  • Together, let's create a module that:

    • Provides an array named weekdays containing two-character names of the days of the week.
    • Provides a function named getWeekday that accepts a number from
      0 to 6 and returns the name; where 0 = 'Su'.
    • If an invalid number is passed in, assume a value of 1.
  • Let's put our module inside of a "utilities" folder and name it "days-of-week.js":

     $ mkdir utilities
     $ touch utilities/days-of-week.js

Our First Module (cont.)

The code will look like this:

// days-of-week.js

// This is a local variable in scope to this module only
var defaultDay = 1;

// Exporting the weekdays array
module.exports.weekdays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];

// You can "attach" properties directly on "exports".
// However, "assigning" directly to exports breaks!
exports.getWeekday = function(dayNo) {
	return exports.weekdays[dayNo < 0 || dayNo > 6 ? defaultDay : dayNo];
}

console.log("days-of-week module has been loaded");

Note that in Node, all variables defined are local to that module - they will not pollute the global scope.


Our First Module (cont.)


Use our "days-of-week" module in "main.js":

// main.js
	
var dow = require('./utilities/days-of-week');
	
// Outputs the weekdays array
console.log(dow.weekdays);
	
// Outputs "Fr"
console.log(dow.getWeekday(5));

Run "main.js" with Node:

> node main


Practice - Modules #1 (10 mins)


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:

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

Practice - Modules #2 (10 mins)


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.
var circle = require('./utilities/circle');
console.log( circle.area(50) );  // 7853.98...
console.log( circle.circumference(75) );  // 471.23...

Questions - Modules

  • What are modules used for in Node?

  • How many modules can be defined in a file?

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

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

  • Does the variable name we use need to match the name of the module?

continued on next slide...


Questions - Modules (cont.)


  • Will this work?

     // in module file named add.js
     exports = function (x, y) { return x + y };
     
     // in other file
     var add = require('./add');
     console.log( add(1, 2) );

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 (cont.)


  • Working with packages in Node is very similar to working with gems in Ruby:

    Ruby Node
    gem install ... npm install ...
    bundle install (works with Gemfile) npm install (works with package.json)

NPM - Node Package Manager (cont.)


  • Similar to how Rails has a Gemfile to track gems that an application depends on, Node apps have a package.json file that does the same thing.

  • Why is tracking an application's dependencies in a separate file important?


NPM - Node Package Manager (cont.)


  • 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 (cont.)


  • Now, let's use npm to install one of Node's packages:

     $ npm install request
  • Take a look and you will find that a node_modules folder has been added to your project and that it contains a folder for the request module.

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


NPM - Node Package Manager (cont.)

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

// Don't specify path when module is in node_modules
var request = require('request');
request('http://jsonplaceholder.typicode.com/users', function(err, res, body) {
	console.log(body);
});
  • Why do we need to provide a callback?

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

  • Use Node to execute main.js and check out the result!


### NPM - Node Package Manager (cont.)
  • Examining the `packages.json` file reveals that it's structured like this...

{
  "name": "first-node",
  "version": "1.0.0",
  "description": "My first node app",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "You <[email protected]>",
  "license": "MIT",
  "dependencies": {
    "request": "^2.69.0"
  },
  "devDependencies": {
    "gulp": "^3.9.1"
  }
}

NPM - Node Package Manager (cont.)


  • The package.json file works a like a Gemfile in that we can install the dependencies from it. This is almost always necessary after cloning a repo or using the starter code for a given lesson.

  • Let's delete our node_modules file:

     $ rm -rf node_modules

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?

  • Take a break!


References


NodeJS Homepage

Node Package Manager

Why Do Companies Choose Node

Blocking/Non-Blocking, Async/Sync

Node Event Loop

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