Click to view this presentation.
-
Explain the Use Case for NodeJS
-
Use NodeJS to Execute JavaScript
-
Create and Use Node Modules
-
Use NPM to Install External Packages
- Transitioning to Unit 3
- Facts about NodeJS
- Why the Enthusiasm for Node?
- Django or Node?
- Why is Node so Performant?
- Using Node to Execute JavaScript
- NodeJS Modules
- Our First Module
- NPM - Node Package Manager
-
In Unit 2, you begun your journey of becoming a full-stack developer.
-
Although we're moving on from Django, rest assured that much of what you've learned applies to full-stack development as a whole...
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
- Relational Data Design
- Data Manipulation using an ORM
- Server-side Templating
- Authentication & Authorization
- Deployment
-
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.
-
Yes, learning new technologies is always a challenge!
-
Secondly, Node/Express, unlike with Django, is minimalistic and unopinionated, which translates into:
- More code to write to accomplish even the most basic of tasks
- Wildly varying ways to structure applications
- Varying degree of modularization of code
-
Basically, Node/Express apps are the...
-
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.
-
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 is an open source project governed by the NodeJS Foundation with board representation from companies such as:
- PayPal
- Microsoft
- GoDaddy
- IBM
- Red Hat
- Intel
-
There is also a Technical Steering Committee independent from the Board.
-
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.
-
Node has packages, just like Python does.
-
Python used pip to manage packages. In Node we use a package manager called npm which is installed with Node.
-
Node's package ecosystem is the largest open source ecosystem in the world.
- Similar to Python, when you type just
node
in Terminal, you enter Node's interactive REPL (Read-Eval-Print-Loop). Typingnode
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.
-
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.
-
The improvements in server performance and developer productivity result in businesses saving money.
-
Businesses saving money results in wide adoption:
-
Lastly, and most importantly, wide adoption of Node results in strong demand for Node developers!
-
Quicker path to building an app with full CRUD.
-
Better at working with complex data relationships - the Django ORM rocks!
-
When full page refreshes aren't an issue.
-
Easier to program because synchronous programming is more straightforward than async programming.
-
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.
- First, it's important to understand how time consuming ("expensive") Input/Output operations are:
- Node's Asynchronous / Event-driven design enables non-blocking Input/Output:
-
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.
Django or Rails (Synchronous Programming)
-
Each line of code must finish before the next line is executed. Sounds logical until you consider that 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.
NodeJS (Asynchronous Programming)
-
Node's I/O is non-blocking. That means that it is designed not wait for those notoriously slow I/O operations to complete before it moves on.
-
Callback functions enable this async programming model. When our code calls a method involving I/O, the rest of the program keeps running and the callback is put in the event queue when I/O operation finishes.
-
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?
Let's see how we can run a JavaScript program in Node:
$ mkdir first-node
$ cd first-node
$ touch main.js
$ code .
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.
-
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
thefives
array.
- Defines an empty array named
-
Use Node to execute your program.
-
Modules in Node allow us to organize and reuse JavaScript code.
-
Node itself comes with several core modules, such as the
http
andfs
modules. -
There are thousands of open-source modules available.
-
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. This was exactly the same as in Python.
-
You can put your app's modules (files) in any folder within your project. This allows us to organize our code inside folders named
models
,routes
, etc.
-
Unlike in Python modules, where every module variable, function and class were available by default to be imported by another module, Node modules limit what is available to whatever an implicit property,
module.exports
, is set to or holds. -
Also, Node's modules use a
require
function instead ofimport
to import whatever is exported by the module...
-
For example, say you have a module (file) named colors.js:
module.exports = ['red', 'green', 'blue'];
-
Any other module that wanted that array of colors can
require
it as follows:var basicColors = require('./colors'); // basicColors now references the array exported by colors.js
-
Inside of our modules, Node automatically provides a special object named
module.exports
and a "shortcut" variable that points tomodule.exports
named what else -exports
. -
We can attach our module's functionality to
module.exports
orexports
:module.exports.myNumber = 123; // same as above exports.myNumber = 123; // add as many properties as you wish exports.sayHi = function() { console.log('Hi'); };
-
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
thatrequire
s this module references the function!
-
Wherever and whenever we need access to a custom module's
module.exports
, we justrequire
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.
-
require
basically "turns into" whatevermodule.exports
is - PERIOD:// 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'
-
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.
- Provides an array named
-
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
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) {
if (dayNo < 0 || dayNo > 6) dayNo = defaultDay;
return exports.weekdays[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.
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
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) );
}
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...
-
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?
continued on next slide...
-
Wy won't this work as intended?
// 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
-
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.
-
Node programs use a
package.json
file that tracks the installed modules that the app depends upon. -
Why is tracking an application's dependencies in a separate file important?
-
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
-
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 therequest
module many other dependencies. -
There's also a new
package-lock.json
file that npm uses to track dependencies and unlikepackage.json
, should not be edited. -
Note: it's highly recommended that
node_modules
be added to your.gitignore
file.
-
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": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Jim Clark <[email protected]>",
"license": "MIT",
"dependencies": {
"request": "^2.88.0"
}
}
-
The
package.json
is used to install a project's dependencies. -
Installing dependencies is necessary after cloning a repo or when using the starter code for a lesson.
-
To demonstrate this, first delete the
node_modules
file, then...
-
Now we can install our app's dependencies like this:
$ npm install
Witness the return of
node_modules
!
-
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!