본 글은 Udemy에서 Node JS: Advanced Concepts 강의를 듣고 정리한 글입니다.
우리가 작성한 Javascript 코드가 NodeJS에서는 어떤식으로 동작하는지 다음 그림을 보면서 설명하도록 하겠다.
가장 위를 보면 우리가 일반적으로 작성하는 Javascript 코드가 있다. 그 밑으로는 NodeJS가 있는데 NodeJS 안에는 여러가지 기본모듈들(http, fs, crypto, path 등)이 존재한다. 그 모듈은 50%는 JS, 나머지 50%는 C++으로 되어있다.
NodeJS는 2가지 의존성을 갖는데 V8과 libuv이다.
그렇다면 NodeJS는 왜 탄생했을까? 🤔 우리같은 웹 개발자들은 C++를 쓰기를 원하지 않고 자바스크립트를 쓰기를 원하기 때문이다 (실제로는 내부적으로 C++로 동작하지만...)
이제 NodeJS 에 있는 기본 라이브러리 모듈이 어떤식으로 실행되는지 한번 보도록 하겠다.
진행 순서는 다음과 같다.
여기서는 crypto
라이브러리에 있는 pbkdf2
함수를 선택했다. 소스코드는 NodeJS 깃허브에서 찾아볼 수 있다. 참고로 pbkdf2
는 암호화할때 쓰이는 함수이다.
먼저 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++ 소스코드는 node > src > node_crypto.cc에 존재한다. 참고로 src 디렉토리는 C++로 구현되어있는 집합체이다. C++ 코드를 잘 보면 거의 마지막줄에 보면 내보내기함수가 있다. 따라서 Javascript 파일에서 이걸 interbinding 해서 쓸 수 있었던 것이다.
그리고 중간에 보면 실제 구현된 PBKDF2 함수가 있다. Javascript 코드인줄 알았는데 알고보니 실제동작은 C++로 되어있다는 사실이 뭔가 새롭게 다가오지 않는가? 😲
node_crypto.cc 상단에 보면 using v8
이 보인다. using v8::False
라고 쓰면 JS에서의 False 개념을 C++이 이해하도록 V8이 중간자 역할을 한다. 이를 통해 C++는 Javascript 정수, 문자열, 배열 등을 이해할 수 있게 된다.
libuv도 사용되는데 libuv를 의미하는 uv
를 검색해 보면 된다. libuv는 C++ 쪽에 있는 많은 동시성 및 처리 구조를 위해 사용되는데, 그것은 사실 우리가 나중에 조금 더 깊이 들어가 볼 중요한 논의의 주제이다.
정리해보면 NodeJS는 다음과 같은 프로세스로 동작한다는 것을 알 수 있었다.