์„œ๋ฒ„ ์ธก JavaScript ํ”Œ๋žซํผ Node.js 21.0 ์‚ฌ์šฉ ๊ฐ€๋Šฅ

JavaScript๋กœ ๋„คํŠธ์›Œํฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ”Œ๋žซํผ์ธ Node.js 21.0์ด ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Node.js 21.0 ๋ธŒ๋žœ์น˜๋Š” 6๊ฐœ์›” ๋™์•ˆ ์ง€์›๋ฉ๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ๋ฉฐ์น  ๋‚ด์— Node.js 20 ๋ธŒ๋žœ์น˜์˜ ์•ˆ์ •ํ™”๊ฐ€ ์™„๋ฃŒ๋˜์–ด LTS ์ƒํƒœ๋ฅผ ๋ฐ›๊ฒŒ ๋˜๋ฉฐ 2026๋…„ 18.0์›”๊นŒ์ง€ ์ง€์›๋ฉ๋‹ˆ๋‹ค. Node.js 2025์˜ ์ด์ „ LTS ๋ธŒ๋žœ์น˜ ์œ ์ง€ ๊ด€๋ฆฌ๋Š” 16.0๋…„ 2024์›”๊นŒ์ง€ ์ง€์†๋˜๋ฉฐ, ๋งˆ์ง€๋ง‰ LTS ๋ธŒ๋žœ์น˜ XNUMX์˜ XNUMX๋…„ ์ „์ธ XNUMX๋…„ XNUMX์›”๊นŒ์ง€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๊ฐœ์„  ์‚ฌํ•ญ:

  • Fetch API๋Š” ์•ˆ์ •์ ์œผ๋กœ ์„ ์–ธ๋˜์—ˆ์œผ๋ฉฐ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ ๋กœ๋“œํ•˜๊ณ  ์„œ๋ฒ„ ๋ฐ ํด๋ผ์ด์–ธํŠธ ์ธก ์ž‘์—…์— ์ ํ•ฉํ•œ ๋ฒ”์šฉ JavaScript ์ฝ”๋“œ ์ž‘์„ฑ์„ ๋‹จ์ˆœํ™”ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌํ˜„์€ HTTP/1.1 undici ํด๋ผ์ด์–ธํŠธ์˜ ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณต๋˜๋Š” ์œ ์‚ฌํ•œ API์— ์ตœ๋Œ€ํ•œ ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. API์—๋Š” fetch() ๋ฉ”์†Œ๋“œ์™€ Headers ๊ฐ์ฒด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. HTTP ํ—ค๋”, ์š”์ฒญ ๋ฐ ์‘๋‹ต์„ ๋‚˜ํƒ€๋‚ด๋Š” ์š”์ฒญ ๋ฐ ์‘๋‹ต. const res = fetch('https://nodejs.org/api/documentation.json')๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. if (res.ok) { const data = res.json()์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค; console.log(๋ฐ์ดํ„ฐ); }
  • ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” WebStreams API์— ๋Œ€ํ•œ ์ง€์›์ด ์•ˆ์ •ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค. API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ „์ฒด ํŒŒ์ผ์ด ๋‹ค์šด๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์ •๋ณด๊ฐ€ ๋„์ฐฉํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ž์ฒด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Node.js์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์—๋Š” ReadableStream*, TransformStream*, WritableStream*, TextEncoderStream, TextDecoderStream, CompressionStream ๋ฐ DecompressionStream์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
  • ๋ธŒ๋ผ์šฐ์ €์™€ ํ˜ธํ™˜๋˜๋Š” WebSocket ํด๋ผ์ด์–ธํŠธ์˜ ์‹คํ—˜์  ๊ตฌํ˜„์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. WebSocket ์ง€์›์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•ด "--experimental-websocket" ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.
  • CommonJS(Node.js์—๋งŒ ํ•ด๋‹น) ๋Œ€์‹  JavaScript ๋ชจ๋“ˆ ESM(ECMAScript ๋ชจ๋“ˆ, ๋ธŒ๋ผ์šฐ์ €์šฉ ๋ชจ๋“ˆ์— ์‚ฌ์šฉ๋จ)์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์‹คํ—˜ ๋ชจ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ํ˜•์‹์ด package.json์˜ "type" ํ•„๋“œ๋ฅผ ํ†ตํ•ด ๋ช…์‹œ์ ์œผ๋กœ ์ •์˜๋˜๊ฑฐ๋‚˜ "--input-type" ํ”Œ๋ž˜๊ทธ๋ฅผ ํ†ตํ•ด ์ง€์ •๋˜๊ฑฐ๋‚˜ ํŒŒ์ผ ํ™•์žฅ์ž(ESM์˜ ๊ฒฝ์šฐ .mjs, .cjs)๋กœ ์ธํ•ด ๋ช…ํ™•ํ•œ ๋ชจ๋“ˆ์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. CommonJS์˜ ๊ฒฝ์šฐ). ๊ทธ๋Ÿฌ๋‚˜ CommonJS๋กœ ๋ช…์‹œ์ ์œผ๋กœ ์ •์˜๋˜์ง€ ์•Š์€ ๋ชจ๋“ˆ(์˜ˆ: ".js" ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง)์€ ์ƒˆ ๋ชจ๋“œ๊ฐ€ ํ™œ์„ฑํ™”๋˜๋ฉด ESM ๋ชจ๋“ˆ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋ชจ๋“ˆ ์„ค์ •์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•ด "--experimental-default-type" ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ œ์•ˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • V8 ์—”์ง„์€ Chromium 11.8์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฒ„์ „ 118๋กœ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฒ„์ „์€ ์ด์ œ ArrayBuffer.prototype.transfer ๋ฉ”์„œ๋“œ, ๋ฐฐ์—ด ๊ทธ๋ฃนํ™” ๊ธฐ๋Šฅ(groupBy ๋ฉ”์„œ๋“œ) ๋ฐ ์ƒ์ˆ˜ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ WebAssembly ๋ช…๋ น(i32.add, i32.sub, i32.mul, i64 .add, i64.sub ๋ฐ i64.mul).
  • ๋ชจ๋“ˆ ๊ตฌ์„ฑ์„ ์œ„ํ•œ ๋“ฑ๋ก ๋ฐ ์ดˆ๊ธฐํ™” ํ˜ธ์ถœ์„ ์œ„ํ•ด globalPreload ํ•ธ๋“ค๋Ÿฌ์— ๋Œ€ํ•œ ์ง€์›์ด ์ค‘๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • fs.writeFile ํ•จ์ˆ˜์— "flush" ์˜ต์…˜์ด ์ถ”๊ฐ€๋˜์–ด ๊ฐ ์“ฐ๊ธฐ ์ž‘์—… ํ›„์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋“œ๋ผ์ด๋ธŒ์— ๊ฐ•์ œ๋กœ ํ”Œ๋Ÿฌ์‹œ๋ฉ๋‹ˆ๋‹ค.
  • URL ๊ตฌ๋ฌธ ๋ถ„์„, API ๊ฐ€์ ธ์˜ค๊ธฐ, ์ŠคํŠธ๋ฆผ, node:fs ๋ฐ HTTP์™€ ๊ด€๋ จ๋œ ์ฝ”๋“œ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธ€๋กœ๋ฒŒ ๋„ค๋น„๊ฒŒ์ดํ„ฐ ๊ฐœ์ฒด๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด CPU ์ฝ”์–ด ์ˆ˜์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์œผ๋ ค๋ฉด navigator.hardwareConcurrency ์†์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • "โ€”test" ๋งค๊ฐœ๋ณ€์ˆ˜์— ์‹คํ–‰ํ•  ํ…Œ์ŠคํŠธ๋ฅผ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•œ glob ๋งˆ์Šคํฌ ์ง€์›์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: "โ€”test **/*.test.js."๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ).
  • ๋ฒˆ๋“ค ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž npm 10.2.0 ๋ฐ llhttp 9.1.2 ํŒŒ์„œ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • Visual Studio 2019 ๋ฐ 11.0 ์ด์ „ macOS ๋ฒ„์ „์— ๋Œ€ํ•œ ์ง€์›์ด ์ค‘๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Node.js ํ”Œ๋žซํผ์€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„œ๋ฒ„ ์œ ์ง€ ๊ด€๋ฆฌ์™€ ์ผ๋ฐ˜ ํด๋ผ์ด์–ธํŠธ ๋ฐ ์„œ๋ฒ„ ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋žจ ์ƒ์„ฑ์— ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Node.js์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ธฐ ์œ„ํ•ด HTTP, SMTP, XMPP, DNS, FTP, IMAP, POP3 ์„œ๋ฒ„ ๋ฐ ํด๋ผ์ด์–ธํŠธ ๊ตฌํ˜„์ด ํฌํ•จ๋œ ๋ชจ๋“ˆ, ํ†ตํ•ฉ์šฉ ๋ชจ๋“ˆ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ๋Œ€๊ทœ๋ชจ ๋ชจ๋“ˆ ๋ชจ์Œ์ด ์ค€๋น„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์›น ํ”„๋ ˆ์ž„์›Œํฌ, WebSocket ๋ฐ Ajax ํ•ธ๋“ค๋Ÿฌ, DBMS ์ปค๋„ฅํ„ฐ(MySQL, PostgreSQL, SQLite, MongoDB), ํ…œํ”Œ๋ฆฟ ์—”์ง„, CSS ์—”์ง„, ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„ ๋ฐ ์ธ์ฆ ์‹œ์Šคํ…œ(OAuth), XML ํŒŒ์„œ.

๋งŽ์€ ์ˆ˜์˜ ๋ณ‘๋ ฌ ์š”์ฒญ ์ฒ˜๋ฆฌ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด Node.js๋Š” ๋น„์ฐจ๋‹จ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐ ์ฝœ๋ฐฑ ํ•ธ๋“ค๋Ÿฌ ์ •์˜์— ๊ธฐ๋ฐ˜ํ•œ ๋น„๋™๊ธฐ ์ฝ”๋“œ ์‹คํ–‰ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐํ”Œ๋ ‰์‹ฑ ์—ฐ๊ฒฐ์— ์ง€์›๋˜๋Š” ๋ฐฉ๋ฒ•์€ epoll, kqueue, /dev/poll ๋ฐ select์ž…๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ๋‹ค์ค‘ํ™”๋ฅผ ์œ„ํ•ด Unix ์‹œ์Šคํ…œ์˜ libev ๋ฐ Windows์˜ IOCP์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ธ libuv ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. libeio ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šค๋ ˆ๋“œ ํ’€์„ ์ƒ์„ฑํ•˜๊ณ  c-ares๋ฅผ ํ†ตํ•ฉํ•˜์—ฌ ๋น„์ฐจ๋‹จ ๋ชจ๋“œ์—์„œ DNS ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฐจ๋‹จ์„ ์œ ๋ฐœํ•˜๋Š” ๋ชจ๋“  ์‹œ์Šคํ…œ ํ˜ธ์ถœ์€ ์Šค๋ ˆ๋“œ ํ’€ ๋‚ด์—์„œ ์‹คํ–‰๋œ ๋‹ค์Œ ์‹ ํ˜ธ ์ฒ˜๋ฆฌ๊ธฐ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ž‘์—… ๊ฒฐ๊ณผ๋ฅผ ์ด๋ฆ„ ์—†๋Š” ํŒŒ์ดํ”„(ํŒŒ์ดํ”„)๋ฅผ ํ†ตํ•ด ๋‹ค์‹œ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. JavaScript ์ฝ”๋“œ์˜ ์‹คํ–‰์€ Google์—์„œ ๊ฐœ๋ฐœํ•œ V8 ์—”์ง„์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค(๋˜ํ•œ Microsoft๋Š” Chakra-Core ์—”์ง„์œผ๋กœ Node.js ๋ฒ„์ „์„ ๊ฐœ๋ฐœ ์ค‘์ž…๋‹ˆ๋‹ค).

๋ณธ์งˆ์ ์œผ๋กœ Node.js๋Š” Perl AnyEvent, Ruby Event Machine, Python Twisted ํ”„๋ ˆ์ž„์›Œํฌ ๋ฐ Tcl ์ด๋ฒคํŠธ ๊ตฌํ˜„๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ Node.js์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ˆจ๊ฒจ์ ธ ์žˆ์œผ๋ฉฐ ์‹คํ–‰ ์ค‘์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ. node.js์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ž‘์„ฑํ•  ๋•Œ ์˜ˆ๋ฅผ ๋“ค์–ด "var result = db.query("select..");"๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋Œ€์‹  ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—… ์™„๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ํ›„์† ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ์™€ ํ•จ๊ป˜ Node.js๋Š” ๋น„๋™๊ธฐ ์‹คํ–‰ ์›์น™์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” "db.query("select..", function (result) {result processing});"๋กœ ๋ณ€ํ™˜๋˜๋ฉฐ, ์—ฌ๊ธฐ์„œ ์ œ์–ด๋Š” ์ถ”๊ฐ€ ์ฝ”๋“œ๋กœ ์ฆ‰์‹œ ์ „๋‹ฌ๋˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ๋„์ฐฉํ•˜๋ฉด ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ€ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : opennet.ru

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€