상황

앰플리튜드 설치가 필요해 yarn add @amplitude/analytics-browser
명령어를 입력했을 뿐인데, 위와 같은 화면이 나타났습니다.
원인
Yarn Berry를 적용한 repository에서 작업하고 있었습니다. Yarn Berry는 .yarn/cache
폴더에 의존성 정보를 저장하는데,
Import trace for requested module:
부분에 .yarn/cache
가 여러 번 뜨는 걸 보고 의존성 문제임을 짐작했습니다.
@amplitude/plugin-web-attribution-browser
의 dependencies를 확인해 보니, @amplitude/analytics-core
가 dependencies로 명시되어 있었습니다.
즉, 이 플러그인은 내부적으로 @amplitude/analytics-core
에 의존하고 있었어요.
하지만 제가 작업 중인 프로젝트의 package.json에는 @amplitude/analytics-core
가 명시되어 있지 않았고,
Yarn Berry는 프로젝트에서 해당 의존성을 찾을 수 없어 Module not found 에러가 발생한 것입니다.
해결 방법
Yarn Berry에서 누락된 의존성을 해결하는 방법은 크게 두 가지가 있습니다.
이 경우, @amplitude/analytics-core
를 프로젝트의 dependencies로 직접 설치하거나,
packageExtensions 기능을 이용해 로컬에서 해당 패키지의 의존성 정보를 보완해야 합니다.
프로젝트에서 직접 사용하지도 않는 모듈을 설치하는 것이 과연 좋은 해결 방법일까 하는 의문이 들었습니다.
그래서 packageExtensions를 사용해 의존성 정보를 확장하는 방법을 선택했습니다.
해당 플러그인이 @amplitude/analytics-core
를 필요로 한다는 사실을 Yarn에 알리면 됩니다.
내가 직접 사용하는 건 아니지만, 반드시 함께 설치되어 있어야 한다고 기대하는 경우에는 peerDependencies로 선언해야 의존성 관계가 정확하게 표현됩니다.
peerDependencies는 호환성을 보장하기 위해 사용되는 개념입니다.
사용자가 프로젝트에서 특정 버전의 패키지를 함께 설치하도록 요구하기 위해 정의합니다.
이해를 돕기 위해 useSum
이라는 훅을 가지는 use-sum
패키지를 만들었다고 가정해 볼게요.
const useSum = (a, b) => {
return a + b;
};
export default useSum;
이때는 다음과 같이 package.json을 작성할 수 있습니다.
{
"name": "use-sum",
"version": "1.0.0",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
}
실제로 다양한 React 훅을 제공하는 @react-hookz/web
패키지도
다음과 같은 package.json을 가집니다.
{
"name": "@react-hookz/web",
"peerDependencies": {
"js-cookie": "^3.0.5",
"react": "^16.8 || ^17 || ^18 || ^19",
"react-dom": "^16.8 || ^17 || ^18 || ^19"
},
}
앞서 살펴본 packageExtensions와 peerDependencies 개념을 바탕으로 yarn config set
명령어를 사용해 Yarn 패키지 매니저의 설정을 변경하면 됩니다.
yarn config set 'packageExtensions["@amplitude/plugin-web-attribution-browser@0.7.0"].peerDependencies["@amplitude/analytics-core"]' '^0'
이 명령어는 @amplitude/plugin-web-attribution-browser
패키지가 버전 '0.x.x'의 @amplitude/analytics-core
패키지를 peerDependencies로 가지도록 설정하겠다는 의미입니다.
명령어를 실행한 이후에는 .pnp.cjs
와 .yarnrc.yml
파일이 수정되었습니다.
// .yarnrc.yml
packageExtensions:
"@amplitude/plugin-web-attribution-browser@0.7.0":
peerDependencies:
"@amplitude/analytics-core": "^0"
이렇게 되면 @amplitude/plugin-web-attribution-browser
패키지가 @amplitude/analytics-core
패키지를 참조하는 상황에서 오류가 발생하지 않습니다.
예전에 읽은 아티클을 통해 Yarn Berry의 Plug'n'Play(PnP) 전략 덕분에 엄격한 의존성 관리가 가능함을 인지하고만 있었는데, 이 장점을 실제로 경험한 것이 신기해 글로 남겨봅니다.