[2] 快速學會 node.js 基礎入門

·

5 min read

0. 說明

本篇將完整說明如何使用 node.js 建立一個簡單的 web,也介紹如何對 mysql 的資料庫操作。

本篇文章是一個步驟指導,建議可以搭配影片一起學習:

1. 安裝 node.js

安裝最新版:

$ sudo apt-get install curl
$ curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -

開始安裝:

$ sudo apt-get install nodejs

檢查版本:

$ node -v
v14.15.4

2. 建立專案

建立資料夾:

% mkdir test_node
% cd test_node

進入資料夾後,進行初始化的動作:

% npm init

接下來會進行一連串的詢問:

Press ^C at any time to quit.
package name: (test_node) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /Users/jake/Desktop/test_node/package.json:
{
  "name": "test_node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Is this OK? (yes)

按下 OK,專案就建立好了。

3. 第一次執行 node

用 Visual Studio Code 開啟專案資料夾

建立 index.js 檔案:

console.log('Hello');

開啟 terminal 視窗,用 node 執行 index.js:

% node index.js

會印出:

Hello

3-1. 安裝 nodemon

安裝 nodemon:

% npm install -g nodemon

修改 package.json,新增:

"scripts": {
    "dev": "nodemon index.js"
},

執行:

% npm run dev

如此一來,只要修改程式碼儲存後,就會自動重新啟動 Node

4. Web 框架

node.js 的 web 框架有很多種,這邊介紹最受歡迎的 express 框架來製作 web

安裝 express:

% npm install express --save

修改 index.js:

const express = require("express");
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send(' Hello World!');
});

app.listen(port, () => {
    console.log(`Listening at http://localhost:${port}`);
});

在瀏覽起開啟:localhost:3000 ,會顯示 Hello World! 字串

程式碼解說:

const express = require("express"); //載入 express 模組
const app = express(); //初始化 express
const port = 3000; //web port 設定 3000

/*
網址為 / 時,方法設定為 GET
*/
app.get('/', (req, res) => {
    res.send('Hello World!'); //印出 Hello World!
});

/*
開啟 web
*/
app.listen(port, () => {
    console.log(`Listening at http://localhost:${port}`);
});

5. EJS 框架

程式與資料如何跟 HTML 標籤做互動,這邊會使用 EJS 框架

安裝 EJS 框架:

$ npm install ejs --self

使用 EJS 在專案內新增一個資料夾 views 在 views 資料夾內新增一個檔案 index.ejs:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>Hello EJS</h1>
</body>

</html>

修改 index.js:

const express = require("express");
const app = express();
const port = 3000;

app.set('view engine', 'ejs'); // 設定 view 的框架為 EJS

app.get('/', (req, res) => {
    res.render("index"); // 將結果傳入給 index.ejs
});

app.listen(port, () => {
    console.log(`Listening at http://localhost:${port}`);
});

接下來要從 index.js 傳出資料給 index.ejs

修改 index.ejs,設定變數名稱:

<h1>Hello <%=name%></h1>

EJS 用 <%%> 語法來表示,name 則表示設定了一個名為 name 的變數,而等號表示直接呈現出來。

修改 index.js:

app.get('/', (req, res) => {
    res.render("index", {
        name: "Jake" //表示出數一個變數叫 name,然後給予內容為 "Jake"
    });
});

EJS 的變數呈現也可以這樣寫:

<%-name%>

傳出陣列給 EJS 如果要傳出多個資料給 EJS,可以使用陣列的方式傳出,修改 index.js:

app.get('/', (req, res) => {
  res.render("index", {
      name: "Jake",
      names: ["Jake", "John", "David"]
  });
})

然後接著在 index.ejs 新增:

<% for(var i = 0; i < names.length; i++) { %>
    <h1>
        Hello <%- names[i] %>
    </h1>
<% } %>

任何 EJS 語法都寫在 <% ... %> 範圍之內,所以在這邊使用一個 for 迴圈去走訪 names 這個陣列。

6. 模組化架構

學習如何將程式架構模組化

目前的程式碼會將所有邏輯寫在 index.js:

app.get('/', (req, res) => {
    res.render("index", {
        name: "Jake",
        names: ["Jake", "John", "David"]
    });
});

但網頁的邏輯不是只有輸出資料給 EJS,還有資料的輸入、資料庫的使用或者其他判斷,所以將所有邏輯寫在這邊是不智之舉,在這邊就要介紹模組化架構,使用 exports 方式來實作。

新增一個 main.js:

exports.showMain = function showMain(req, res) {
    res.render("index", {
        name: "Jake",
        names: ["Jake", "John", "David"]
    });
};

這邊使用 exports 把 showMain 這個 function 給輸出出去。

然後就可以在 index.js 把 main.js 給 require 進來:

const main = require("./main.js");

然後就可以去呼叫 main.js 裡面所 exports 出來的函式了:

app.get('/', (req, res) => {
    main.showMain(req, res);
});

7. 使用 body-parser

body-parser 主要可以處理 http request 的資料解析,body-parser 已經被納入 Express 的框架裡,所以只要

定義好要解析哪幾種格式即可,修改 index.js:

// 解析 application/x-www-form-urlencoded
app.use(express.urlencoded({
    extended: false,
}));

// 解析 application/json
app.use(express.json());

接下來就可以透過 GET 或者 POST 的方法將資料送給 server

如果是 GET 的方法,取值的方式:

const name = req.query.name;

如果是 POST 的方法,取值的方式:

const name = req.body.name;

GET 範例 index.js:

app.get('/', (req, res) => {
    main.showMain(req, res);
});

main.js:

exports.showMain = function showMain(req, res) {
    const name = req.query.name;

    res.render("index", {
        name: name
    });
};

POST 範例 index.js:

app.post('/', (req, res) => {
    main.showMain(req, res);
});

main.js:

exports.showMain = function showMain(req, res) {
    const name = req.body.name;

    res.render("index", {
        name: name
    });
};

8. 安裝 Docker

之前篇幅主要是對 node.js 的基礎操作有一個了解,接下來就會針對 mysql 的操作做說明,這邊會使用 Docker 來建立本機端的資料庫

先到官方網站下載:@[docs.docker.com/desktop/mac/install/]

9 .安裝 Docker: mysql

安裝好 Docker,就可以利用指令來做安裝,首先先安裝 mysql

下載 mysql:

% docker pull mysql

開啟 mysql 的指令為: docker run --name <自定義容器名字> -e MYSQL_ROOT_PASSWORD=<設定資料庫密碼> -d -p :<容器的port> mysql:latest

% docker run --name mysql1 -e MYSQL_ROOT_PASSWORD=123456 -d -p 3306:3306 mysql:latest

登入 mysql 容器:

% docker exec -it mysql1 bash

登入 mysql:

# mysql -u root -p

接著輸入剛剛設定的 mysql 密碼,即可以登入

設定可以讓外部程式登入:

ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'password';
flush privileges;

10. 安裝 Docker: phpmyadmin

phpmyadmin 是一個 web 的 mysql 操作工具

直接執行安裝:

% docker run --name myadmin -d --link mysql1:db -p 9100:80 phpmyadmin

在瀏覽器打上:http://127.0.0.1:9100/即可開啟

11. 開啟資料庫

接下來就可以在 node.js 上來操作 mysql 了

先安裝 mysql 的 node 模組:

% npm install mysql --self

接下來修改 index.js

將 mysql 匯入進來:

const mysql = require("mysql");

設定連線到 mysql 的 ip、帳號、密碼、資料庫名稱

const pool = mysql.createPool({
    name: "test",
    host: 'x.x.x.x',       // 連線 ip
    user: 'root',          // 連線帳號
    password: 'xxxxxxxx',  // 連線密碼
    database: 'demo'  .    // 資料庫名稱
});

開啟資料庫連線:

pool.getConnection(function (err, connection) {
    if (err) { // 發生錯誤時的處理
        console.log(err);
        return;
    }
});

進行 sql 指令查詢:

const sql = "SELECT * FROM device";
connection.query(sql, function (errorQuery, rows) {
    connection.release(); // 查詢完之後,因為不會再連到資料庫,所以進行關閉連線

    if (errorQuery) {
        console.log('Error SELECT to Db: ', errorQuery);
        return;
    }

    console.log(rows); // 將查詢到的資料列印出來
});

12. 模組化

接下來繼續整理程式碼,將 mysql 相關的程式碼做一個模組化的整理

新增一個 mysql.js:

const mysql = require("mysql");

//
const pool = mysql.createPool({
    name: "test",
    host: 'x.x.x.x',       // 連線 ip
    user: 'root',          // 連線帳號
    password: 'xxxxxxxx',  // 連線密碼
    database: 'demo'  .    // 資料庫名稱
});

新增一個 function:

exports.query = function query(sql, success) {
}

這個函式有兩個輸入為 sql 跟 success,並且使用 exports ,讓別的 .js 檔案也可以呼叫。

接下來把開啟與查詢資料庫的程式碼放入:

exports.query = function query(sql, success) {
    //
    pool.getConnection(function (err, connection) {
        if (err) {
            console.log(err);
            return;
        }

        connection.query(sql, function (errorQuery, rows) {
            connection.release();

            if (errorQuery) {
                console.log('Error SELECT to Db: ', errorQuery);
                return;
            }

            success(rows); //這邊將結果 rows 輸出出去
        });
    });
}

所以 main.js 的要呼叫 mysql.js 時,必須要先匯入:

const mysql = require("./mysql.js");

然後就可以呼叫 query 這個函式,第一個輸入使用字串,第二個輸入使用函式,並且將回傳的資料列印出來:

mysql.query("SELECT * FROM device", function (rows) {
    console.log(rows);
});