Node.js

Node.js® is an open-source, cross-platform JavaScript runtime environment.

— Node.js 공식 웹사이트 메인 페이지의 상징적인 공식 정체성 한 줄

자바스크립트라는 브라우저 전용 언어를 서버사이드 생태계로 탈출시켜 백엔드 업계를 완전히 집어삼키게 만든 장본인이자, 오늘날 웹 개발자가 되기 위해 무조건 컴퓨터에 설치해야 하는 필수 프로그램 0순위. 분명 가볍고 빠르다고 해서 전사적으로 도입했는데, 어느새 'node_modules' 폴더 용량이 수백 메가바이트를 가뿐히 돌파하며 하드디스크의 비명을 감상하게 된다.(...)

1. 개요

자바스크립트를 웹 브라우저라는 차가운 감옥에서 구출해 낸 역사적인 자바스크립트 런타임(Runtime). 구글 크롬의 고성능 엔진인 V8 Engine을 탑재하여 서버사이드에서도 어마어마한 속도로 스크립트를 직접 실행할 수 있게 되었다. 출시되자마자 백엔드 생태계에 엄청난 대격변을 몰고 왔으며, 단순한 서버 개발을 넘어 프론트엔드 빌드 도구와 하이브리드 앱 개발 등 현대 웹 생태계 전반을 지배하는 우주적 스펙으로 성장했다.

2. 핵심 아키텍처와 비동기 I/O

Node.js의 심장은 싱글 스레드 비동기 이벤트 루프(Single-threaded Event Loop)이다. 여러 요청을 다중 스레드로 처리하는 전통적인 자바 스펙의 WASApache와 달리, 단 하나의 메인 스레드가 쉴 새 없이 몰아치는 요청들을 접수하고 무거운 디스크 읽기/쓰기나 네트워크 통신 등의 입출력(I/O) 연산은 운영체제 백그라운드의 libuv 엔진에 위임해 비동기 비차단(Non-blocking) 방식으로 처리한다.1 요청이 끝나면 이벤트 큐에 콜백 함수를 던져 메인 스레드가 순서대로 낚아채 처리하는 이 방식은 압도적인 가벼움과 고성능을 보장한다. 덕분에 대규모 실시간 알림 시스템이나 채팅 앱 등 I/O가 빈번한 시스템 개발에서 타의 추종을 불허하는 가성비를 뿜어낸다.

3. 양날의 검: 싱글 스레드의 맹점

이러한 혁신적인 구조 뒤에는 치명적인 함정이 숨겨져 있다. 메인 스레드가 단 하나뿐이기 때문에, 본문에서 아주 무겁고 복잡한 연산(예: 대용량 이미지 압축, 암호화 처리)을 실행하면 이벤트 루프 자체가 굳어버리는 대참사가 발생한다. 메인 스레드가 굳어버리는 순간, 뒤이어 들어오는 수만 명의 사용자 요청은 그대로 대기실에 갇힌 채 타임아웃을 맞이하게 된다.물론 이 문제 해결을 위해 Worker Thread가 도입되긴 했으나 이걸 깔끔하게 쓰는 개발자는 많지 않다.2 또한, 콜백 지옥(Callback Hell)을 방지하기 위해 Promise와 async/await를 철저히 마스터해야 하며, 백엔드 로직 깊은 곳에서 단 하나의 예외(Exception)라도 처리하지 못하고 uncaughtException 에러를 뿜는 순간 서버 전체가 쥐도 새도 모르게 죽어버리는 극단적인 취약성도 안고 있다.

4. node_modules의 블랙홀

4.1. 우주에서 가장 무거운 물질

Node.js 개발 과정에서 패키지 매니저(npm, yarn 등)를 통해 외부 라이브러리를 몇 개 설치하다 보면 생성되는 'node_modules' 폴더의 악마 같은 용량을 풍자하는 유서 깊은 밈이다. 인터넷에는 블랙홀과 중성자별, 그리고 'node_modules' 폴더의 무게를 비교하는 짤방이 유행할 정도로 악명이 드높다. 의존성 라이브러리의 의존성의 의존성까지 무한으로 끌어다가 로컬에 내려받는 독특한 패키지 구조 덕분에, 소스 코드는 고작 몇 십 킬로바이트(KB)인데 빌드용 의존성 폴더는 500메가바이트(MB)를 훌쩍 넘어가는 기이한 풍경을 매일같이 감상할 수 있다.(...)

5. 여담

  • 라이언 달의 후회와 Deno: Node.js를 창시한 라이언 달은 이후 Node.js의 설계 오류들(난잡한 node_modules 구조, 빈약한 보안 모델, package.json에 대한 지나친 의존 등)을 공식적으로 후회하며, 이를 전면 개선한 새로운 런타임인 Deno를 만들어 배포했다. 하지만 이미 Node.js가 세상의 중심이 되어버려 Deno는 찬밥 신세를 면치 못하고 있다.
  • io.js라는 눈물의 반란: 2014년경 Node.js의 상표권을 쥐고 있던 Joyent 사의 부진한 관리와 느린 업데이트에 폭발한 핵심 개발진들이 프로젝트를 포크(Fork)하여 'io.js'라는 독자 런타임을 구축해 나갔다. 당황한 Joyent 사가 화해의 손길을 내밀며 자본과 커뮤니티를 합치기로 합의했고, 결국 4.0 버전에서 극적으로 재통합되는 역사적 화해극을 연출했다.
  • 자바스크립트의 지배력 확장: Node.js의 성공으로 인해 프론트엔드 개발자들이 프론트엔드 기술 그대로 백엔드까지 개발하는 '풀스택 개발자'의 전성시대가 열렸다. 이는 자바스크립트를 단지 화면 속의 장난감 스크립트에서 엔터프라이즈 서버를 설계하는 핵심 언어로 위상을 급상승시킨 결정적인 계기가 되었다.

6. 관련 문서

각주

  1. 실제로 자바 가상 머신(JVM)이나 .NET 서버가 수백 메가바이트의 메모리를 기본으로 드시고 시작할 때, Node.js 서버는 단 수십 메가바이트 수준의 경이로운 가벼움으로 가볍게 떠서 동작한다.

  2. 실제로 대량 연산이 필요한 인공지능이나 빅데이터 연산 분야에서는 Node.js를 거의 쓰지 않으며, 대부분 파이썬이나 C++ 기반의 도구들에게 자리를 양보하는 형국이다.