프론트엔드 개발을 하다 보면 dependencies, devDependencies, peerDependencies는 자주 마주치게 됩니다. 자주 보긴 하는데 정확히 어떤 차이가 있는지 헷갈릴 수 있죠. 이 글에서는 각각의 개념을 간단한 예시와 함께 설명하고, 특히 헷갈리기 쉬운 peer dependencies를 집중적으로 알아보겠습니다.
가장 일반적인 애플리케이션의 의존성입니다.
런타임, 개발 중, 빌드 시 모든 상황에서 필요합니다.
애플리케이션을 빌드할 때 번들에 포함되어 함께 배포됩니다.
// 예: my-app의 package.json
"dependencies": {
"react": "^18.0.0",
"axios": "^1.4.0"
}이 패키지들은 실제 서비스가 동작할 때도 반드시 필요한 모듈입니다.
개발 도중이나 빌드할 때만 필요한 의존성입니다.
개발 중, 또는 빌드 시에만 사용됩니다. 런타임에는 필요 없습니다.
webpack, eslint, jest 같은 툴들이 여기에 포함됩니다.
번들에는 포함되지 않으며, 실제 서비스에서는 사용되지 않습니다.
// 예: my-app의 package.json
"devDependencies": {
"eslint": "^8.0.0",
"jest": "^29.0.0"
}이 패키지들은 오직 개발을 수월하게 하기 위한 도구일 뿐, 실제 동작에는 영향을 주지 않습니다.
이제 본론입니다. peer dependencies는 종종 이해하기 어려운 개념 중 하나인데, 이렇게 생각해보세요.
"내가 직접 필요하진 않지만, 나를 사용하는 프로젝트에서는 반드시 이 패키지가 필요해!"
당신이 React 기반의 UI 컴포넌트 라이브러리 my-ui-library를 만든다고 가정해봅시다. 이 라이브러리는 React 위에서 동작하므로 React가 반드시 필요합니다.
하지만, 직접 react를 설치하면 어떻게 될까요?
// my-ui-library package.json
"peerDependencies": {
"react": "^17.0.0"
}이 말은 곧,
"나를 사용하려면 React 17이 설치되어 있어야 해!"
라고 사용하는 쪽(my-app)에게 알려주는 것입니다.
// my-app의 package.json
"dependencies": {
"react": "^16.0.0",
"my-ui-library": "^0.0.1"
}my-ui-library는 React 17 이상을 원하지만, my-app은 React 16만 설치되어 있죠. 이 경우 어떤 일이 일어날까요?
warning "my-ui-library@0.0.1" has incorrect peer dependency "react@^17.0.0".react를 따로 설치하면 버전 충돌이나 번들 크기 증가 문제가 생깁니다.| 항목 | 설명 | 번들 포함 여부 |
|---|---|---|
dependencies | 런타임, 개발, 빌드 모두에서 사용되는 의존성 | ✅ 포함 |
devDependencies | 개발, 빌드에만 필요한 도구 (런타임엔 불필요) | ❌ 미포함 |
peerDependencies | 라이브러리가 의존하지만 직접 포함하지는 않는 패키지 | ❌ 미포함 |