Node.js를 직접 만든다면? 런타임 구성 요소와 구현 예제
Node.js는 V8 JavaScript 엔진과 libuv 비동기 I/O 라이브러리를 기반으로 동작하는 JavaScript 런타임.
Node.js를 직접 만든다면 어떤 요소들이 필요한지, 그리고 실제로 C++로 구현해볼 수 있는 예제들을 통해 구조를 이해 ㄱㄱ
1. Node.js의 기본 구성 요소
Node.js는 아래와 같은 구성 요소로 이루어져 있음.
- JavaScript 엔진: V8 (또는 SpiderMonkey, JavaScriptCore)
- 비동기 I/O: libuv 또는 직접 구현한 이벤트 루프
- C++ 네이티브 모듈: 파일 시스템, 네트워크 API 등
- 바인딩 시스템: C++ API를 JS에서 호출할 수 있도록 연결
2. V8을 사용한 간단한 JavaScript 실행기
V8 엔진만 사용해도 JavaScript 코드를 실행 가능.
#include <v8.h>
#include <iostream>
using namespace v8;
int main() {
V8::InitializeICUDefaultLocation("");
V8::InitializeExternalStartupData("");
Platform* platform = v8::platform::NewDefaultPlatform().release();
V8::InitializePlatform(platform);
V8::Initialize();
Isolate* isolate = Isolate::New();
{
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
Local<Context> context = Context::New(isolate);
Context::Scope context_scope(context);
Local<String> source = String::NewFromUtf8(isolate, "'Hello, V8!'", NewStringType::kNormal).ToLocalChecked();
Local<Script> script = Script::Compile(context, source).ToLocalChecked();
Local<Value> result = script->Run(context).ToLocalChecked();
String::Utf8Value utf8(isolate, result);
std::cout << *utf8 << std::endl;
}
isolate->Dispose();
V8::Dispose();
V8::ShutdownPlatform();
delete platform;
}
위 코드를 통해 Node.js처럼 JavaScript 실행이 가능하지만, 파일 시스템이나 네트워크는 구현되지 않은 반쪽짜리임.
3. libuv를 이용한 비동기 이벤트 루프
Node.js는 libuv를 통해 비동기 I/O와 이벤트 루프를 관리. 아래는 비동기 타이머 예제.
#include <stdio.h>
#include <uv.h>
void timer_callback(uv_timer_t* handle) {
printf("비동기 타이머 실행됨!\n");
}
int main() {
uv_loop_t *loop = uv_default_loop();
uv_timer_t timer_req;
uv_timer_init(loop, &timer_req);
uv_timer_start(&timer_req, timer_callback, 1000, 0);
printf("이벤트 루프 시작!\n");
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
setTimeout()
처럼 타이머 기능을 구현할 수 있습니다.
4. JavaScript에서 C++ 함수 호출 (바인딩)
Node.js는 내부적으로 C++ 코드를 JavaScript에서 사용할 수 있게 바인딩. 아래는 예시.
#include <v8.h>
#include <uv.h>
using namespace v8;
void HelloWorld(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "Hello from C++!", NewStringType::kNormal).ToLocalChecked());
}
void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", HelloWorld);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
위 코드를 빌드하면 JavaScript에서 require('./myModule').hello()
로 C++ 함수를 실행할 수 있습니다.
5. 정리
Node.js는 결국 JavaScript 실행기(V8)에 다음과 같은 요소들이 결합된 런타임이다.
- V8 엔진
- libuv로 구현된 비동기 이벤트 루프
- C++로 작성된 네이티브 모듈
- JavaScript에서 네이티브 호출을 가능하게 하는 바인딩
'web' 카테고리의 다른 글
WEB - Web Worker, 웹 워커 (0) | 2025.05.11 |
---|---|
Javascript - 자바스크립트의 모듈 시스템 (0) | 2025.05.11 |
Prisma - Node.js ORM Prisma 동작 원리 (1) | 2025.05.02 |
Web Assembly - WASM, 웹 어셈블리 (1) | 2025.05.02 |
Typescript - 타입스크립트 자주 발생하는 에러 (0) | 2025.05.02 |