
- 能夠在伺服器上面運行 JavaScript 的應用平台環境
- NVM(Node Version Manager)
- 處理專案時需要不同的 Node 版本來執行(因有些 npm 模組有版本相容性問題)
- 下載
1
| curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
|
開始一個專案
npm init
- 在
package.json
的 scripts 中新增”start”指令
npm run start
fs(File System)模組
1
| const fs = require('fs')
|
- 讀取檔案
- 同步
readFileSync(檔案名稱, 編碼)
- 非同步
readFile(檔案名稱, 編碼, 要做的處理)
- Promise
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
| //同步讀取 try{ const data = fs.readFileSync('hello.txt', 'utf8'); console.log("檔案內容:", data); } catch(err){ console.log("讀取檔案錯誤:", err) }
//非同步讀取 fs.readFile('hello.txt', 'utf8', (err, data) => { if(err){ console.log("讀取檔案錯誤", err); return; } console.log("檔案內容:", data) })
//promise版本 const fsPromise = require('fs').promises; async function readAndWriteFile(){ try{ const content = await fsPromise.readFile('hello.txt', 'utf8'); await fsPromise.writeFile('hej.txt', content + '\n new new world~~~~'); console.log("done"); } catch(err){ console.error("something wrong:", err) } } readAndWriteFile();
|
1 2 3 4 5 6 7
| const path = require('path');
const fullPath = path.join(__dirname, 'files', 'hello.txt'); console.log("檔案名稱:", path.basename(fullPath)); console.log("副檔名:", path.extname(fullPath)); const pathInfo = path.parse(fullPath); console.log("路徑資訊:",pathInfo);
|
1 2 3 4 5
| const myUrl = new URL('https://jsonplaceholder.typicode.com/comments?postId=1') console.log('主機名:', myUrl.pathname) console.log('路徑名:', myUrl.pathname) console.log('搜尋參數:', myUrl.searchParams.get('postId')) console.log('完整搜尋字串', myUrl.search)
|
建立基本 http 伺服器
1
| const http = require('http')
|
- 定義 server
http.createServer
設定 server
res
設定內容
res.setHeader
設定網頁內容/類型
res.writeHead
網頁狀態碼
res.send
寫入 html 內容
res.end
req
取得網址
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const server = http.createServer((req, res) => { res.setHeader('Content-Type', 'application/json')
if(req.url === '/'){ res.writeHead(200); res.end(JSON.stringify({ message: 'Welcome to Home Page' })) } else if(req.url === '/api/users'){ res.writeHead(200); res.end(JSON.stringify({ users: ['user1', 'user2']})) } else { res.writeHead(404); res.end(JSON.stringify({message: 'not found'})) } })
|
1 2 3
| server.listen(3200, () => { console.log('伺服器運行在 http://localhost:3200/') })
|
nodemon
它會監視你的程式碼有無任何更改,並自動重新啟動服務,這時只要刷新你的瀏覽器就能看到改動
- 下載
npm install --save-dev nodemon
- 修改 package.json
- 在 scripts 中新增
"dev": "nodemon index.js"
npm 下載方式
- 下載時會出現在 package.json 中的
"devDependencies"
- 使用
npm install --production
下載非開發版本需要的
- 用於非開發版本,因為 nodemon 只用於開發,所以下這個指令不會安裝 nodemon
- 部署時使用
Express
- 下載
npm install express
- 拿出 express
1
| const express = require('express')
|
1 2 3 4
| const app = express() app.get('/', (req, res) => { res.send("<h1>hello world!!!</h1>") })
|
1 2 3
| app.listen(3200, () => { console.log("伺服器運行在:http://localhost:3200/") })
|
Middleware
Middleware 是 Express 處理 HTTP 請求的中間處理層,可執行任何任務
1 2 3 4
| const firstMiddleware = (req, res, next) => { console.log("111111") next() }
|
1
| app.use(firstMiddleware)
|
使用情境
logger 通常放所有頁面之前
- 驗證/權限判斷
- 新增判斷的 function
- 把 function 帶入
.get()
的參數裡
- 用
req.query
取得網址資訊(/users 後面的?以後)
1 2 3 4 5 6 7 8 9 10 11 12 13
| app.get('/users', auth, (req, res) => { res.send("<h1>Users List</h1>") })
function auth(req, res, next) { // 網址是/user?admin=true就會顯示 if(req.query.admin === 'true'){ next() return } //其餘顯示沒有權限 res.send("<h2>您沒有權限</h2>") }
|
- 回傳 json
res.json({ message: "hello" })
- 通常畫面會搭配 vue,所以
.send()
可以改為回傳資料
1 2 3 4 5 6 7 8 9 10 11 12 13
| app.get('/users', auth, (req, res) => { // res.send("<h1>Users List</h1>") res.json({ message: "使用者清單" }) })
function auth(req, res, next) { if(req.query.admin === 'true'){ next() return } // res.send("<h2>您沒有權限</h2>") res.json({ message: "您沒有權限" }) }
|
專案結構化
- 在專案中新增 src 資料夾
- 在 src 中新增 routes 與 middlewares 資料夾
- 將 index.js 中的 middlewares 跟 routes 拆到資料夾中
- 最後加
module.exports = middleware名稱
logger
1 2 3 4 5 6 7 8 9 10
| // 路徑:middlewares/logger.js
// 處理 log 的 middleware function logger(req, res, next) { console.log("log") next() }
// export 出去 module.exports = logger
|
router
- 引入 express,從 express 拿出
Router()
- 將之前的
app
改為 router
- 有用到 middleware 則需要用
require("檔案路徑")
引入
const auth = require("../middlewares/auth.js")
- 最後加
module.exports = router
1 2 3 4 5 6 7 8 9
| const express = require("express") const router = express.Router()
router.get('/', (req, res) => { let time = new Date() res.json({ message: "首頁", visit_time: time.toLocaleString() }) })
module.exports = router
|
index.js
- 引入所有建立好的 router 跟 middlewares
- use 他們
1 2 3 4 5 6 7 8 9 10 11 12 13
| const express = require('express') const app = express() const indexRouter = require("./src/routes/index.js") const productsRouter = require("./src/routes/products.js") const usersRouter = require("./src/routes/users.js") const logger = require("./src/middlewares/logger.js")
app.use(logger) app.use(indexRouter) app.use(productsRouter) app.use(usersRouter)
app.listen(3200)
|