👉🏻 Nodejs에서 C++ 애드온(Native Addons)을 사용하는 이유는 Node.js의 성능 제한을 극복하고, 기존의 C++ 생태계와 자원을 활용하기 위함입니다.
The reason for using C++ addons (Native Addons) in nodejs is to overcome the performance limitations of Node.js and to leverage the existing C++ ecosystem and resources.
👉🏻 아래는 맥os에서 실행되었습니다.
Below was run on macOS.
1.코드작성 / Write code
1.1 sersver.js
// server.js
const express = require("express");
const app = express();
const port = 3000;
// 1. C++ 애드온 로드 / Loading C++ add-ons
// node-gyp 빌드 후 생성되는 .node 파일의 경로를 지정합니다.
// Specifies the path to the .node file generated after building node-gyp.
// (빌드가 성공하면 build/Release/addon_module.node 파일이 생성됩니다.)
// (If the build is successful, the build/Release/addon_module.node file will be created.)
const cppAddon = require("./build/Release/addon_module");
app.use(express.json());
// 2. C++ 애드온을 사용하는 API 엔드포인트 정의
// Defining API endpoints using C++ add-ons
app.get("/calculate", (req, res) => {
// 쿼리 파라미터에서 두 숫자를 추출
// Extract two numbers from query parameters
const num1 = parseFloat(req.query.a);
const num2 = parseFloat(req.query.b);
if (isNaN(num1) || isNaN(num2)) {
return (
res
.status(400)
//Please enter valid numbers for query parameters 'a' and 'b'.
.send("쿼리 파라미터 'a'와 'b'에 유효한 숫자를 입력하세요.")
);
}
try {
// 3. C++ 애드온의 함수 호출 / Calling functions in C++ add-ons
const result = cppAddon.multiply(num1, num2);
// 4. 결과를 클라이언트에게 응답 / Reply the results to the client
res.json({
input_a: num1,
input_b: num2,
source: "C++ Addon",
result: result,
});
} catch (error) {
console.error("C++ add-on call error:", error.message);
res.status(500).send("Server internal error occurred");
}
});
app.listen(port, () => {
console.log(`Node.js server is running at http://localhost:${port} .`);
console.log(`Test URL: http://localhost:${port}/calculate?a=123&b=4.5`);
});
1.2 addon.cpp
// addon.cpp
/*
* 이 코드는 "현재 Node.js 환경(env)에서 C++ 변수 result를 이용하여 새로운 JavaScript 숫자 객체를 만들어 반환하라"는 의미가 됩니다.
* This code means "Create a new JavaScript numeric object
* using the C++ variable result in the current Node.js environment (env) and return it."
*
* C++ 애드온은 main함수가 없는 이유:Node.js 자체에 이미 거대한 main 함수가 포함되어 있기 때문입니다.
* Why C++ addons don't have a main function: Because Node.js itself already contains a huge main function.
*
* Napi::Number는 node-addon-api 라이브러리에서 제공하는 C++ 클래스로, Node.js 환경에서 통신할 때 JavaScript의 number 타입을 나타냅니다.
* Napi::Number is a C++ class provided by the node-addon-api library that represents the JavaScript number type when communicating in a Node.js environment.
*
* Napi::Number 클래스는 내부적으로 C++의 기본 숫자 타입을 JavaScript가 이해하는 숫자 객체 포맷으로 변환해 줍니다.
* The Napi::Number class internally converts C++'s basic number type into a numeric object format that JavaScript understands.
*/
// C++ 개발자가 Node.js의 고성능 네이티브 기능을 사용하기위한 헤더
// Header for C++ developers to use high-performance native features of Node.js
#include <napi.h>
#include <iostream>
// JavaScript에서 호출될 C++ 함수 정의
// Define a C++ function to be called from JavaScript
Napi::Number Multiply(const Napi::CallbackInfo& info) {
// env: 현재 Node.js의 실행 환경(Napi::Env)을 나타냅니다.
// env: Represents the current Node.js execution environment (Napi::Env).
Napi::Env env = info.Env();
// 인자 개수 확인 / Check number of arguments
if (info.Length() < 2 || !info[0].IsNumber() || !info[1].IsNumber()) {
Napi::TypeError::New(env, "두 개의 숫자를 입력해야 합니다.").ThrowAsJavaScriptException();
return env.Null().As<Napi::Number>();
}
// JavaScript 인자를 C++ 숫자로 변환
// Convert JavaScript arguments to C++ numbers
double a = info[0].As<Napi::Number>().DoubleValue();
double b = info[1].As<Napi::Number>().DoubleValue();
// C++ 로직 실행
// Execute C++ logic
double result = a * b;
std::cout << "C++ 애드온에서 곱셈 로직 실행됨: " << a << " * " << b << std::endl;
// 결과를 JavaScript Number 타입으로 변환하여 반환
// Convert the result to JavaScript Number type and return it
// New()는 새로운 JavaScript 객체를 생성하는 메서드
// New() is a method that creates a new JavaScript object.
return Napi::Number::New(env, result);
}
// 모듈 초기화 (exports 객체에 함수 등록)
// Initialize module (register functions in exports object)
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(
// 자바스크립트에서 addon.multiply(a, b);로 사용됨.
// Used in JavaScript as addon.multiply(a, b);
Napi::String::New(env, "multiply"),
// Function타입은 자바스크립트에서 함수로 사용 할 수 있게 해줌.
// The Function type allows you to use it as a function in JavaScript.
// 실제로 실행될 c++ 함수입니다. / This is the c++ function that will actually be executed.
Napi::Function::New(env, Multiply)
);
return exports;
}
// Node.js 모듈로 등록
// Register as a Node.js module
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
1.3 binding.gyp
# GYP (Generate Your Projects): 이 형식은 Google에서 개발되었으며,
# 원래는 Chromium 프로젝트를 위해 사용되었습니다.
# 이는 다양한 플랫폼(macOS, Linux, Windows)에서 C++ 프로젝트를 빌드하기 위한 빌드 시스템 설정 언어입니다.
# GYP (Generate Your Projects): This format was developed by Google and was originally used for the Chromium project.
# It is a build system configuration language for building C++ projects on various platforms (macOS, Linux, Windows).
# binding.gyp
{
"targets": [
{
# target_name : 최종적으로 생성될 .node 파일의 이름 / The name of the .node file that will ultimately be created
# sources : 빌드할 소스 코드 파일 목록을 지정합니다. / Specifies a list of source code files to build.
# include_dirs : C++ 코드에서 #include <napi.h>를 사용할 수 있도록 합니다. / Enables you to use #include <napi.h> in your C++ code.
"target_name": "addon_module",
"sources": [ "addon.cpp" ],
"include_dirs": [
"<!@(node -p \"require('node-addon-api').include\")"
],
"defines": [ "NAPI_CPP_EXCEPTIONS" ],
# C++ 컴파일러 플래그 설정: 예외 처리 활성화 / Setting C++ Compiler Flags: Enable Exception Handling
# -- C++의 핵심 기능인 try, catch, throw 구문이 컴파일되어 런타임에 제대로 작동할 수 있도록 만듭니다.
# The try, catch, and throw statements, which are core features of C++, are compiled so that they work properly at runtime.
"cflags_cc": [
"-fexceptions"
],
# (macOS 전용) XCode/Darwin 빌드 설정 오버라이드
# (macOS only) Override XCode/Darwin build settings
# 예외처리 기능이 비활성화되면 오류가 발생합니다.
# 아래의 코드는 맥os의 예외처리 기능을 활성화하는 코드 입니다.
# An error will occur if exception handling is disabled.
# The code below enables exception handling in macOS.
'xcode_settings': {
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', # C++ 예외 활성화
'OTHER_CPLUSPLUSFLAGS': [ '-fexceptions' ] # 추가 플래그
},
# 안전을 위해 기본 -fno-exceptions를 제거 (만약 node-gyp 기본 설정에 있다면)
# Remove default -fno-exceptions for safety (if it's in node-gyp default config)
# cflags! : C 컴파일러의 예외 비활성화 옵션 제거 / Removed the option to disable exceptions from the C compiler.
# cflags_cc! : C++ 컴파일러의 예외 비활성화 옵션 제거 / Removed the option to disable exceptions from the C++ compiler.
"cflags!": [ "-fno-exceptions" ],
"cflags_cc!": [ "-fno-exceptions" ]
}
]
}
2.1.의존성 설치 / install dependencies
npm install node-gyp node-addon-api express --save
2.2.C++ 애드온 빌드 / C++ add-on build
npx node-gyp configure
npx node-gyp build
2.3.서버실행 / server run
node server.js
2.4 터미널에서 테스트 / Test in terminal
curl http://localhost:3000/calculate?a=123&b=4.5
2.5 브라우저 테스트 결과 / Browser test results
{
"input_a": 123,
"input_b": 4.5,
"source": "C++ Addon",
"result": 553.5
}
3. 실행 / Run


4.설정파일을 수정한 경우 / If you have modified the settings file
4.1 빌드파일정리 / Build file organization
npx node-gyp clean
4.2 구성 재실행 / Rerun configuration
npx node-gyp configure
4.3 빌드 재실행 / Rerun the build
npx node-gyp build