[npm] --legacy-peer-deps / --force 옵션 차이점
Peer Dependencies란 무엇인가?
Peer dependencies는 특정 패키지가 정상적으로 동작하기 위해 다른 패키지의 특정 버전이 프로젝트에 존재해야 하는 경우에 사용됩니다. 보통 라이브러리나 플러그인이 **호스트 패키지**(예: React)와 긴밀하게 연결되어 있을 때 필요합니다.
Peer dependencies는 해당 패키지가 독립적으로 설치되지 않고, **호스트 패키지와의 버전 호환성을 사용자에게 맡기는 것**이 특징입니다.
예시로 이해하기:
`custom-cursor-react`라는 패키지가 있다고 가정해 봅시다. 이 패키지는 React를 기반으로 작동하므로, 개발자는 프로젝트에 React가 설치되어 있어야 한다고 가정합니다.
이때, `custom-cursor-react`는 자신이 **React의 특정 버전에서만 잘 동작**한다고 명시해야 합니다.
만약 `custom-cursor-react`가 React 16에서만 정상 작동한다고 가정하면, package.json에 다음과 같이 명시합니다:
"peerDependencies": {
"react": "^16.0.0"
}
**Peer dependencies**는 직접 설치되지 않으며, 이를 사용하는 **최종 사용자**가 프로젝트의 호환되는 버전을 직접 관리해야 합니다.
각 옵션이 어떻게 peer dependencies를 처리할까?
옵션 1: `npm install --legacy-peer-deps`
npm install --legacy-peer-deps
이 옵션은 **npm의 최신 버전**에서 도입된 **엄격한 peer dependencies 확인**을 건너뛰고, **기존의 방식**으로 의존성을 처리합니다.
기본적으로 `npm v7`부터는 패키지를 설치할 때 **peer dependencies**도 함께 설치하려고 시도하며, 만약 버전이 맞지 않으면 설치를 중단합니다.
**이 옵션을 사용하면:**
- **peer dependencies 충돌을 무시**하고, 프로젝트가 요구하는 버전을 무시하면서 패키지를 설치합니다.
- 예를 들어, `custom-cursor-react`가 React 16을 요구하지만, 프로젝트에 React 18이 설치되어 있을 때 이 옵션을 사용하면, 충돌을 무시하고 `custom-cursor-react`를 설치할 수 있습니다.
**결과:**
- React 18 버전은 유지됩니다.
- `custom-cursor-react` 패키지는 설치되지만, React 18과 호환성 문제는 발생할 수 있습니다.
옵션 2: `npm install --force`
npm install --force
이 옵션은 모든 의존성 충돌을 무시하고, **강제로 설치**를 진행합니다.
즉, `package.json`에 명시된 대로 모든 패키지를 설치하며, 호환되지 않는 의존성도 **강제로** 설치합니다.
**이 옵션을 사용하면:**
- 모든 패키지가 설치되지만, 의존성 충돌이 있는 패키지가 강제 설치되기 때문에, 프로젝트가 정상적으로 동작하지 않을 가능성이 큽니다.
- 예를 들어, `custom-cursor-react`가 React 16을 요구하지만, 프로젝트에 React 18이 설치되어 있는 경우 **충돌을 무시하고 강제로 설치**합니다. 이는 충돌이 해결되지 않았기 때문에 문제가 발생할 가능성이 높습니다.
### 요약:
- **Peer dependencies**는 주로 플러그인이나 라이브러리가 **호스트 패키지(예: React)**와 긴밀하게 연결되어 있을 때 사용되며, 특정 버전이 필요합니다.
- **옵션 1**은 peer dependencies 충돌을 무시하고 **설치하지만** 비교적 안전하게 설치가 진행됩니다.
- **옵션 2**는 의존성 충돌을 **무시하고 강제 설치**하기 때문에 프로젝트에 예상치 못한 문제가 생길 수 있습니다.
이해를 돕기 위해 예시로 설명드리면, `custom-cursor-react`가 React 16을 요구하는데, 프로젝트에 React 18이 있는 상황에서:
- **옵션 1**은 React 18을 유지한 채 충돌을 무시하고 설치하지만, 문제가 생길 가능성이 있습니다.
- **옵션 2**는 충돌을 강제 무시하고 설치해 더 큰 문제가 발생할 수 있습니다.
이를 기반으로, 실제 프로젝트에 적용할 때는 가능하면 **옵션 1을 사용하는 것이 안전**합니다.
충돌을 무시하고 설치한다는 것은?
- **peer dependencies를 설치하지 않고**라는 의미는, `npm`이 **해당 패키지가 필요로 하는 다른 패키지**(예: `react@16`)를 자동으로 설치하려고 하지 않는다는 뜻입니다. 대신 **현재 프로젝트에 이미 있는 패키지**(예: `react@18`)를 그대로 두고 설치를 진행합니다.
- 예를 들어, `custom-cursor-react`가 **React 16**을 요구하고 있지만, 이미 프로젝트에는 **React 18**이 설치되어 있을 때, `npm`은 React 16을 따로 설치하지 않고 **이미 있는 React 18을 그대로 유지**하면서 `custom-cursor-react`를 설치합니다. 하지만 이 경우 `custom-cursor-react`는 React 18과 호환되지 않을 수 있습니다.
### **충돌을 무시하고 설치한다**는 의미는?
- `custom-cursor-react`가 React 16을 요구하더라도, **React 18이 이미 설치된 상태에서** 패키지를 설치할 때 그 **호환성 문제를 무시**하고 설치를 진행한다는 뜻입니다. 즉, **충돌 경고는 나오지만 설치가 중단되지 않고 계속됩니다.**
npm install --legacy-peer-deps
- **결과:** `custom-cursor-react`가 설치되지만, `peer dependencies`로 명시된 React 16은 설치되지 않고, 프로젝트에 이미 설치된 **React 18**은 그대로 유지됩니다.
이 방식은 **peer dependencies 충돌을 일으키는 패키지를 무시하고 설치**하는 것이며, 설치 후에도 해당 패키지가 **제대로 작동하지 않을 수 있는** 위험이 존재합니다.
요약
npm install --legacy-peer-deps
옵션1. 충돌 무시, 강제 설치(단, peer dependencies를 자동으로 설치하지 않음)(즉, A라이브러리가 B라이브러리 16.0.0 버전을 필요로 하는 라이브러리여도 해당 라이브러리를 설치하지 않고 기존 버전의 B라이브러리를 사용)
npm install --force
옵션2. 충돌 무시, 강제 설치(package.json에 명시된 그대로 강제설치)