Node.js 學習筆記(六):使用 Express 框架

2023/11/24閱讀時間約 9 分鐘

經歷過 NPM 宇宙的洗禮後,我們知道 NPM 擁有許多前人努力的結晶,使用那些套件可以大幅提升我們的開發效率。而在眾多的套件之中,有些套件被稱作框架,像是 React、Vue、Express 等等,它們比起一般的套件或函式庫 (library) 還要更大型。

本次的學習筆記會偏重在 Express 框架的使用,不過在進入到 Express 之前,先讓我們好好釐清一下,框架 (framework) 與函式庫 (library) 的差異。


框架 (framework) vs 函式庫 (library)

函式庫(library)

我們以前所使用過的 Bootstrap、Axios 等等都是函式庫,也就是別人寫好的程式碼,由我們自由決定何時在什麼地方加入到專案裡面。函式庫的目的通常只是幫助我們解決單一性質的任務,所以使用函式庫時,我們掌握了應用程式碼的主導權 (we control the flow)。

框架 (framework)

框架所做的事情比函式庫更宏遠,往往是協助我們架設應用程式。在這樣的情境下,我們願意獻出主導權 (control inversion),換取框架提供的便利功能,加速開發流程。相較於函式庫任由我們決定置入位置,框架會要求我們該把程式碼填入到哪裡。

以房屋比喻

The Difference Between a Framework and a Library 提供了很生動的比喻。作者把函式庫想像成從 IKEA 買回來的傢俱。在這情況下,我們已經有房子了,但不想要連桌椅都從頭自己製作,所以直接去 IKEA 物色合適的傢俱,全權由我們掌控。

框架則比較像蓋房子。我們手上已經有好幾份藍圖了,或許在設計和房屋架構方面,仍舊握有一點選擇權,但最終仍舊由設計師、師傅等人說了算 (不要質疑專業啊)。這些專家會告訴你,他們何時、何地需要你的 input。

You call a library, but frameworks call you.

什麼是 Express

截至目前,我們把框架吹得很厲害,現在就來看看 Express 是何方神聖吧。Express 在官網號稱是 Node.js 的網頁框架,主打快速、彈性而且輕便

Fast, unopinionated, minimalist web framework for Node.js

具體上來說,Express 能夠協助我們的事情族繁不及備載,以下列出較為常用的:

  • 架設伺服器監聽 client request
  • 把傳送進來的 request 解析成 JavaScript 物件
  • 將 request 分配到對應的路由
  • 製作出 http response 以及相關內容

這些事情就算不透過 Express 也可以辦到,但我們就要花不少時間去架設基礎設施,節省這些時間,可說是 Express 帶來的最大價值喔。


架設第一台 Express 主機

正式上工之前,不免俗還是要安裝 Express,輸入我們熟悉的指令 npm init 以及 npm i express。其實 Express 官網的 Getting started 已經完整列出架設主機的步驟了,我們來參考一下 👁️

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

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

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});


我們先用關鍵字 require 把 express 模組帶入到 script 裡面,然後建立一個名為 app 的變數,執行 express 套件後存入到 app 變數。接著和之前用 Node.js 建立伺服器一樣,我們將 port 號碼定義為 3000。

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


如果我們用 console.log 把 app 列印出來,會發現 app 本身是一個巨大的物件,裡面包含了許多 Express 準備的 method。

raw-image

接著我們要啟動 port 3000 的伺服器,利用 app.listen() 帶入 port 號以及 callback 函式,確認伺服器是否有順利啟用、監聽傳進來的 request。

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});


這個時候將 http://localhost:3000/ 輸入到瀏覽器看看,畫面呈現出 Cannot GET / 的錯誤訊息。這並不是 404 的錯誤代碼,而且 console.log() 也跑出伺服器開始監聽的文字訊息了,代表伺服器啟動了沒錯,但我們沒有指示伺服器要回傳什麼內容給 client。

raw-image

Request & Response 物件

我們現在要針對特定路由發送過來的 request,傳送 response 回去。由於目前這個網站尚未規畫好路由,所以先直接把根目錄 / 帶入到 app.get() 。get 這個動詞,代表 client 和 server 要求資料。

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


路徑後面的第二個參數是一個 callback 函式,裡面有兩個參數 req 以及 res,都和 app 一樣是龐大的物件。req 是 Express 將 client 傳進來的 request 解析成 JavaScript 物件,而 res 物件則提供了很多回覆 http response 的方法可用。其中一個便是 res.send()。裡面可以帶入純字串、HTML tag、物件、陣列等等。

這次我們改用 Postman 來檢查,可以看到朝 localhost: 3000 傳送 get request 之後,伺服器成功回傳了 Hello World! 純文字回來。打開 response header,像是 content-type 等等的 metadata,Express 都幫我們處理好了,所以不必像之前使用 Node.js 還需要手動設定 🥹

raw-image

走到這邊,我們終於搭建人生第一台 Express 網站主機囉!


結語

最後我們來比對一下 Node.js 與 Express 搭建伺服器的程式碼:

Node.js

const http = require('http')
const hostname = 'localhost' // 127.0.0.1
const port = 3000

const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('hello world!')
})

server.listen(port, hostname, () => {
console.log(`the server is running on http://${hostname}:${port}`)
})


Express

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

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

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});


除了不用帶入 http 模組之外,Express 還幫我們處理了 response header 和 status code,因此程式碼簡潔了不少。當然,若要進行客製化的調整,Express 的 res 物件也都有提供 method。


參考資料


16會員
34內容數
Bonjour à tous,我本身是法文系畢業,這邊會刊登純文組學習網頁開發的筆記。如果能鼓勵更多文組夥伴一起學習,那就太開心了~
留言0
查看全部
發表第一個留言支持創作者!