`npm install` 이 내부적으로 하는 일 

npm install 은 크게 두 종류의 의존성을 처리합니다:

구분예시설치 방식OS 영향 여부
순수 JS 패키지 lodash, axios, moment 등 .js 파일만 다운로드 ❌ 영향 없음
네이티브 애드온 패키지 node-sass, bcrypt, sqlite3, canvas, sharp 등 C/C++ 소스를 node-gyp 로 빌드 → .node 바이너리 생성 ✅ OS·Node·컴파일러·라이브러리 모두 영향받음

즉, 순수 JS 모듈은 어디서 설치해도 동일하지만,
네이티브 모듈은 빌드된 결과(.node)가 OS·CPU·Node 버전에 따라 다릅니다.

 

 

 

js 파일을 실행시키는 것은 문제가 안되지만, C/C++로 작성된 확장 모듈 (ex. glibc, OpenSSL, GCC, python) 은 OS와 런타임의 ABI에 직접 의존하기 때문에 로드하는 Node 프로세스는 순간 오류가 나거나 죽을 수 있다.

npm install 시 이 모듈들은 c++로 빌드가 된다.

즉, npm install을 어느 OS에서 진행하냐에 따라 애드온의 결과가 달라진다.

다만 모든 패키지가 그런 것은 아니고 'C/C++로 빌드가 필요한 모듈'만 OS에 영향을 받는다.

 

대표적인 네이티브 애드온

Node 프로젝트에는 **C/C++로 작성된 확장 모듈(네이티브 애드온)**이 종종 들어있습니다.
대표적인 예가 아래입니다.

모듈명 설명 특징
node-sass SCSS를 C++로 컴파일 libsass.so 등 네이티브 코드
bcrypt 암호화 알고리즘 구현 OpenSSL, glibc 의존
canvas, sqlite3, fsevents 등 시스템 라이브러리 직접 호출 OS/컴파일러와 강하게 묶임

 

빌드가 OS별로 달라지는 이유

(1) node-gyp 빌드는 OS의 “컴파일러 + 시스템 라이브러리”를 사용

  • Linux → gcc, glibc, libstdc++, OpenSSL
  • macOS → clang, libc++, CommonCrypto
  • Windows → MSVC, msvcrt.dll

→ 각 플랫폼마다 ABI(Application Binary Interface)심볼 이름이 다름.
따라서 동일한 C++ 코드라도 다른 바이너리 형태로 컴파일됩니다.

예:

 
build/Release/bcrypt_lib.node # Linux build/Release/bcrypt_lib.node # macOS build/Release/bcrypt_lib.node # Windows

파일 이름은 같지만 내부 구조가 완전히 다름.

(2) Node 버전에 따라 ABI 버전(NODE_MODULE_VERSION)이 다름

Node 10 = ABI 64, Node 12 = ABI 72, Node 16 = ABI 93 …
→ Node10에서 빌드한 모듈은 Node16에서 로드 불가.

에러 예시:

 
Error: The module '/.../binding.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 64.

 

(3) OS 버전(glibc 차이)에 따라 심볼 링크 달라짐

  • RHEL7 glibc 2.17
  • RHEL9 glibc 2.34
    → RHEL9에서 빌드하면 GLIBC_2.28 이상 심볼 사용 → RHEL7에서는 “not found” 오류 발생
 
/lib64/libc.so.6: version `GLIBC_2.28' not found

 

 

예시: bcrypt 설치 결과 비교

환경결과 바이너리glibc/ABI 의존성
RHEL7 + Node10 bcrypt_lib.node (ELF, glibc 2.17) 낮은 glibc 심볼
RHEL9 + Node10 bcrypt_lib.node (ELF, glibc 2.34) 높은 glibc 심볼
Windows + Node10 bcrypt_lib.node (DLL, PE/COFF) msvcrt 의존

모양은 같지만 내부 코드 완전히 다름.
따라서 한 OS에서 만든 node_modules를 다른 OS에 옮기면 작동이 안 될 수 있음.

 

 

확인 방법

(1) 네이티브 모듈 찾기

 
find node_modules -name '*.node' -print

(2) 빌드 환경 확인

 
file node_modules/**/binding.node ldd node_modules/**/binding.node | egrep 'libc|stdc++' node -p "process.versions.modules"

 

 

OS별 빌드 차이를 피하는 방법

 

전략 설명 비고
① 사전 빌드(prebuild) 패키지 제작자가 OS별로 미리 빌드해 배포 (prebuild-install 사용) 가장 안전. 단, 폐쇄망에서는 다운로드 불가 가능
② 동일 OS 환경에서 빌드 운영환경(RHEL9 등)과 동일한 OS 버전에서 npm install 실행 내부망 배포 시 재현성↑
③ Docker / CI 빌드 이미지 고정 node:10-buster 등 고정 이미지로 항상 동일 glibc에서 빌드 RHEL9 서버에서도 호환
④ JS-only 대체 사용 bcrypt → bcryptjs, node-sass → sass 빌드 필요 없음

 

'#시스템관리 > 마이그레이션' 카테고리의 다른 글

레지스트리란  (0) 2025.11.09

  복합키(@EmbeddedId)의 내부 필드에 접근할 때는 **언더스코어(_)**를 사용합니다:

  - Id → 복합키 필드명 (PrdtMstrId)
  - Id_PrdtId → 복합키 내부의 prdtId 필드
  - Id_HistStrDate → 복합키 내부의 histStrDate 필드

  따라서:
  - findFirstById_PrdtId → id.prdtId로 조회
  - OrderById_HistStrDateDesc → id.histStrDate로 내림차순 정렬
  - findFirst → 첫 번째 결과만 반환

  이제 @Query 없이도 JPA가 자동으로 쿼리를 생성합니다!

'#개발 > JPA' 카테고리의 다른 글

Spring Data JPA Query Method  (0) 2025.10.23

+ Recent posts