สอน Node.js ตั้งแต่ต้น
Node.js คือสภาพแวดล้อมที่นำ JavaScript มารันบนเครื่องและบนเซิร์ฟเวอร์ ทำให้ใช้ภาษาเดียวกันทั้งฝั่งหน้าเว็บและฝั่งเซิร์ฟเวอร์ได้ Node.js ใช้โมเดลที่ไม่บล็อกการทำงาน (non-blocking I/O) จึงเหมาะกับงานเครือข่ายและ API บทความนี้จะให้คุณรันสคริปต์แรก ใช้โมดูลมาตรฐานอ่านเขียนไฟล์ และสร้างเซิร์ฟเวอร์ HTTP ขนาดเล็กที่ตอบเป็น JSON
ตัวอย่างทั้งหมดในบทความนี้ถูกรันจริงด้วย Node.js และแสดงผลลัพธ์ตามที่ได้รับ
สิ่งที่ต้องเตรียม
- Node.js เวอร์ชัน 18 ขึ้นไป (ตรวจด้วย `node --version`)
- โปรแกรมแก้ไขข้อความ เช่น VS Code
ภาพรวมการทำงาน
สคริปต์แรก
สร้างไฟล์ `hello.js` แล้วรันด้วย `node hello.js`
console.log("สวัสดี Node.js");
โมดูลและการอ่านเขียนไฟล์
Node.js มีโมดูลมาตรฐานให้ใช้ทันที เช่น `fs` สำหรับไฟล์ และ `path` สำหรับจัดการเส้นทาง ตัวอย่างต่อไปนี้เขียนข้อมูลลงไฟล์ JSON แล้วอ่านกลับมา
const http = require("http");
const path = require("path");
const fs = require("fs");
// โมดูลและฟังก์ชัน
function grade(score) {
if (score >= 80) return "A";
if (score >= 70) return "B";
if (score >= 50) return "C";
return "F";
}
const students = [
{ name: "สมชาย", score: 85 },
{ name: "สมหญิง", score: 72 },
{ name: "สมศักดิ์", score: 45 },
];
// เขียนไฟล์แล้วอ่านกลับมา
const file = path.join(__dirname, "grades.json");
fs.writeFileSync(file, JSON.stringify(students.map(s => ({ ...s, grade: grade(s.score) })), null, 2));
const data = JSON.parse(fs.readFileSync(file, "utf8"));
console.log("สวัสดี Node.js", data.length, "คน");
console.log(data.map(d => `${d.name}: ${d.grade}`).join("\n"));
// เซิร์ฟเวอร์ HTTP ขนาดเล็ก ตอบ JSON แล้วปิดตัวเองหลังตอบ 1 ครั้ง (สำหรับทดสอบ)
const server = http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "application/json; charset=utf-8" });
res.end(JSON.stringify({ message: "สวัสดีจาก Node.js", count: data.length }));
server.close();
});
server.listen(3100, () => console.log("server listening on http://localhost:3100"));
ผลลัพธ์ที่ได้จากการรันจริง (รันสคริปต์ แล้วส่งคำขอด้วย curl ไปยัง `http://localhost:3100/`)
สวัสดี Node.js 3 คน
สมชาย: A
สมหญิง: B
สมศักดิ์: F
server listening on http://localhost:3100
{"message":"สวัสดีจาก Node.js","count":3}
สิ่งที่ควรสังเกต
- `require` โหลดโมดูล และ `__dirname` คือโฟลเดอร์ของไฟล์สคริปต์
- `fs.writeFileSync` และ `fs.readFileSync` เป็นเวอร์ชัน Sync ซึ่งบล็อกการทำงานจนเสร็จ เหมาะกับสคริปต์ง่าย ๆ แต่ในเซิร์ฟเวอร์ควรใช้เวอร์ชัน async เช่น `fs.promises.readFile`
- `http.createServer` รับ callback ที่ทำงานทุกครั้งที่มีคำขอเข้ามา
Promise และ async/await
การอ่านไฟล์แบบ async ทำให้โปรแกรมไม่หยุดรอ ตัวอย่างนี้ใช้ `async/await` เพื่อให้โค้ดอ่านง่ายเหมือนลำดับปกติ
const fs = require("fs/promises");
async function main() {
await fs.writeFile("note.txt", "บันทึกจาก Node.js");
const text = await fs.readFile("note.txt", "utf8");
console.log("อ่านได้:", text);
}
main().catch(err => console.error("เกิดข้อผิดพลาด:", err.message));
ข้อผิดพลาดที่มือใหม่มักเจอ
- **พอร์ตถูกใช้งานอยู่แล้ว:** เปลี่ยนหมายเลขพอร์ต หรือปิดโปรแกรมเดิมที่ใช้พอร์ตนั้น
- **ลืม `await` กับ Promise:** ค่าที่ได้จะเป็น Promise แทนผลลัพธ์จริง
- **ใช้ `require` ในไฟล์ที่เป็น ES Module โดยไม่ตั้งค่า:** ตรวจสอบประเภทโมดูลในไฟล์ `package.json`
- **ไม่จัดการข้อผิดพลาด:** ใช้ `try/catch` หรือ `.catch` เพื่อให้โปรแกรมแจ้งสาเหตุได้
ขั้นต่อไป
ลองสร้าง API ที่รับและเก็บรายการงาน (todo) ในไฟล์ JSON แล้วพัฒนาต่อด้วย Express หรือ Fastify ซึ่งเป็นเฟรมเวิร์กยอดนิยมบน Node.js
สรุป
Node.js ทำให้ JavaScript ทำงานฝั่งเซิร์ฟเวอร์ได้ โดยใช้โมดูลมาตรฐานจัดการไฟล์และเครือข่าย การเขียนแบบ async/await ช่วยให้โค้ดที่ทำงานหลายอย่างพร้อมกันยังอ่านง่าย