Node รองรับ สองระบบโมดูล: CommonJS (CJS) — ระบบเดิม ใช้ require/module.exports — และ ES Modules (ESM) — มาตรฐาน ใช้ import/ ความแตกต่างอยู่ในไวยากรณ์ พฤติกรรมการโหลด และ interop
Node รองรับ สองระบบโมดูล: CommonJS (CJS) — ระบบเดิม ใช้ require/module.exports — และ ES Modules (ESM) — มาตรฐาน ใช้ import/ ความแตกต่างอยู่ในไวยากรณ์ พฤติกรรมการโหลด และ interop
export// math.js
function add(a, b) { return a + b; }
module.exports = { add };
// app.js
const { add } = require("./math"); // synchronous, runtime
// math.mjs (or .js with "type": "module")
export function add(a, b) { return a + b; }
export default something;
// app.mjs
import { add } from "./math.mjs"; // static, hoisted
CommonJS ES Modules
Syntax require/module.exports import/export
Loading synchronous, runtime static, hoisted
Top-level await no yes
Tree-shaking hard yes (statically analyzable)
File extension .cjs / .js (default) .mjs / .js with "type":"module"
__dirname/__filename available not available (use import.meta.url)
// package.json
{ "type": "module" } // now .js files are treated as ESM
หรือใช้นามสกุล .mjs อย่างชัดแจ้ง หากไม่มี Node จะตั้งค่า .js เป็น CommonJS โดยค่าเริ่มต้น
// ESM can import CommonJS:
import pkg from "some-cjs-lib"; // works (default import)
// CommonJS CANNOT require() a pure-ESM package (it's async):
const esm = require("esm-only-pkg"); // ❌ ERR_REQUIRE_ESM
// must use dynamic import: const esm = await import("esm-only-pkg");
จุดที่เป็นปัญหา: CJS ไม่สามารถ require() แพคเกจ ESM-only ได้ — ปัญหาทั่วไปในการย้ายข้อมูล นอกจากนี้โปรดสังเกตว่า ESM ขาด __dirname (ใช้ import.meta.url)
การรู้ทั้งสองระบบเป็นสิ่งจำเป็นสำหรับงาน Node จริงๆ: ESM คืออนาคต (มาตรฐาน tree-shakeable top-level await สอดคล้องกับเบราว์เซอร์) และเป็นตัวเลือกที่เหมาะสมสำหรับโครงการใหม่ แต่ส่วนใหญ่ของ npm ecosystem และโค้ดที่มีอยู่คือ CommonJS
การเข้าใจความแตกต่างของไวยากรณ์ วิธีเปิดใช้งาน ESM ("type": "module")
และข้อจำกัด interop (โดยเฉพาะ CJS-can't-require-ESM) เป็นการป้องกันความสับสนและข้อผิดพลาดที่บ่อยครั้งเกิดขึ้นจากการผสมกัน