DEV Community

Rittwick Bhabak
Rittwick Bhabak

Posted on

Introduction to Node.js

1. Introduction, Set up and Basics

1

To check node version in my computer: node -v
To start node console: node

Running a javascript file 'test.js'

//filename test.js
const name = 'rittwick'
console.log(name)
Enter fullscreen mode Exit fullscreen mode

Command to run this file: node test

2. Basics

1. The global object

There is an object called global in node. The same object in browser console is called window.
Checkout console.log(global); in node console.
This object contains functions like setInterval, setTimeout etc.
File globaltut.js:

const interval = setInterval(() => {
    console.log('In the interval');
}, 1000);

setTimeout(() => {
    console.log("In the timeout")
    clearInterval(interval);
}, 5000);
Enter fullscreen mode Exit fullscreen mode

The output will be:

In the interval
In the interval
In the interval
In the interval
In the timeout
Enter fullscreen mode Exit fullscreen mode

Finding the filename and directory name in node

console.log(__dirname);
console.log(__filename);
Enter fullscreen mode Exit fullscreen mode

Some attributes are present in node and not in window and some are present in window and not in node global object.For example 'document' is present in window object and not in node.

2. Modules and Require

We've two files: people.js and data.js
people.js contains:

const persons = ['arun', 'shankar', 'vinod', 'irfan'];
console.log(`From people.js: ${persons}`);
Enter fullscreen mode Exit fullscreen mode

data.js contains:

const xyz = require('./people');
console.log(`From data.js: `, xyz);
Enter fullscreen mode Exit fullscreen mode
From people.js: arun,shankar,vinod,irfan
From data.js:  {}
Enter fullscreen mode Exit fullscreen mode

This way persons array is not available in data.js. We have to manually send from person.js to data.js.

people.js have to contain a line:

module.export = persons;
Enter fullscreen mode Exit fullscreen mode

Then only person is accessible to data.js.
Note: In require statement the path should be a relative path not an absolute path

Exporting multiple things from person.js to data.js

people.js

const persons = ['arun', 'shankar', 'vinod', 'irfan'];
const ages = [12, 22, 44, 9];

module.exports = {
    personsList: persons,
    agesList: ages
}
Enter fullscreen mode Exit fullscreen mode

data.js

const xyz = require('./people');
console.log(xyz.personsList);
console.log(xyz.agesList);
Enter fullscreen mode Exit fullscreen mode

Output on running node data:

[ 'arun', 'shankar', 'vinod', 'irfan' ]
[ 12, 22, 44, 9 ]
Enter fullscreen mode Exit fullscreen mode

persons array of people.js --> personsList array of data.js

To call persons array of people.js as persons in data.js:
people.js:

module.export = {
    persons: persons,
    ages: ages
}
Enter fullscreen mode Exit fullscreen mode

There is a shortcut of these method:

module.export = {
    persons, ages
}
Enter fullscreen mode Exit fullscreen mode

Now there are different types of accessing tricks:
Trick 1

//people.js
const persons = ['arun', 'shankar', 'vinod', 'irfan'];
const ages = [12, 22, 44, 9];

module.exports = {
    persons, ages
}


// data.js
const xyz = require('./path_of_people')
console.log(xyz.persons);
console.log(xyz.ages);
Enter fullscreen mode Exit fullscreen mode

Trick 2

//people.js
const persons = ['arun', 'shankar', 'vinod', 'irfan'];
const ages = [12, 22, 44, 9];

module.exports = {
    persons, ages
}


// data.js
const { persons, ages } = require('./path_of_people')
Enter fullscreen mode Exit fullscreen mode

Trick 3

//people.js
const persons = ['arun', 'shankar', 'vinod', 'irfan'];
const ages = [12, 22, 44, 9];

module.exports = {
    personsList: persons,
    agesList: ages
}


// data.js
const { personsList } = require('./path_of_people')
//agesList is not accessible now. Only personsList is imported here.
Enter fullscreen mode Exit fullscreen mode

node also has some built in modules: For example:

// OS MODULE
const os = require('os');
const os = require('os');
console.log(os.platform());
console.log(os.homedir());
Enter fullscreen mode Exit fullscreen mode

Another important built in module is filesystem module

3. The filesystem

Reading the file

const fs = require('fs');
fs.readFile('./textfile.txt', (err, data) => {
    if(err){
        console.log('Some error happened');
    }else{
        console.log(data);
    }
})
Enter fullscreen mode Exit fullscreen mode

Output:

<Buffer 6c 6f 72 65 6d 20 69  ... 94 more bytes>
Enter fullscreen mode Exit fullscreen mode

data is a package of objects. To read it we have to convert it into string.

console.log(data);
//Output: <Buffer 6c 6f 72 65 6d 20 94 more bytes>

console.log(data.toString());
// Output: This is a nice tutorial
Enter fullscreen mode Exit fullscreen mode

Note: readFile is asynchronous function. Following code reveals that:

const fs = require('fs');
fs.readFile('./textfile.txt', (err, data) => {
        console.log(data.toString());
})
console.log('last line of the code')
Enter fullscreen mode Exit fullscreen mode

The output will be:

last line of the code
This is a nice tutorial
Enter fullscreen mode Exit fullscreen mode

Wirting the file

fs.writeFile('./new.txt', 'hello rittwick', () => {
    console.log('File was written');
}
Enter fullscreen mode Exit fullscreen mode

writeFile is also a asynchronous function. This function overwrites the file if the file already exists and creates, writes the file if the file already not exists.

4. Creating and Removing Directories

fs.mkdir('./assets', (err)=>{
        if(err){
            console.log('Some error happened 1');
        }else{
            console.log('Folder created');
        }
    })
Enter fullscreen mode Exit fullscreen mode

mkdir creates the folder if does not exists. If exists then returns error.

Creating the folder if not exists and deleting otherwise:

if(!fs.existsSync('./assets')){
    fs.mkdir('./assets', (err)=>{
        if(err){
            console.log('Some error happened 1');
        }else{
            console.log('Folder created');
        }
    })
}else{
    fs.rmdir('./assets', (err) => {
        if(err){
            console.log('Some error happened 2');
        }else{
            console.log('Folder Deleted');
        }
    })
}
Enter fullscreen mode Exit fullscreen mode

5. Deleting Files

if(fs.existsSync('./deleteme.txt')){
    fs.unlink('./deleteme.txt', err => {
        if(err){
            console.log('Some error occurred ');
        }else{
            console.log('File deleted successful');
        }
    })
}
Enter fullscreen mode Exit fullscreen mode

unlink deletes the file if exists otherwise returns an error.

4. Streams and Buffers

Starts using data before it has finished loading completely. For example loading a chunk of data and watching the video before the video fully loads.

Reading a stream

const readStream = fs.createReadStream('./docs/huge.txt');
readStream.on('data', (chunk)=>{
    console.log('-------NEW CHUNK---------');
    console.log(chunk);
})
Enter fullscreen mode Exit fullscreen mode

This will output some buffers. To get a readable text:
console.log(chunk.toString())
OR there we can directly encode it to a readable string:

const readStream = fs.createReadStream('./docs/huge.txt', { encoding:'utf8' });
Enter fullscreen mode Exit fullscreen mode

Writing a Stream

const readStream = fs.createReadStream('./docs/huge.txt', { encoding:'utf8' });
const writeStream = fs.createWriteStream('./docs/newhuge.txt');

readStream.on('data', (chunk)=>{
    writeStream.write('\nNEW CHUNK\n');
    writeStream.write(chunk);
})
Enter fullscreen mode Exit fullscreen mode

Piping

Reading streams and writing it into a writestream.

const readStream = fs.createReadStream('./docs/huge.txt', { encoding:'utf8' });
const writeStream = fs.createWriteStream('./docs/newhuge.txt');

readStream.pipe(writeStream);
Enter fullscreen mode Exit fullscreen mode

3. Client and Servers

Creating a server in node

const http = require('http');

const server = http.createServer((req, res)=>{
    console.log('Everytime a request is made, I pops up.');
})

Enter fullscreen mode Exit fullscreen mode

The callback function in the above code block runs every time a request is made.
The arguments of the callback function are req and res. In req, the information about incoming request is present and through req the response is sent back.

This alone is not doing anything. The server have to actively listen to the requests.
server.listen()

server.listen(3000, 'localhost', ()=>{
    console.log('Listening to port number 3000')
});
Enter fullscreen mode Exit fullscreen mode

4. Requests & Responses

1.The Request Object

Getting the request url and request method: req.url & req.method

const server = http.createServer((req, res)=>{
    console.log(req.url, req.method);
})
Enter fullscreen mode Exit fullscreen mode

2. The Response Object

Sending response is a three step process:

  1. setting the response header
  2. writing the response
  3. sending the response
const server = http.createServer((req, res)=>{
    //Setting response header
    res.setHeader('Content-type', 'text/plain');

    //Writing the response
    res.write(`Hello, Rittwick!`);

    //Sending the response
    res.end();
})
Enter fullscreen mode Exit fullscreen mode

In the above code we're just sending plain text. We can also send html.

const server = http.createServer((req, res)=>{
    console.log(req.url, req.method);
    //Setting response header to 'text/html'
    res.setHeader('Content-type', 'text/html');

    res.write('<h1>Hello! Rittwick</h1>');

    res.end();
})
Enter fullscreen mode Exit fullscreen mode

The browse automatically adds the other tags body, html and head. We can overwrite them.

const server = http.createServer((req, res)=>{
    res.setHeader('Content-type', 'text/html');

    res.write('<head><title>Hello page </title></head>');
    res.write('<h1>Hello! Rittwick</h1>');

    res.end();
})
Enter fullscreen mode Exit fullscreen mode

3. Sending html files

const server = http.createServer((req, res)=>{
    res.setHeader('Content-type', 'text/html');

    fs.readFile('./views/index.html', (err, data) => {
        if(err){
            res.end();
        }else{
            res.write(data);
            res.end();
        }
    })
})
Enter fullscreen mode Exit fullscreen mode

Instead of doing the following in two lines, we can do it in one line res.end(data)

res.write(data)
res.end()

Instead the shortcut
res.end(data)
Enter fullscreen mode Exit fullscreen mode

When we are sending the only one data, like the above then only this shortcut can be applied.

4. Basic Routing

const server = http.createServer((req, res)=>{
    res.setHeader('Content-type', 'text/html');
    let path = './views/';
    switch(req.url){
        case '/':
            path += 'index.html';
            break;
        case '/about':
            path += 'about.html';
            break;
        default:
            path += '404.html';
            break;
    }
    fs.readFile(path, (err, data) => {
        res.end(data);
    })
})
Enter fullscreen mode Exit fullscreen mode

5. Status Codes

Setting status codes is very easy.
res.statusCode=<your_status_code> for example res.statusCode=200

In the following code block example, status code is set according to need.

const server = http.createServer((req, res)=>{
    res.setHeader('Content-type', 'text/html');
    let path = './views/';
    switch(req.url){
        case '/':
            path += 'index.html';
            res.statusCode = 200;
            break;
        case '/about':
            path += 'about.html';
            res.statusCode = 200;
            break;
        default:
            path += '404.html';
            res.statusCode = 404;
            break;
    }
    fs.readFile(path, (err, data) => {
            res.end(data);
    })
})
Enter fullscreen mode Exit fullscreen mode

Some more important points:

  1. 100 range - Informative codes for browser
  2. 200 range - Success codes
  3. 300 range - redirection codes
  4. 400 range - User side errors
  5. 500 range - Server errors

Example:

  • 200 - OK
  • 301 - Resource moved
  • 404 - Page not found
  • 500 - Internal server error

6. Redirects

Suppose my website has an established route '/about'. I wish someone who also visits to '/about-me' get redirected to '/about'. The below code does that:

  • First set the statuscode to 301 res.statusCode=301;
  • Then do res.setHeader('Location', '/about');
  • Send the request res.end()
        case '/about':
            path += 'about.html';
            res.statusCode = 200;
            break;
        case '/about-me':
            res.statusCode = 301;
            res.setHeader('Location', '/about');
            res.end();
            break;
        default:
            path += '404.html';
            res.statusCode = 404;
            break;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)