Introduction
Prior to Node.js, JavaScripts runs only under a web browser (such as Chrome, Firefox, and MSIE) bundled with a built-in JavaScript engine. Node.js is a JavaScript Runtime Engine that allows us to run JavaScript in standalone manner, without using a browser.
Node.js is commonly-used for programming web server, i.e., server-side JavaScript. This is popular because you can use the same JavaScript language to program the client and the server.
The mother site of Node.js is https://nodejs.org/.
The important features of Nodes.js are:
- Node.js runs the high-performance V8 JavaScript engine, the core of Google Chrome, outside of the browser.
- Node.js uses asynchronous programming. It provides a set of asynchronous non-blocking I/O functions (with new keywords
async
andawait
). Instead of blocking the thread and wasting CPU cycles waiting, Node.js will suspend the first request, continue with the next request, and resume the operations when the response of the first request comes back. This allows a Node.js app to run in a single process, without creating a new thread for every request. A Node.js server can handle thousands of concurrent connections without the burden of managing thread concurrency. - You can program the client and server using the same JavaScript language.
- A huge number of libraries is available, which are managed by npm (Node package manager).
- Node.js is free, open-source, and runs under many platform (Linux, Windows, macOS).
Installation
Installing Node.js
In Windows
- Goto Node.js download site @ https://nodejs.org/en/download/ ⇒ Choose "LTS" (Long-Term Support) ⇒ Download "Windows Binary (
.zip
)" and "64-bit" (e.g., "node-v12.16.1-win-x64.zip
" - 18MB) ⇒ Unzip into a directory of your choice, denoted as "Node.js installed directory". - Add the "Node.js installed directory" to your PATH environment variable. See "How to add a directory to the PATH".
In macOS
[TODO]
In Ubuntu
- Download Node.js from https://nodejs.org/. Choose Linux platform (e.g.,
node-v0.12.3-linux-x64.tar.gz
). - Unzip into a directory of your choice (e.g.,
/usr/local
or/usr/local/lib
). - Node.js has two executables in its
bin
sub-directory:node
(the standalone JavaScript engine) andnpm
(Node.js Package Manager). Instead of adding thebin
directory to the PATH, you can create symlinks in one of the PATH directories. For example, I create symlinks in/usr/local/bin
(which is in the PATH), as follows:$ cd /usr/local/bin // Create symlinks, may need to sudo $ ln -s /path-to-nodejs/bin/node $ ln -s /path-to-nodejs/bin/npm // Set to executable, may need to sudo $ chmod +x node $ chmod +x npm
Environment Variable NODE_PATH
In my Windows system, Node.js cannot locate some of my installed packages, even with npm install --global
option. I resolved this issue by adding the "node_modules
" sub-directory to the NODE_PATH environment variable.
To set "node_modules
" directory to NODE_PATH:
- (For Windows) Read "How to add/set an environment variable".
- (For macOS/Linux) Read "How to set an Environment variable".
Take note that the NODE_PATH may take multiple directories, separated by semicolon (;
) in Windows, or colon (:
) in macOS/Linux.
Getting Started with Node.js
Running Node.js in REPL (Read-Evaluate-Print Loop) Command-Line Mode
Start a CMD/Terminal/Bash-Shell. Launch Node.js:
node Welcome to Node.js v12.16.1. Type ".help" for more information. > .help .break Sometimes you get stuck, this gets you out .clear Alias for .break .editor Enter editor mode .exit Exit the repl .help Print this help message .load Load JS from a file into the REPL session .save Save all evaluated commands in this REPL session to a file Press ^C to abort current expression, ^D to exit the repl > console.log("hello, world") hello, world undefined // return value of console.log() function > .exit // or Ctrl-C twice, or Ctrl-D
Node.js runs in the REPL (Read-Evaluate-Print Loop) mode - an interactive language shell. It takes a single user input, evaluates, and returns the result.
Executing JavaScript Source Files
Prepare a JavaScript called "hello.js
" as follows:
// hello.js
console.log('hello, world');
You can run the Script under Node.js as follows:
node hello.js
hello, world
Install other JavaScript/Node Packages using npm (Node Package Manager)
Node.js is bundled with a program called npm (Node Package Manager), which is used to maintain the JavaScript packages.
You can install other node packages easily via npm (Node Package Manager). For example,
// Install Less, a CSS preprocessor. May need to use "sudo" to write to the global directory npm install -g less // -g (or --global) for all users // Installed under /usr/local/lib/node_modules/less // A symlink lessc created in /usr/local/bin // Install Gulp, an automation tool. May need to use "sudo" to write to the global directory npm install -g gulp // Installed under /usr/local/lib/node_modules/gulp // A symlink gulp created in /usr/local/bin
More on npm in the later section.
Node.js Get Started By Examples
Example 1: Node.js as a Web Server
Create the following JavaScript file, and save as "app.js
" in a directory of your choice.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// app.js const http = require('http'); // 'http' module const hostname = '127.0.0.1'; // ip for localhost const port = 3000; const server = http.createServer((req, res) => { res.statusCode = 200; // set the repsonse status code to 200 "OK" res.setHeader('Content-Type', 'text/plain'); // set the response MIME type res.end('hello, world'); // write and end the response }); server.listen(port, hostname, () => { console.log(`HTTP Server listening at http://${hostname}:${port}/`); }); |
Run the "app.js
" using Node (as a standalone program) as follows, which starts a HTTP server process.
cd /path/to/JavaScript-Directory
node app.js
HTTP Server listening at http://127.0.0.1:3000/
Start a web browser (Chrome, Firefox). Issue URL http://localhost:3000/
. You shall see a hello-world message.
To stop the server, press Ctrl-C (or Ctrl-Shift-C).
How It Works?
- Read "HTTP Basics", if you are not familiar with HTTP protocol.
- In Line 5, the
http.createServer()
creates a new HTTP server and returns it. - In Line 11, the server is set to listen on the specified port and hostname, via
.listen(port, host, callback)
. When the server is ready, the callback function is called, which runs theconsole.log()
to inform our the server is ready. - Whenever a new request is received, the
request
event is called, providing two objects: arequest
(anhttp.IncomingMessage
object) and aresponse
(anhttp.ServerResponse
object). - In Line 6, we set the response
statusCode
property to 200 to indicate a successful response (i.e., "OK"). In Line 7, we set theContent-Type
of the response header to MIME'text/plain'
. In Line 8, we write the output and close the response viaend()
. - You could activate the F12 Debugger, to inspect the request and response messages under the "Network".
Node.js Web Frameworks
Reference: Introduction to Node.js @ https://nodejs.dev/.
Node.js is a low-level platform. Over the years, many full-stack frameworks have been developed over the Node.js, such as:
- AdonisJs: A full-stack framework highly focused on developer ergonomics, stability, and confidence.
- Express: It provides one of the most simple yet powerful ways to create a web server.
- Fastify: A web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture.
- hapi: A rich framework for building applications and services that enables developers to focus on writing reusable application logic instead of spending time building infrastructure.
- koa: It is built by the same team behind Express, aims to be even simpler and smaller, building on top of years of knowledge.
- Loopback.io: Makes it easy to build modern applications that require complex integrations.
- Meteor: An incredibly powerful full-stack framework, powering you with an isomorphic approach to building apps with JavaScript, sharing code on the client and the server. It integrates with frontend libs React, Vue, and Angular. Can be used to create mobile apps as well.
- Micro: It provides a very lightweight server to create asynchronous HTTP microservices.
- NestJS: A TypeScript based progressive Node.js framework for building enterprise-grade efficient, reliable and scalable server-side applications.
- Next.js: A framework to render server-side rendered React applications.
- Nx: It powers the Angular CLI which allows building full-stack applications using NestJS, Express, and Angular and easily share code between backends and frontends.
- Socket.io: A real-time communication engine to build network applications.
Example 2: Setting up an "Express" Web Server
Reference: "Express: Fast, unopinionated, minimalist web framework for Node.js" @ https://expressjs.com/.
This example illustrates how easy to set up a functional Node web server using the "Express" package.
First, create a project directory (say "myExpressApp
"), initialize, and install the "express
" module.
// Create a project directory mkdir myExpressApp cd myExpressApp // Initialize npm, which creates "package.json" npm init // accept the defaults // Install "express" package, under "node_modules" sub-directory npm install express
Example 1: Setting up a HTTP Server for Static Resources (HTML/CSS/JS/Images/fonts)
Create the following script under your project directory.
1 2 3 4 5 6 7 8 9 10 11 12 |
// app.js const express = require('express'); // include the "express" module const app = express(); const port = 3000; // Define route for get request at '/' app.get('/', (req, res) => res.send('hello, express world')); // Define the static resource (HTML/CSS/JS/images) app.use(express.static('public')); // URL '/' (root) maps to 'public' directory app.use('/static', express.static('public')); // URL '/static' also maps to 'public' directory |
Create a sub-directory called "public
". Place some static resources, such as "hello.html
", "test.txt
", "image.png
", under the public
directory.
Run the app:
node app.js
Server listening at port 3000...
Try the following URLs. This "express" HTTP server is able to serve static resources!
http://localhost:3000/
http://localhost:3000/hello.html
http://localhost:3000/test.txt
http://localhost:3000/image.png
http://localhost:3000/something.html // 404 Not Found
http://localhost:3000/static/hello.html
http://localhost:3000/static/test.txt
http://localhost:3000/static/image.png
How it Works?
- This app starts a HTTP server listening on port 3000.
- In Line 7, we set up a route for
get
request at'/'
(base directory), to return the hello-word message. The syntax is:app.http-method(path, handler) // For examples, app.get('/', (req, res) => res.send('hello, get')); // for get request at '/' app.post('/test', (req, res) => res.send('hello, get')); // for post request at '/test' app.put('/test/test', (req, res) => res.send('hello, put')); // for post request at '/test/test' app.delete('/tmp/tem.txt', (req, res) => res.send('hello, delete')); // for post request at '/tmp/tem.txt'
- In Line 9, we map the URL
'\'
(root) to the physical server's directory "public
". You can use multiple statements to include multiple directories in the root, for example,app.use(express.static('public')); app.use(express.static('test'));
- In Line 10, we also map the URL
'\static'
to the physical server's directory "public
" (for illustration only). - For any other URL, the server will return "404 Not Found".
[TODO] Express Application Generator. See https://expressjs.com/en/starter/generator.html.
Modules
Modules are JavaScript Libraries, available to Node.js.
Built-in Modules
Node.js comes with a set of built-in modules. To include a built-in module, use the require(moduleName)
function, e.g.,
const http = require('http');
// Prior to ES6
var http = require('http');
Writing Your Own Module
To make your objects in a JavaScript available, use exports()
. For example, create a JavaScript called "myHello.js
", as follows:
// myHello.js - myHello module exports.sayHello = () => console.log('hello, world');
You can reference the exported objects via require()
. For example, create a JavaScript called "testMyHelloModule.js
", as follows:
// testMyHelloModule.js const hello = require('./myHello'); // kept in the same directory // Invoke the exported function of myHello module hello.sayHello();
Use Node.js to run the JavaScript:
node testMyHelloModule.js
hello, world
HTTP ('http') Module
The Built-in HTTP module allows us to create a web server. See the above example.
You can create a web server in one statement:
// app1.js const http = require('http'); http.createServer((req, res) => { res.end('hello, world'); // write and end the response }).listen(3000, () => console.log('Server listening at port 3000...'));
To run:
node app1.js
Server listening at port 3000...
Start a web browser and issue URL "http://localhost:3000
".
File System ('fs') Module
The built-in File System module allows us to manipulate files, such as:
.open(filename, [encoding], callback(err, file))
: open a file or create a new file..readFile(filename, callback(err, data))
.writeFile(filename, data, callback(err))
: writesdata
intofilename
, erasing existing contents..appendFile(filename, data, callback(err))
: appends givendata
tofilename
..unlink(filename, callback(err))
: delete file.rename(oldFilename, newFilename, callback(err))
Example: Reading File via .readFile()
For example, let us create a web server that reads the response from a file.
- First, create the following HTML file called "
hello.html
":<!DOCTYPE html> <html> <head><title>Hello</title></head> <body> <h1>hello, world</h1> </body> </html>
- Write the Node.js web app:
// app2.js const http = require('http'); const fs = require('fs'); // file system module const port = 3000; http.createServer((req, res) => { fs.readFile('hello.html', (err, data) => { res.writeHead(200, {'Content-Type': 'text/html'}); // set status code and MIME type res.write(data); res.end(); // end the response }); }).listen(port, () => console.log(`Server listening at port ${port}...`));
- Run the app, as in the above example.
Asynchronous I/O
Most of the I/O operations in Node.js are asynchronous and non-blocking, which is good for programming web server.
Try the following JavaScript:
// testReadFile1.js const fs = require('fs'); var content; fs.readFile('test.txt', (err, data) => { if (err) throw err; content = data; }); // readFile() is asynchronous. The callback executes when the file loading has completed // Node continues the next statement without waiting for readFile() to complete console.log(content); //undefined
The output is an unexpected "undefined
". This is because readFile()
is asynchronous. The callback executes only after the file loading completes. The node will not wait, but continue to the next statement.
In asynchronous .readFile()
, you need to process the data inside the callback.
You can either (a) put your processing code inside the callback of .readFile()
, or (b) define a function and invoke the function inside the callback, for example,
// testReadFile2.js const fs = require('fs'); function myReadFile(callback) { fs.readFile('test.txt', 'utf8', (err, data) => { if (err) throw err; callback(null, data); // process the data upon completion of asynchronous readFile() }); }; myReadFile((err, data) => console.log(data));
A synchronous version called .readFileSync()
is available, for example,
// testReadFile3.js const fs = require('fs'); const content = fs.readFileSync('test.txt', 'utf8'); // without the encoding='utf8', the raw buffer is returned console.log(content);
Example: .writeFile() and .appendFile()
The .writeFile()
erases the existing contents, while .appendFile()
appends after the existing contents.
const fs = require('fs');
fs.writeFile('test.txt', 'hello 123\n', (err) => {
if (err) throw err;
console.log('writefile() done...');
});
const fs = require('fs');
fs.appendFile('test.txt', 'hello 456\n', (err) => {
if (err) throw err;
console.log('appendfile() done...');
});
URL ('url') Module
The URL module can be used to parse a URL. For example,
// testURL.js const url = require('url'); const adr = 'http://123.4.5.6:8080/hello.html?fruit=apple&beverage=coffee'; const q = url.parse(adr, true); console.log(q.host); //123.4.5.6:8080 console.log(q.pathname); //hello.html console.log(q.search); //?fruit=apple&beverage=coffee const qdata = q.query; console.log(qdata); //[Object: null prototype] { fruit: 'apple', beverage: 'coffee' } console.log(qdata.beverage); //coffee console.log(qdata.pet); //undefined
Example 3: A Simple Static HTTP Server using 'http', 'url' and 'fs'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// app3.js const http = require('http'); const url = require('url'); const fs = require('fs'); // file system const port = 3000; http.createServer((req, res) => { let q = url.parse(req.url, true); let filename = "." + q.pathname; fs.readFile(filename, (err, data) => { if (err) { res.writeHead(404, {'Content-Type': 'text/html'}); return res.end('404 Not Found'); } res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); return res.end(); }); }).listen(port, () => console.log(`Server listening at port ${port}...`)); |
How it Works?
- In Line 7-8, we use
url.parse()
to get the filename requested. - If the file is not found, the callback returns a
'404 Not Found'
, with status code 404. - if the file is found, the callback writes out the file data, with status code 200
'OK'
.
Events ('events') Module for Managing Node.js Events
Objects in Node.js can fire events. For example, the readSteram
object fires events when opening and closing a file.
Node.js has a built-in module, called "Events
", where you can create, fire and attach listener to event. In addition, all event properties and methods are instances of EventEmitter
objects. You need to create an instance of EventEmitter
object. For example,
// testEvents.js const events = require('events'); const eventEmitter = new events.EventEmitter(); // Create an event handler for hello event const myHelloEventHandler = () => console.log('someone says hello to me...'); // Attach an event handler to an event eventEmitter.on('hello', myHelloEventHandler); // Fire the 'hello' event eventEmitter.emit('hello'); //someone says hello to me...
NodeMailer ('nodemailer') Module for Sending Email
The "Nodemailer" module simplifies sending email from Node.js.
To install "Nodemailer":
npm install -g nodemailer
The module is installed under "node_modules
" of the Node.js installed directory.
Error Notes: If you encounter "error: module not found", you may try adding the "node_modules
" directory to the NODE_PATH environment variable. See "NODE_PATH".
The following JavaScript can be used to send an email:
// testEmail.js // npm install -g nodemailer const nodemailer = require('nodemailer'); const transporter = nodemailer.createTransport({ host: 'smtp.gmail.com', // gmail port: 465, // SSL:465, TLS:587 secure: true, // SSL auth: { user: 'your-email-address', pass: 'your-password' } }); const mailOptions = { from: 'your-email-address', to: 'receipent-email-address', subject: 'Sending Email using Node.js', text: 'hello' }; transporter.sendMail(mailOptions, (err, info) => { if (err) { console.log(err); } else { console.log('Email sent: ' + info.response); } });
You need to check your SMTP server's hostname/port, and whether SSL/TLS is used.
For "gmail", the SMTP server's hostname/port is shown. You also need to "Enabled Less Secure Apps". Goto "Manage your google account" ⇒ security ⇒ "Less secure app access" ⇒ "on".
Node.js Database Programming
MySQL
Reference: mysql module @ https://www.npmjs.com/package/mysql.
I assume that you are familiar with MySQL. Otherwise, read "How to Install MySQL and Get Started".
First, create a project directory (say "mySQLApp
"), initialize, and install the Node's "mysql
" driver module.
// Create a project directory mkdir mySQLApp cd mySQLApp // Initialize npm, which creates "package.json" npm init // accept the defaults // Install Node's "mysql" driver package, under "node_modules" sub-directory npm install mysql
(For MySQL 8) MySQL 8 uses a new caching-sha2_password
authentication methods, which is not supported by Node's "mysql" module. You need to revert back to the old mysql_native_password
method, by issuing these commands:
ALTER USER 'username'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; flush privileges;
Example 1: Connecting to the MySQL Database Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// testSqlConnnect.js const mysql = require('mysql'); // Create database connection const conn = mysql.createConnection({ host: 'localhost', port: '3306', user: 'username', password: 'xxxxxxxx' }); // Connect to the MySQL Database server conn.connect(err => { if (err) throw err; console.log('connected...'); // Run a SELECT query let sql = `SELECT 1 + 1 AS ans`; conn.query(sql, (err, rset, fields) => { if (err) throw err; console.log(rset); // debugging console.log(fields); // debugging console.log('The ans is: ', rset[0].ans); // Close the database connection conn.end(err => { if (err) throw err; console.log('disconnected...'); }); }); }); |
Start a CMD/Terminal/Bash and launch MySQL server:
// Start MySQL Server
cd /path/to/mysql/bin
mysqld --console
Start "another" CMD/Terminal/Bash to run the JavaScript:
node testMysqlConnect.js
connected...
[ RowDataPacket { ans: 2 } ] // the result set
[ FieldPacket { // Each column or field heading of the result set
catalog: 'def',
db: '',
table: '',
orgTable: '',
name: 'ans',
...
}
]
The ans is: 2
disconnected...
How it Works?
- [TODO]
- [TODO]
Example 2: CREATE TABLE, SELECT, INSERT, UPDATE and DELETE
First, use a MySQL client to create a database called "coffeeshop
":
CREATE DATABASE IF NOT EXISTS coffeeshop;
Write and Run the JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
// testSqlSelect.js const mysql = require('mysql'); // Create database connection const conn = mysql.createConnection({ host: 'localhost', port: '3306', user: 'username', password: 'xxxxxxxx', database: "coffeeshop" // database to be used }); // Connect to the MySQL Database server conn.connect(err => { if (err) throw err; console.log('connected...'); // Create Table let sql = `CREATE TABLE IF NOT EXISTS beverage ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(30) NOT NULL DEFAULT '', price DECIMAL(5,2) NOT NULL DEFAULT 999.99, PRIMARY KEY (id))`; conn.query(sql, (err, result) => { if (err) throw err; console.log(result); // debugging //OkPacket { // fieldCount: 0, // affectedRows: 0, // insertId: 0, // serverStatus: 2, // warningCount: 1, // message: '', // protocol41: true, // changedRows: 0 //} console.log('created table...'); // Insert Rows let sql = `INSERT INTO beverage VALUES (NULL, 'Espresso', 5.5), (NULL, 'Cappuccino', 5.6), (NULL, 'Latte', 5.7)`; conn.query(sql, (err, result) => { if (err) throw err; console.log(result); // debugging //OkPacket { // fieldCount: 0, // affectedRows: 3, // insertId: 4, // serverStatus: 2, // warningCount: 0, // message: '&Records: 3 Duplicates: 0 Warnings: 0', // protocol41: true, // changedRows: 0 //} console.log(result.message); console.log('insert id is: ' + result.insertId); // Select all rows let sql = `SELECT * FROM beverage`; conn.query(sql, (err, rset, fields) => { if (err) throw err; console.log(fields); // debugging //[ // FieldPacket { // catalog: 'def', // db: 'coffeeshop', // table: 'beverage', // orgTable: 'beverage', // name: 'id', // orgName: 'id', // ...... // }, // FieldPacket { // name: 'name', // ...... // }, // FieldPacket { // name: 'price', // ...... // } //] console.log(rset); // debugging //[ // RowDataPacket { id: 1, name: 'Espresso', price: 5.5 }, // RowDataPacket { id: 2, name: 'Cappuccino', price: 5.6 }, // RowDataPacket { id: 3, name: 'Latte', price: 5.7 }, //] // Processing the result set rset.forEach((item, index) => console.log(`${item.name}, ${item.price}`)); //Espresso, 5.5 //Cappuccino, 5.6 //Latte, 5.7 // Close the database connection conn.end(err => { if (err) throw err; console.log('disconnected...'); }); }); }); }); }); |
How it Works?
- [TODO]
- [TODO]
Example 3: Prepared Statement (to Prevent SQL Injection)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// testSqlPrepared.js const mysql = require('mysql'); // Create database connection const conn = mysql.createConnection({ host: 'localhost', port: '3306', user: 'username', password: 'xxxxxxxx', database: "coffeeshop" // database to be used }); // Connect to the MySQL Database server conn.connect(err => { if (err) throw err; console.log('connected...'); // Select all rows let sql = `SELECT * FROM beverage WHERE price < ?`; // ? for placeholder conn.query(sql, [5.6], (err, rset, fields) => { // Array gives the actual parameters if (err) throw err; //console.log(fields); // debugging console.log(rset); // debugging //[ // RowDataPacket { id: 1, name: 'Espresso', price: 5.5 }, //] // Processing the result set rset.forEach((item, index) => console.log(`${item.name}, ${item.price}`)); //Espresso, 5.5 // Close the database connection conn.end(err => { if (err) throw err; console.log('disconnected...'); }); }); }); |
How it Works?
- [TODO]
- [TODO]
Example 4: Commit and Rollback
[TODO]
MongoDB
I assume that you are familiar with MongoDB. Otherwise, read "MongoDB Get Started".
First, create a project directory (say "myMongoApp
"), initialize, and install the Node's MongoDB "mongodb
" driver module.
// Create a project directory mkdir myMongoApp cd myMongoApp // Initialize npm, which creates "package.json" npm init // accept the defaults // Install Node's "mongodb" driver package, under "node_modules" sub-directory npm install mongodb
Example 1: Connect to the MongoDB Database Server
[TODO]
NPM (Node Package Manager)
npm (Node Package Manager) is the most important tool for working with Node applications. It manages the Node and JavaScript packages, and can also be used to run tests and tools used in the development process. npm is installed together with Node.js. It consists of a program, also called npm
, and a registry for managing packages.
npm uses a definition file called "package.json
" to manage the package dependencies. It lists all the dependencies of a package, including name, version, description, initial file to execute, production dependencies, development dependencies, version of Node it can work with, and etc. It contains everything npm needs to fetch and run your application.
Setup a Node Project
- Create a project directory, say
myNodeApp
:mkdir myNodeApp cd myNodeApp
- Use the "
npm init
" to create a "package.json
" file for this app. It will prompt you for a number of things. Accept the defaults for the time being.npm init package name: (mynodeapp) version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to ...\myNodeApp\package.json: { "name": "mynodeapp", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
Inspect the "package.json
" created under the project directory.
Note: You might also initialize Git via "git init
". - Install your desired packages via "
npm install
", for example, "express":npm install express ...... + express@4.17.1 added 50 packages from 37 contributors and audited 126 packages
Inspect the "package.json
", which added the dependencies:{ "name": "mynodeapp", "version": "1.0.0", ...... "dependencies": { "express": "^4.17.1" } }
The package is installed under the "node_modules
" sub-directory of the project directory. - To use the module, invoke require() function to include it in your application:
const express = require('express'); // include package const app = express(); // using package ......
More on "npm install"
Global (--global or -g) Option
npm install --global packageName npm install packageName
- Without the
--global
(or-g
) option, the package will be installed under the current project in the "node_modules
" sub-directory. It is, hence, avaiable to the current project only. - With the
--global
(or-g
) option, the package will be installed under Node's "node_modules
" sub-directory. It is available for all projects. Take note that you might need to set the NODE_PATH to the global "node_modules
" directory.
Uisng locally installed packages
From npm@5.2.0, npm ships with npx package which lets you run commands from a local node module or from a global one.
npx [options] <command>[@version] [command-arg]...
By default, npx will check whether <command> exists in PATH, or in the local project binaries, and execute that.
Calling npx <command>
when <command>
isn't already in your PATH will automatically install a package with that name from the NPM registry for you, and invoke it. You can prevent this behaviour by providing --no-install
option.
[TODO] more on npx
Development (--save-dev) Option
npm install --save packageName // --save is default since npm 5
npm install --save-dev packageName
Some packages, such as those meant for testing, are not needed for production deployment. You could use --save-dev
option to mark it for development only. In "package.json
", it would be listed under "devDependencies
" instead of "dependencies
", e.g.,
"dependencies": { ...... } // install for development only with --save-dev option, not needed for production "devDependencies": { ...... }
npm run script
You can also configure npm as a shorthand to run a script or command, via "npm run
", under the "scripts
" section of "package.json
".
For example, add the following lines in "package.json
":
{
......
"scripts": {
"dev": "node test.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
......
}
Write a simple "test.js
" as follows:
console.log('testing npm run...');
Now, try:
npm run dev
npm run-script dev // same as "npm run dev"
npm run test
Note: You can also use Task Runners such as Gulp and Grunt to run tests and other external tools.
npm Command
The executable npm
is install under the base directory of Node.js.
npm help
Usage: npm <command>
where <command> is one of:
access, adduser, audit, bin, bugs, c, cache, ci, cit,
clean-install, clean-install-test, completion, config,
create, ddp, dedupe, deprecate, dist-tag, docs, doctor,
edit, explore, fund, get, help, help-search, hook, i, init,
install, install-ci-test, install-test, it, link, list, ln,
login, logout, ls, org, outdated, owner, pack, ping, prefix,
profile, prune, publish, rb, rebuild, repo, restart, root,
run, run-script, s, se, search, set, shrinkwrap, star,
stars, start, stop, t, team, test, token, tst, un,
uninstall, unpublish, unstar, up, update, v, version, view,
whoami
......
Installing a Package
npm install package-name // install latest version, local project npm install --global package-name // or -g, available to all projects npm install package-name@version // specific version of the package
Uninstalling a Package
npm uninstall package-name
npm uninstall --global package-name // or -g
[TODO] more
REFERENCES & RESOURCES
- Node.js mother site @ https://nodejs.org/.
- Introduction to Node.js @ https://nodejs.dev/.