Contents

Install Node.js on Mac and Hello web server

1 Environment

  • Mac OS Catalina 10.15.7

2 Install via nodebrew

Firstly, I installed it via brew.

Nodebrew is Node.js version manager.

I installed via brew.

1
$ brew install nodebrew

Check version

1
2
$ nodebrew -v
nodebrew 1.1.0

However, something is wrong for installing over brew.

1
2
$ nodebrew list
No such file or directory at /usr/local/bin/nodebrew line 575.

Some blogse.g. teratail - nodebrew ls でエラーになります。 says installing over brew (after Yosemite) does note work well.

So, I installed it following official documentation.

Uninstall nodebrew.

1
$ brew uninstall nodebrew

Then installed it by curl.

1
$ curl -L git.io/nodebrew | perl - setup

And add PATH to ~/.bashrc

1
export PATH=$HOME/.nodebrew/current/bin:$PATH" >> ~/.bashrc

Then load ~/.bashrc

1
source ~/.bashrc

check version

1
2
$ nodebrew -version
nodebrew 1.1.0

node ls

1
2
3
4
$ nodebrew list
not installed

current: none

3 Install node.js

3.1 Check installable version

1
$ nodebrew ls-remote

3.2 Install Node.js

According to nodejs.org, Active LTS version is Node.js 14 as of April 2021. So, I installed the latest 14.17.0

1
$ nodebrew install v14.17.0

Check version and switch to v14.17.0

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ node -v
v15.11.0

$ npm -v
7.6.3

$ nodebrew use v14.17.0
use v14.17.0

$ node -v
v14.17.0

$ npm -v
6.14.13

The places where npm and node are installed

1
2
3
4
5
$ which npm
/Users/xxxx/.nodebrew/current/bin/npm

$ which node
/Users/xxxx/.nodebrew/current/bin/node

4 Run simple web server

4.1 Init by npm

At your project directory, initialize npm. npm is a package manager for node.js.

1
2
3
4
$ npm init

$ ls
main.js			node_modules		package-lock.json	package.json

Note that package-lock.json will be updated after running server.

Then you can fill interactive command input for making package.json. In my case,

 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
package name: (second-server) 
version: (1.0.0) 
description: second server test
entry point: (index.js) main.js
test command: 
git repository: 
keywords: 
author: tato
license: (ISC) 
About to write to /Users/xxxx/dev/nodejs-test/second-server/package.json:

{
  "name": "second-server",
  "version": "1.0.0",
  "description": "second server test",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "tato",
  "license": "ISC"
}


Is this OK? (yes) 

4.2 write application code

As I want to use HTTP response code package. I installed it.

1
$ npm i http-status-codes -S

Then write code.

main.js

 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
const getJsonString = obj => {
    return JSON.stringify(obj, null, 2);
}

const port = 3000,
    http = require("http"),
    httpStatus = require("http-status-codes"),
    app = http.createServer();

app.on("request", (req, res) => {
    var body = [];

    // process data in callback function
    req.on("data", (bodyData) => {
        body.push(bodyData);
    });

    // after data transmission is completed
    req.on("end", () => {
        body = Buffer.concat(body).toString();
        console.log(`Request Body Content : ${body}`);
    });

    console.log(`Method: ${getJsonString(req.method)}`);
    console.log(`URL: ${getJsonString(req.url)}`);
    console.log(`Headers: ${getJsonString(req.headers)}`);

    res.writeHead(httpStatus.OK, {
        "Content-Type": "text/html"
    });

    let responseMessage = "<h1>Hello, Node.js!</h1>";
    res.end(responseMessage);

    console.log(`Sent a response : ${responseMessage}`);
});

app.listen(port);
console.log(`The server has started and is listening on port number: ${port}`);

4.3 Run web server

Run Node.js server is quite simple.

1
2
$ node main
The server has started and is listening on port number: 3000

Then access to http://localhost:3000 from browser.

../../../images/nodejs/Hello-Nodejs.jpg

On access to the web server, you can check JSOn string below.

 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
Method: "GET"
URL: "/"
Headers: {
  "host": "localhost:3000",
  "connection": "keep-alive",
  "cache-control": "max-age=0",
  "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"90\", \"Google Chrome\";v=\"90\"",
  "sec-ch-ua-mobile": "?0",
  "upgrade-insecure-requests": "1",
  "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
  "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
  "sec-fetch-site": "none",
  "sec-fetch-mode": "navigate",
  "sec-fetch-user": "?1",
  "sec-fetch-dest": "document",
  "accept-encoding": "gzip, deflate, br",
  "accept-language": "ja,en-US;q=0.9,en;q=0.8",
  "cookie": "_ga=GA1.1.658362304.1615544123"
}
Sent a response : <h1>Hello, Node.js!</h1>
Request Body Content : 
Method: "GET"
URL: "/favicon.ico"
Headers: {
  "host": "localhost:3000",
  "connection": "keep-alive",
  "pragma": "no-cache",
  "cache-control": "no-cache",
  "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"90\", \"Google Chrome\";v=\"90\"",
  "sec-ch-ua-mobile": "?0",
  "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36",
  "accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
  "sec-fetch-site": "same-origin",
  "sec-fetch-mode": "no-cors",
  "sec-fetch-dest": "image",
  "referer": "http://localhost:3000/",
  "accept-encoding": "gzip, deflate, br",
  "accept-language": "ja,en-US;q=0.9,en;q=0.8",
  "cookie": "_ga=GA1.1.658362304.1615544123"
}
Sent a response : <h1>Hello, Node.js!</h1>
Request Body Content : 

This code also parse request body data. I could check that by curl command.

1
$ curl --data "user=tato&pass=secret" http://localhost:3000

Standard output shows request parameter and value.

1
Request Body Content : user=tato&pass=secret

References