NodeJS 내부 살펴보기

기운찬곰·2020년 9월 15일
3

NodeJS 이론

목록 보기
1/4
post-thumbnail

본 글은 Udemy에서 Node JS: Advanced Concepts 강의를 듣고 정리한 글입니다.

Hits


NodeJs 동작원리

우리가 작성한 Javascript 코드가 NodeJS에서는 어떤식으로 동작하는지 다음 그림을 보면서 설명하도록 하겠다.

가장 위를 보면 우리가 일반적으로 작성하는 Javascript 코드가 있다. 그 밑으로는 NodeJS가 있는데 NodeJS 안에는 여러가지 기본모듈들(http, fs, crypto, path 등)이 존재한다. 그 모듈은 50%는 JS, 나머지 50%는 C++으로 되어있다.

NodeJS는 2가지 의존성을 갖는데 V8과 libuv이다.

  • V8은 오픈소스 자바스크립트 엔진으로서 구글이 개발하여 크롬에서 쓰이고 있으며 브라우저 밖에서도 자바스크립트가 실행될 수 있도록 결정적인 역할을 했다.
  • libuv는 C++ 오픈소스 프로젝트로 NodeJS 가 OS에 접근하도록 또는 파일시스템과 네트워킹, 기타 다른것에 접근할 수 있는 모듈로 되어있다. 한마디로 NodeJS가 플랫폼 독립적인데 결정적인 역할을 했다.

그렇다면 NodeJS는 왜 탄생했을까? 🤔 우리같은 웹 개발자들은 C++를 쓰기를 원하지 않고 자바스크립트를 쓰기를 원하기 때문이다 (실제로는 내부적으로 C++로 동작하지만...)


모듈 실행과정


이제 NodeJS 에 있는 기본 라이브러리 모듈이 어떤식으로 실행되는지 한번 보도록 하겠다.

진행 순서는 다음과 같다.

  1. Pick a function in node standard library (Library 안에 함수 한개를 선택)
  2. Find where its implemented in the node source code (그 함수의 node source code를 살펴본다)
  3. See how V8 and libuv are used to implement that function (V8과 libuv가 어떤식으로 사용되는지 살펴본다)

여기서는 crypto 라이브러리에 있는 pbkdf2 함수를 선택했다. 소스코드는 NodeJS 깃허브에서 찾아볼 수 있다. 참고로 pbkdf2는 암호화할때 쓰이는 함수이다.

Javascript

먼저 pbkdf2 function이 어떤식으로 존재하는지 살펴보자. 참고로 lib 디렉토리는 Javascript로 정의되어있는 모듈과 함수 집합체라고 보면 된다. (경로 : node > lib > internal > crypto > pbkdf2.js)

pbkdf2가 Javascript 함수로 구현된 것을 볼 수 있다. 하지만 잘 보면 사실 내부적인 동작은 _pbkdf2를 호출해서 처리하고 있다. 결국 pbkdf2가 하는 역할은 중간에 구현된건 에러체킹 정도이고 실제 내부적인 동작은 _pbkdf2가 처리하고 있다는 것이다.

💻 참고. internalBinding()
the private internal C++ binding loader, inaccessible from user land because they are only available from NativeModule.require() These C++ bindings are created using NODE_MODULE_CONTEXT_AWARE_INTERNAL() and have their nm_flags set to NM_F_INTERNAL.

internalBidnig()의 의미를 보면 C++ 바인딩이라고 적혀있다. 즉 JS와 C++을 이어주는 역할을 한다.

C++

C++ 소스코드는 node > src > node_crypto.cc에 존재한다. 참고로 src 디렉토리는 C++로 구현되어있는 집합체이다. C++ 코드를 잘 보면 거의 마지막줄에 보면 내보내기함수가 있다. 따라서 Javascript 파일에서 이걸 interbinding 해서 쓸 수 있었던 것이다.

그리고 중간에 보면 실제 구현된 PBKDF2 함수가 있다. Javascript 코드인줄 알았는데 알고보니 실제동작은 C++로 되어있다는 사실이 뭔가 새롭게 다가오지 않는가? 😲

V8

node_crypto.cc 상단에 보면 using v8이 보인다. using v8::False라고 쓰면 JS에서의 False 개념을 C++이 이해하도록 V8이 중간자 역할을 한다. 이를 통해 C++는 Javascript 정수, 문자열, 배열 등을 이해할 수 있게 된다.

libuv

libuv도 사용되는데 libuv를 의미하는 uv를 검색해 보면 된다. libuv는 C++ 쪽에 있는 많은 동시성 및 처리 구조를 위해 사용되는데, 그것은 사실 우리가 나중에 조금 더 깊이 들어가 볼 중요한 논의의 주제이다.


결론

정리해보면 NodeJS는 다음과 같은 프로세스로 동작한다는 것을 알 수 있었다.

profile
배움을 좋아합니다. 새로운 것을 좋아합니다.

0개의 댓글