
กำลังโหลด...

กำลังโหลด...

เห็นน้องกด Ctrl+C แล้วรันใหม่ทั้งเช้าแล้ว — หยุดทรมานตัวเองได้แล้ว 555
Boss ตัวนี้ให้จัดบ้านให้เรียบร้อย: nodemon ให้รีสตาร์ทเอง, dotenv สำหรับค่าตั้งค่า, และ npm scripts ให้รันด้วยคำสั่งเดียว
ย้ำเรื่องเดียว — .env ต้องอยู่ใน .gitignore ถ้าหลุดขึ้น GitHub เมื่อไหร่คือเรื่องใหญ่
เป้าหมายของ Boss นี้: ทำให้สภาพแวดล้อมการทำงานสะดวกด้วย nodemon และ dotenv แล้วประกอบทุกอย่างใน Chapter 2 เข้าด้วยกัน
จบ Boss นี้คุณจะ
nodemon ให้ Server รีสตาร์ทเองเมื่อแก้โค้ด.env เก็บค่าตั้งค่าแยกออกจากโค้ด.env)npm scripts ให้รันโปรเจคด้วยคำสั่งสั้นๆตลอด Mission 2-3 คุณต้องกด Ctrl+C แล้ว node index.js ใหม่ทุกครั้งที่แก้โค้ด — น่ารำคาญมาก
และจะยิ่งน่ารำคาญขึ้นเรื่อยๆ
nodemon คือโปรแกรมที่คอย จับตาดูไฟล์ ถ้าไฟล์ไหนถูกแก้และ save มันจะรีสตาร์ท Server ให้เอง
ไม่มี nodemon มี nodemon
+---------------------+ +----------------------------+
| แก้โค้ด | | แก้โค้ด |
| save | | save |
| Ctrl + C | | (nodemon เห็นว่าไฟล์เปลี่ยน) |
| node index.js | | (รีสตาร์ทให้อัตโนมัติ) |
| รีเฟรชเบราว์เซอร์ | | รีเฟรชเบราว์เซอร์ |
+---------------------+ +----------------------------+
ติดตั้ง
npm install --save-dev nodemon
--save-dev แปลว่า "ใช้เฉพาะตอนพัฒนา ไม่ต้องเอาขึ้น production" — จะไปโผล่ใน
devDependencies แทน dependencies
dependencies |
devDependencies |
|
|---|---|---|
| ตัวอย่าง | express, pg, bcrypt | nodemon |
| จำเป็นตอนรันจริงบนเซิร์ฟเวอร์ | ใช่ | ไม่ |
ตอนนี้เราเขียน const PORT = 3000; ไว้ในโค้ดตรงๆ — เรียกว่า hardcode ซึ่งมีปัญหา 3 ข้อ
dotenv คือ package ที่อ่านไฟล์ .env แล้วโยนค่าเข้าไปใน process.env ให้
flowchart LR
A[".env<br/>PORT=3000<br/>DB_PASSWORD=secret"] --> B["dotenv/config<br/>อ่านตอนโปรแกรมเริ่ม"]
B --> C["process.env.PORT<br/>process.env.DB_PASSWORD"]
C --> D["โค้ดของเราหยิบไปใช้"]
E[".gitignore<br/>มี .env อยู่"] -.->|"กัน .env ไม่ให้ขึ้น git"| A
style A fill:#5c4d2d,stroke:#eab308,color:#fff
style E fill:#5c2d2d,stroke:#ef4444,color:#fff
ขั้นที่ 1 — ติดตั้ง
npm install dotenv
npm install --save-dev nodemon
ขั้นที่ 2 — สร้างไฟล์ .env ที่ราก (ระดับเดียวกับ package.json)
PORT=3000
APP_NAME=Books API
กติกาของไฟล์ .env
KEY=value บรรทัดละคู่= → PORT = 3000 ผิดAPP_NAME="Books API" จะได้ค่าติด " มาด้วย; ปิดท้ายขั้นที่ 3 — เพิ่ม .env ลง .gitignore (ข้อนี้พลาดไม่ได้)
node_modules
.env
ขั้นที่ 4 — ใช้ใน index.js
import "dotenv/config"; // ⚠️ ต้องเป็นบรรทัดแรกสุด ก่อน import อื่นทั้งหมด
import express from "express";
const app = express();
const PORT = process.env.PORT || 3000;
ทำไม import "dotenv/config" ต้องอยู่บนสุด? เพราะ import อื่นๆ อาจต้องใช้ค่าจาก
process.env ทันทีตอนถูกโหลด ถ้าโหลด dotenv ทีหลังจะได้ undefined
ทำไมต้องมี || 3000? เป็นค่าสำรอง — ถ้าหาไฟล์ .env ไม่เจอ หรือลืมใส่ PORT โปรแกรม
จะยังรันได้ ไม่พังทั้งระบบ
ขั้นที่ 5 — เพิ่ม npm scripts ใน package.json
จำ "start": "node index.js" ที่ใส่ไว้ตั้งแต่ Mission 1 ได้ไหม — คราวนี้เพิ่มปุ่มที่สองชื่อ dev
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
จากนี้ไปตอนพัฒนาใช้คำสั่งเดียวคือ
npm run dev
ทำไมเก็บ
startไว้ด้วย? เพราะทั้งสองปุ่มมีหน้าที่ต่างกัน —devใช้ตอนเขียนโค้ด (มี nodemon คอยรีสตาร์ทให้) ส่วนstartคือคำสั่งที่ใช้ตอนเอาขึ้นเซิร์ฟเวอร์จริง ซึ่งไม่ควรมี nodemon ติดไปด้วยเทียบกับที่เคยเจอ: เหมือน
npm run devของ Next.js เป๊ะ — เป็นแค่ชื่อย่อของคำสั่งยาวๆ ที่เขียนไว้ในpackage.json
ขั้นที่ 6 — บอก nodemon ว่าอย่าไปยุ่งกับโฟลเดอร์ข้อมูล
เพิ่มก้อนนี้ใน package.json (ระดับเดียวกับ "scripts")
"nodemonConfig": {
"ignore": ["data/*"]
}
ทำไมต้องใส่ตั้งแต่ตอนนี้? เพราะ Chapter 3 เราจะเก็บข้อมูลไว้ในไฟล์ data/books.json
แล้ว API จะเขียนทับไฟล์นั้นทุกครั้งที่มีคนเพิ่ม/แก้/ลบข้อมูล
ถ้าไม่ใส่บรรทัดนี้ nodemon จะเห็นว่าไฟล์เปลี่ยนแล้ว รีสตาร์ท Server กลางอากาศทุกครั้งที่ยิง POST — เป็นอาการที่ไล่หาสาเหตุยากมากถ้าไม่รู้มาก่อน ใส่กันไว้ตั้งแต่วันนี้เลย
| ปัญหา | สาเหตุ / วิธีแก้ |
|---|---|
process.env.PORT ได้ undefined |
ลืม import "dotenv/config" หรือวางไว้ไม่ใช่บรรทัดแรก |
.env อยู่ผิดที่ |
ต้องอยู่ระดับเดียวกับ package.json ไม่ใช่ในโฟลเดอร์ย่อย |
ตั้งชื่อไฟล์ผิดเป็น env หรือ .env.txt |
ต้องชื่อ .env เป๊ะๆ (Windows ชอบเติม .txt ให้เอง ระวัง) |
ค่าที่ได้มีเครื่องหมาย " ติดมา |
ในไฟล์ .env ไม่ต้องใส่ quote |
แก้ .env แล้วค่าไม่เปลี่ยน |
dotenv อ่านครั้งเดียวตอนเริ่ม → ต้องรีสตาร์ท Server |
เผลอ commit .env ขึ้น GitHub |
เพิ่มลง .gitignore ก่อน commit แรกเสมอ ถ้าเผลอไปแล้วต้องเปลี่ยนรหัสผ่านทุกตัวทันที |
nodemon: command not found |
ลงเป็น dev dependency ในโปรเจค ต้องเรียกผ่าน npm run dev ไม่ใช่พิมพ์ nodemon ตรงๆ |
| nodemon รีสตาร์ทวนไม่หยุด | มักเกิดจากมีโค้ดเขียนไฟล์ลงในโฟลเดอร์ที่ nodemon เฝ้าอยู่ — แก้ด้วย nodemonConfig.ignore |
ใส่ nodemonConfig แล้วขึ้น Unexpected token |
วางผิดที่ — ต้องอยู่ระดับบนสุดของ package.json ข้างๆ "scripts" ไม่ใช่ข้างใน และอย่าลืม , คั่น |
.env เข้า process.env — แยก config ออกจากโค้ด.env ต้องอยู่ใน .gitignore เสมอ และค่าที่อ่านได้เป็น string เสมอnpm run dev สั้นๆ — dev ตอนพัฒนา / start ตอนขึ้นจริงnodemonConfig.ignore = กัน nodemon รีสตาร์ทเวลาโปรแกรมเขียนไฟล์ข้อมูลเอง (ต้องมีก่อนเข้า Chapter 3)
Boss Battle — ทำให้ครบทั้ง 7 ข้อ
dotenv (dependency) และ nodemon (devDependency).env ที่มี PORT=3000 และ APP_NAME=Books API.env ลงใน .gitignoreindex.js ให้อ่าน PORT จาก process.env โดยมีค่าสำรองเป็น 3000dev (nodemon) ต่อจาก start ที่มีอยู่แล้ว แล้วรันด้วย npm run dev"nodemonConfig": { "ignore": ["data/*"] } ใน package.json
(เตรียมไว้สำหรับ Chapter 3 ที่จะเขียนข้อมูลลงไฟล์)GET /info ที่ตอบ JSON แบบนี้
{
"app": "Books API",
"version": "1.0.0",
"port": 3000,
"routes": ["/books", "/books/:id", "/info"]
}
โดยค่า app ต้องอ่านมาจาก .env ไม่ใช่พิมพ์ทับลงไปตรงๆเปิด npm run dev ค้างไว้ แล้วแก้ข้อความใน route ไหนก็ได้ → กด save →
ดู terminal ว่าขึ้น [nodemon] restarting due to changes... ไหม → รีเฟรชเบราว์เซอร์
โดยไม่ต้อง Ctrl+C
แก้ .env เป็น PORT=4000 → รีสตาร์ท → เข้า http://localhost:4000 ได้ไหม?

ข้อ 1. nodemon แก้ปัญหาอะไร
ข้อ 2. ทำไม .env ต้องอยู่ใน .gitignore
ข้อ 3. process.env.PORT ให้ค่าชนิดอะไร
ข้อ 4. const PORT = process.env.PORT || 3000; ส่วน || 3000 มีไว้ทำไม
ข้อ 5. ความต่างระหว่าง dependencies กับ devDependencies คืออะไร
ข้อ 6. ทำไม import "dotenv/config" ต้องอยู่บรรทัดแรกสุด