ข้ามไปยังเนื้อหา

Glossary

Node ใช้คำศัพท์ JavaScript ปกติในบางจุด และมีคำเฉพาะของ runtime ในบางจุด — libuv, highWaterMark, backpressure ไม่มีคำเทียบเท่าในฝั่ง browser เวลาบทเรียนใช้คำที่ไม่แน่ใจความหมาย ให้กลับมาดูที่นี่

TermMeaning
Event loopกลไก single-thread ที่ทำให้ Node จัดการงาน concurrent จำนวนมากได้โดยไม่ block — มันส่งงานที่ช้า (I/O, timer, crypto บางตัว) ให้ OS หรือ threadpool ทำแทน แล้วค่อยรัน callback เมื่อผลลัพธ์กลับมา ดู Event Loop & Async
Phaseหนึ่ง stage ของ event loop หนึ่งรอบ (timers, pending callbacks, poll, check, close callbacks และอื่น ๆ) Node จะรัน callback ที่ครบกำหนดของทั้ง phase ก่อนไปยัง phase ถัดไป ไม่ใช่รันทีละ callback สลับ phase ดู Event Loop & Async
libuvlibrary ภาษา C ที่อยู่ข้างใต้ Node เป็นคน implement ตัว event loop เอง, threadpool, และกลไก async I/O ระดับ OS (epoll, kqueue, IOCP) ที่ทำให้ non-blocking I/O เป็นไปได้ ดู Event Loop & Async
Threadpoolpool ของ worker thread ขนาดคงที่ (default 4 ปรับได้ด้วย UV_THREADPOOL_SIZE) ที่ libuv ใช้กับงานที่ไม่มี async OS API ให้ใช้โดยตรง — async fs, crypto.pbkdf2/scrypt/randomBytes, dns.lookup, และ zlib ส่วน network socket ไม่ใช้ threadpool เลย ดู The fs Module
Macrotask / microtaskmacrotask คือ entry หนึ่งใน task queue (callback ของ setTimeout/setInterval, callback ของ I/O) ส่วน microtask คือ Promise reaction หรือ callback ของ queueMicrotask microtask queue (รวมกับ process.nextTick) จะ drain จนหมดหลังทุก callback เดี่ยว ๆ ไม่ใช่แค่ครั้งเดียวต่อรอบ loop ดู Microtasks & Macrotasks
process.nextTickจัดคิว callback ให้รันก่อน microtask queue ในการ drain รอบปัจจุบัน — เป็นคิวแยกที่มี priority สูงกว่า Promise microtask ดู Microtasks & Macrotasks
Tickแบบไม่เป็นทางการ หมายถึงการวนคิว process.nextTick หนึ่งรอบ ความหมายที่แม่นยำจะหมายถึงคิวนั้นโดยเฉพาะ ไม่ใช่ “event loop วนหนึ่งรอบ” ดู Microtasks & Macrotasks
Callbackfunction ที่ส่งเข้าไปใน function อื่นเพื่อให้ถูกเรียกทีหลัง เมื่องานหนึ่งเสร็จ เป็น async pattern ดั้งเดิมของ Node ตามธรรมเนียม error-first: (err, result) => ... ดู Callbacks
Promise / async / awaitPromise แทนค่าที่จะมีอยู่ในอนาคต (pending, fulfilled, หรือ rejected) async/await คือ syntax สำหรับใช้งาน Promise ราวกับเป็น synchronous code โดย function จะหยุดพักที่แต่ละ await โดยไม่ block event loop ดู Promises และ async/await
Unhandled rejectionPromise ที่ reject โดยไม่มีอะไรจับมันไว้เลย (ไม่มี .catch(), ไม่มี try ครอบ await) ตั้งแต่ Node 15 เป็นต้นมา สิ่งนี้ทำให้ process crash โดย default ไม่ใช่แค่ warning ดู async/await
Backpressureสัญญาณที่ consumer ที่ช้าส่งให้ producer ที่เร็วให้หยุด เพื่อไม่ให้ write กองอยู่ใน memory เร็วกว่าที่จะ drain ได้ ใน stream การที่ writable.write() คืนค่า false คือสัญญาณนั้น ดู Backpressure
highWaterMarkthreshold ขนาด buffer ที่ stream ใช้ตัดสินใจว่าจะเริ่ม backpressure เมื่อไหร่ — default 64 KiB (65536 byte) สำหรับ byte stream และ 16 object สำหรับ object mode ดู Backpressure
Chunkข้อมูลชิ้นหนึ่งที่ event data ของ Readable ปล่อยออกมา หรือที่ส่งเข้า write() ของ Writable — เป็น Buffer (หรือ string หรือ value อะไรก็ได้ใน object mode) ไม่ใช่ payload ทั้งก้อนในครั้งเดียว ดู Readable Streams
Readable / Writable / Duplex / Transformstream base class ทั้งสี่ตัว: Readable ผลิตข้อมูล, Writable รับข้อมูล, Duplex ทำทั้งสองอย่างแยกอิสระจากกัน (เช่น TCP socket), และ Transform คือ Duplex ที่แปลง input ให้เป็น output (zlib.createGzip()) ดู Streams & I/O
pipelinestream.pipeline() เชื่อม stream หลายตัวเข้าด้วยกัน และต่างจาก .pipe() ตรงที่มันส่งต่อ error จาก stream ตัวไหนก็ได้ในสาย แล้ว cleanup stream ทุกตัวทันทีที่ตัวใดตัวหนึ่ง fail หรือจบ ดู pipe() and pipeline()
Object modeโหมดของ stream ที่ chunk เป็น JavaScript value อะไรก็ได้ แทนที่จะเป็นข้อมูล Buffer/string ทำให้หน่วยของ highWaterMark เปลี่ยนจาก byte เป็นจำนวน object ดู Streams & I/O
EventEmitterclass ฐานที่อยู่เบื้องหลัง API แบบ event-driven ของ Node (http.Server, stream, process) .on() ลงทะเบียน listener ส่วน .emit() เรียก listener ทุกตัวของ event นั้นแบบ synchronous ตามลำดับที่ลงทะเบียน ดู EventEmitter
Listener leakการผูก listener เพิ่มเข้ากับ EventEmitter event เดียวกันโดยไม่เคยเอาออก ทำให้ array ของ listener โตขึ้นเรื่อย ๆ ตลอดอายุ process Node จะเตือนด้วย MaxListenersExceededWarning เมื่อ listener ของ event เดียวเกิน 10 ตัว ดู EventEmitter
AbortController / AbortSignalAbortController สร้าง cancellation token (.signal) ที่ async API อย่าง fetch รับได้ การเรียก .abort() — หรือ AbortSignal.timeout(ms) ที่ทำงานเอง — จะ reject operation ที่ค้างอยู่ แทนที่จะปล่อยให้มันรันค้างตลอดไป ดู fetch and Outbound Requests
TermMeaning
CommonJS (CJS)ระบบ module ดั้งเดิมของ Node: require() โหลด module แบบ synchronous แล้วคืน copy ของ module.exports ตามสภาพ ณ ตอนที่เรียก ดู Modules: CommonJS vs ESM
ESMระบบ ECMAScript Module (import/export) ที่เป็นมาตรฐานอยู่ใน JavaScript เอง resolve แบบ static ก่อนที่ code ใด ๆ จะรัน ซึ่งเป็นสิ่งที่ทำให้ tree-shaking เป็นไปได้ ดู Modules: CommonJS vs ESM
Live bindingimport ของ ESM ให้ reference ไปยังตัวแปรของ module ต้นทางเลย ไม่ใช่ copy แบบ snapshot — ถ้า module ต้นทาง assign ตัวแปรนั้นใหม่ทีหลัง ทุกที่ที่ import ไปจะเห็นค่าใหม่ด้วย CJS require() ไม่ทำแบบนี้เลย ดู Modules: CommonJS vs ESM
Module resolutionalgorithm ที่กำหนดแน่นอนของ Node ในการแปลง specifier ('express', './util.js') ให้เป็นไฟล์จริงบนดิสก์ — ตรวจ node_modules, extension ของไฟล์ และ field exports ไปตามลำดับ ดู Module Resolution
exports / imports mapexports ใน package.json คือ entry-point map สมัยใหม่ที่เป็นตัวกำหนดจริงว่าผู้ใช้ package import/require อะไรได้บ้าง และจาก subpath ไหน — มี priority เหนือ main ส่วน imports คือ map แบบเดียวกันสำหรับ subpath import ภายในของ package เองที่ขึ้นต้นด้วย # ดู Module Resolution
Conditionkey ที่มีชื่อภายใน exports/imports map ("import", "require", "types", "node", "default") ที่ Node เลือกใช้ตามวิธีที่ module ถูกโหลด ลำดับมีผล — "types" ต้องมาก่อนเสมอ เพื่อให้ tooling ของ TypeScript เห็นมันได้ ดู Module Resolution
Package scope / "type"package.json ที่ใกล้ไฟล์ที่สุดเป็นตัวกำหนดระบบ module default ของไฟล์นั้นผ่าน "type": "module" ทำให้ไฟล์ .js ถูกมองเป็น ESM ค่าอื่น (หรือไม่มี field นี้เลย) ทำให้เป็น CommonJS ดู package.json Deep Dive
Lockfileไฟล์ (package-lock.json) ที่ pin version ที่ resolve แล้วแบบเป๊ะของทุก dependency ทั้งทางตรงและทางอ้อม ทำให้การติดตั้งได้ผลเหมือนกันทุกเครื่อง ดู Dependencies
Semver caret / tilde / ^0.x^1.2.3 ยอม upgrade 1.x.x อะไรก็ได้ (minor และ patch) ส่วน ~1.2.3 ยอมแค่ patch upgrade ภายใน 1.2.x สำหรับ version 0.x npm มองว่าเลข major 0 เองยัง unstable ทำให้ ^0.4.2 ยอมแค่ patch upgrade (0.4.x) เหมือนกับที่ ~0.4.2 จะให้ ดู package.json Deep Dive
Peer / dev / optional dependencypeerDependencies ประกาศ package ที่ผู้ใช้ต้องติดตั้งเอง (npm 7 ขึ้นไป install ให้อัตโนมัติ พร้อม warning ถ้า version ไม่ตรง) devDependencies คือเครื่องมือที่ใช้แค่ตอน build หรือ test ไม่ถูกส่งไปให้ผู้ใช้ optionalDependencies ติดตั้งแบบ best-effort ไม่ทำให้การติดตั้งทั้งหมด fail ถ้า build ไม่ผ่าน ดู Dependencies
npm ciติดตั้งจาก lockfile เท่านั้นแบบเคร่งครัด ลบ node_modules เดิมทิ้งก่อน แล้ว fail ทันทีถ้า package.json กับ lockfile ไม่ตรงกัน เป็นคำสั่งติดตั้งแบบ reproducible สำหรับ CI และ Docker build ต่างจาก npm install ที่ update lockfile ได้ ดู Dependencies
Workspaceฟีเจอร์ของ npm สำหรับจัดการหลาย package ใน repository เดียว (monorepo) จาก package.json ตัวเดียวที่ root โดย dependency ข้าม package จะถูก symlink เข้า node_modules ของแต่ละ package แทนที่จะ publish แล้วติดตั้งใหม่ ดู Dependencies
node: prefixprefix node: (node:fs, node:path) ระบุชัดเจนว่า specifier นี้คือ built-in module เป็น optional สำหรับ built-in module เก่าที่มีมานาน แต่บังคับสำหรับตัวใหม่อย่าง node:test และ node:sqlite ที่ไม่มีรูปแบบไม่มี prefix ดู Core APIs
TermMeaning
Request lifecycleลำดับที่ HTTP request ขาเข้าหนึ่งตัวผ่าน: header ถูก parse เป็น IncomingMessage, body ถูก stream เข้ามา (ถ้ามี), handler ของเรารันแล้วเขียนลง ServerResponse จากนั้น connection จะปิดหรือคงไว้รอ request ถัดไป ดู The HTTP Server
IncomingMessage / ServerResponseสอง object ที่ callback ของ http.createServer ได้รับ IncomingMessage (req) คือ readable stream ของ request (method, URL, header, body) ส่วน ServerResponse (res) คือ writable stream ที่ใช้ส่ง status, header, และ body กลับไป ดู The HTTP Server
Keep-aliveการใช้ TCP connection เดียวซ้ำสำหรับหลาย request ที่มาต่อกัน แทนที่จะเปิด socket ใหม่ทุกครั้ง ควบคุมด้วย header Connection: keep-alive และฝั่ง server ด้วย server.keepAliveTimeout ดู The HTTP Server
Chunked transferencoding แบบ HTTP/1.1 (Transfer-Encoding: chunked) ที่ stream response body ออกเป็นชิ้น ๆ โดยไม่รู้ขนาดรวมล่วงหน้า ใช้อัตโนมัติเมื่อเขียนลง res โดยไม่ตั้ง Content-Length ไว้ก่อน ดู The HTTP Server
Content-Lengthresponse header ที่ประกาศขนาด byte ของ body ไว้ล่วงหน้าแบบเป๊ะ Node ตั้งค่าให้อัตโนมัติเฉพาะตอนเรียก res.end(data) ครั้งเดียวจบด้วยขนาดที่คำนวณได้ ไม่งั้น response จะย้อนกลับไปใช้ chunked encoding แทน ดู The HTTP Server
Headers sentเมื่อ res.writeHead() หรือการเรียก res.write()/res.end() ครั้งแรก flush header ออกไปแล้ว จะเปลี่ยนไม่ได้อีก — การตั้ง header หรือ status code หลังจากนั้นจะ throw ERR_HTTP_HEADERS_SENT ดู The HTTP Server
Body limitเพดานที่กำหนดไว้ชัดเจนว่า handler จะรับ body ของ request ได้กี่ byte ก่อนจะตัด connection ทิ้ง ป้องกันไม่ให้ client stream payload ที่ไม่มีขอบเขตเข้ามาจน memory ของ server หมด ดู A Small JSON API
headersTimeout / requestTimeout / keepAliveTimeouttimeout สามตัวของ server ที่แยกจากกันและมี default ต่างกัน: headersTimeout (60 วินาที) จำกัดเวลาที่ Node รอ header ของ request มาครบ requestTimeout (300 วินาที) จำกัดทั้ง request keepAliveTimeout (5 วินาที) จำกัดว่า connection แบบ keep-alive ที่ไม่มีอะไรทำจะเปิดค้างได้นานแค่ไหน ดู The HTTP Server
Graceful shutdownการปิด server ด้วยการเรียก server.close() ก่อน — ซึ่งหยุดรับ connection ใหม่แต่ปล่อยให้ request ที่กำลังทำอยู่เสร็จก่อน — เมื่อได้รับ SIGTERM แทนที่จะปิดทันทีแล้วตัด request ที่ทำค้างอยู่กลางทาง ดู The HTTP Server
fetch / undicifetch ที่มีมาในตัวของ Node (เป็น global ตั้งแต่ Node 18 stable ตั้งแต่ 21) implement ด้วย undici ซึ่งเป็น HTTP client ของ Node เอง มัน reject แค่ตอนที่การเชื่อมต่อระดับ network ล้มเหลวเท่านั้น ไม่ reject ตอนได้ status ที่ไม่ใช่ 2xx ดู fetch and Outbound Requests
AbortSignal.timeout()สร้าง AbortSignal ที่ทำงานเองหลังผ่านไปตามจำนวนมิลลิวินาทีที่กำหนด ทำให้ส่ง timeout ของ request เข้า fetch({ signal }) ได้เลย โดยไม่ต้องต่อ setTimeout กับ AbortController เองด้วยมือ ดู fetch and Outbound Requests
CORSCross-Origin Resource Sharing: response header (Access-Control-Allow-Origin และพวก) ที่บอก browser ว่ายอมให้ script จาก origin หนึ่งอ่าน response จากอีก origin ได้ ไม่เกี่ยวข้องกับการเรียกระหว่าง server กับ server ซึ่ง fetch/undici ไม่เคย block อยู่แล้ว ดู fetch and Outbound Requests
URL / URLPatternclass URL ที่มีมาในตัว parse และสร้าง URL ได้ (pathname, searchParams, …) ส่วน URLPattern (global ตั้งแต่ Node 24) จับคู่ path ของ URL กับ route pattern แบบ /items/:id ได้เลยโดยไม่ต้องใช้ routing library ดู Routing
TermMeaning
Test runnernode:test test runner ที่มีมาในตัวของ Node — ไม่ต้องติดตั้งอะไรเพิ่ม รันด้วย node --test มันจะหาไฟล์ *.test.js แล้วรายงานผลเป็น TAP format ดู node:test
describe / itfunction จัดกลุ่มของ node:test: describe ตั้งชื่อกลุ่ม test ที่เกี่ยวข้องกัน ส่วน it (alias ของ test) กำหนด test case หนึ่งตัวข้างใน ดู node:test
Mockimplementation ตัวปลอมที่ใช้แทน dependency จริง เพื่อให้ test ควบคุมพฤติกรรมและตรวจสอบได้ว่าถูกเรียกยังไง สร้างใน node:test ด้วย t.mock.fn(), t.mock.method(), หรือ t.mock.module() ดู node:test
Fake timersแทนที่นาฬิกาจริง (setTimeout, Date) ด้วยตัวที่ควบคุมได้ระหว่าง test ผ่าน t.mock.timers ทำให้ test code ที่ขึ้นกับเวลาได้โดยการเลื่อนนาฬิกาปลอมแทนที่จะรอเวลาจริง ดู node:test
Coverageเปอร์เซ็นต์ของ line หรือ branch ที่ test รันผ่านจริง วัดด้วย node --test --experimental-test-coverage (ยัง experimental บน Node 24/26) เป็นสัญญาณที่จำเป็นแต่ไม่พอสำหรับคุณภาพของ test ดู node:test
Snapshotcopy ของ output ที่ serialize ไว้แล้ว ที่ test รอบถัดไปจะเอาไปเทียบ แล้ว fail ถ้า output เปลี่ยนไปโดยไม่ตั้งใจ node:test รองรับผ่าน t.assert.snapshot (stable ตั้งแต่ 23.4) ดู node:test
Inspectorprotocol debug ที่มีมาในตัวของ Node เปิดใช้ด้วย node --inspect ทำให้ Chrome DevTools หรือ VS Code attach เข้า process ที่กำลังรันเพื่อตั้ง breakpoint และไล่ดู code ทีละบรรทัดได้ ดู Debugging Node.js
--watchflag ของ Node CLI ที่ restart process ให้อัตโนมัติเมื่อไฟล์ที่ require เปลี่ยน — stable สำหรับการรันแอป แต่ยัง experimental เมื่อใช้คู่กับ --test ดู The Node.js Ecosystem
--env-fileflag ของ Node CLI ที่โหลด key-value จากไฟล์ .env เข้า process.env ก่อน code เราจะรัน โดยไม่ต้องใช้ package ภายนอกเลย (stable ตั้งแต่ 22.21/24.10) ดู The Node.js Ecosystem
Strip-typesความสามารถที่มีมาในตัวของ Node ที่รันไฟล์ .ts ได้ตรง ๆ ด้วยการตัด type annotation ออกตอนโหลด โดยไม่ transpile syntax ที่ไม่มีคู่เทียบใน JS — node app.ts ได้เลยโดยไม่ต้อง build สำหรับ TypeScript แบบตรงไปตรงมา ดู The Node.js Ecosystem
perf_hooksmodule ที่มีมาในตัว (performance.now(), performance.mark()/.measure(), PerformanceObserver) สำหรับวัดเวลาที่ผ่านไปและเก็บ performance entry ด้วยความละเอียดระดับต่ำกว่ามิลลิวินาที ดู Performance Basics
Event-loop lagความล่าช้าระหว่างเวลาที่ timer หรือ callback ควรจะทำงานกับเวลาที่มันทำงานจริง เกิดจากงาน synchronous ที่ block loop อยู่ วัดด้วย monitorEventLoopDelay() ของ perf_hooks ดู Performance Basics
Worker threadinstance ของ worker_threads: V8 isolate แยกต่างหากที่มี event loop ของตัวเอง รันขนานกันบน OS thread อีกตัว ใช้กับงานที่กิน CPU หนักซึ่งไม่งั้นจะ block main thread ดู Performance Basics
Clustermodule cluster ที่มีมาในตัว ทำการ fork Node process หลายตัวให้ share listening port เดียวกัน เพื่อกระจาย connection ขาเข้าไปยังแต่ละตัว เป็นทางเลือก (หรือใช้คู่กับ) reverse proxy สำหรับ scale ข้าม CPU core ดู Performance Basics

โค้ด Node.js ที่ generate มามักจะรันผ่านฉลุยใน happy path มากกว่าที่มันจะถูกต้องจริงตอนโหลดหนัก, input ที่ผิดรูป, หรือ dependency ที่ช้า — นี่คือ pattern ที่มีโอกาสสูงสุดที่จะดูดีตอน demo แต่พังเงียบ ๆ ตอนขึ้น production

PatternWhy it’s a smellCovered in
ลืม awaitเรียก async function โดยไม่ใส่ await ข้างใน async function อีกตัว จะได้ Promise กลับมาที่ผู้เรียกไม่เคยรอเลย — rejection หลุดไปแบบไม่มีใครรู้ และ code ที่ต้องใช้ผลลัพธ์ต่อจากนั้นจะทำงานกับ value ที่ยังไม่ resolveasync/await
.forEach(async fn)Array.prototype.forEach ไม่สนใจ return value ของ callback เลย ทำให้ promise ที่ callback แบบ async คืนมาไม่เคยถูก await หรือเก็บไว้เลย loop ดูเหมือน synchronous แต่จริง ๆ แต่ละรอบทำงานไม่ประสานกัน แล้ว failure ก็หายไปแบบเงียบ ๆasync/await
Promise.all ไม่จำกัด concurrencymap ทุก item ของ array ใหญ่ผ่าน async call แล้ว await ทั้งหมดเป็น Promise.all เดียว จะยิง request ทุกตัวพร้อมกันโดยไม่มีเพดาน concurrency — อาจทำให้ socket, memory หมด หรือชน rate limit ของ service ปลายทางPromises
งาน sync fs/CPU ใน request handlerเรียก fs.readFileSync หรือรัน loop synchronous หนัก ๆ ข้างใน HTTP handler จะ block event loop thread เดียวที่มีอยู่ ทำให้ request อื่นที่กำลังทำค้างอยู่ทั้งหมดหยุดรอจนกว่าจะเสร็จThe fs Module
เรียก res.end() ซ้ำสอง / ไม่มี listener errorการเรียก res.end() บน response ที่จบไปแล้วจะ throw ERR_STREAM_WRITE_AFTER_END ถ้าไม่มี listener error อยู่บน request, response, หรือ server การ throw นั้นจะทำให้ process ทั้งตัว crash แทนที่จะแค่ request เดียว failThe HTTP Server
ไม่จำกัดขนาด request bodyรวม chunk ของ req ที่เข้ามาเป็น buffer โดยไม่มีเพดานสูงสุด ทำให้ client stream payload ที่ไม่มีขอบเขตเข้ามาจน memory ของ server หมดก่อนที่ handler จะได้ตรวจสอบด้วยซ้ำA Small JSON API
fetch ไม่เช็ก .ok หรือไม่มี timeoutfetch จะ reject แค่ตอนที่การเชื่อมต่อระดับ network ล้มเหลวเท่านั้น ไม่ reject ตอนได้ status 4xx/5xx — code ที่คิดว่า promise resolve แปลว่าสำเร็จ จะประมวลผล error body เป็น data แบบเงียบ ๆ ถ้าไม่มี AbortSignal.timeout(...) server ที่ค้างจะทำให้ request ค้างรอตลอดไปfetch and Outbound Requests
Listener leakผูก listener ใหม่เข้ากับ EventEmitter ทุกครั้งที่มี request หรือ connection โดยไม่เคยเอาออก ทำให้ array ของ listener โตขึ้นเรื่อย ๆ ไม่มีขอบเขต เมื่อ listener ของ event เดียวเกิน 10 ตัว MaxListenersExceededWarning ของ Node คือสัญญาณของ memory leak จริง ไม่ใช่แค่ noise ที่ปิดเสียงทิ้งได้EventEmitter
ใช้ process.env.PORT เป็นตัวเลขตรง ๆprocess.env.X เป็น string หรือ undefined เสมอ การเอาไปใช้ในนิพจน์คำนวณหรือเทียบแบบ port > 1024 ตรง ๆ จะ coerce string นั้น และตัวแปรที่ไม่ได้ตั้งไว้จะเป็น undefined ไม่ใช่ default สำรอง เว้นแต่ code จะเช็กเองอย่างชัดเจนprocess.env and process.argv
ปน require กับ import / ใช้ __dirname ใน ESMการเอา require() ไปปนในไฟล์ที่ "type": "module" จะ throw ReferenceError ส่วน __dirname/__filename ไม่มีอยู่ใน ESM เลย — import.meta.dirname (หรือ fileURLToPath(import.meta.url)) คือตัวแทนที่ใช้แทนกันModules: CommonJS vs ESM
range ^0.x / ไม่มี lockfile^0.4.2 ยอมแค่ patch bump เท่านั้น (ไม่ใช่ minor) เพราะ npm มองว่า major 0.x เองยัง unstable — code ที่คิดว่า ^ แปลว่า “minor กับ patch” เสมอ จะ pin แน่นกว่าที่ตั้งใจไว้แบบเงียบ ๆ การไม่มี lockfile เลยทำให้ทุกการติดตั้งอาจ resolve transitive dependency คนละ version กันในแต่ละเครื่องหรือใน CIpackage.json Deep Dive
หลีกเลี่ยงใช้แทน
ลูปเหตุการณ์event loop
ตัวรับฟังเหตุการณ์listener
การเรียกกลับcallback
คำสัญญาPromise
แรงดันย้อนกลับ / แรงต้านกลับbackpressure
กลุ่มเธรด / พูลเธรดthreadpool
ตัวปล่อยเหตุการณ์EventEmitter
ตัวอ่าน / ตัวเขียน (สำหรับ stream)Readable / Writable
ก้อนข้อมูล (สำหรับ chunk)chunk
ไฟล์ล็อกlockfile
ตัวจัดการ (สำหรับ handler)handler
โมดูลโมดูล (ใช้ได้ปกติ ไม่ใช่ calque)