package-lock.json 과 yarn.lock 파일의 정체는 뭘까
=> 패키지 잠금을 위한 파일들
패키지를 프로젝트에 설치하거나 갱신 또는 삭제하는데 사용되는 도구를 패키지 매니저라고 하는데요.
현재 자바스크립트 커뮤니티는 npm과 yarn, 이렇게 두가지 도구로 양분이 되어 있는 상황입니다.
기본적으로 이 두가지 도구 모두 앞으로 설명드릴 패키지 잠금 기능을 지원하고 있는데요.
npm은 package-lock.json 파일을, yarn은 yarn.lock 파일을 패키지 잠금 파일로 사용합니다.
즉, 패키지 잠금 파일은 자신이 개발을 하는 프로젝트에서 어떤 패키지 매니저를 사용하느냐에 따라 달라지게 됩니다.
패키지 관리 메커니즘
패키지 잠금을 이해하려면 먼저 패키지 매니저가 프로젝트가 의존하는 패키지를 어떻게 관리해주는지 이해하는 것이 좋습니다.
패키지 관리를 위해 npm을 사용하든 yarn을 사용하든 해당 프로젝트의 메타 정보는 package.json 파일을 통해 관리가 됩니다. 이 package.json 파일에는 해당 프로젝트가 의존하고 있는 모든 패키지 이름과 버전이 나열되어 있는데요. 일반적으로 설치되어야 하는지 패키지들은 dependencies 항목에, 그리고 개발할 때만 필요한 패키지들은 devDependencies 항목에 명시됩니다.
예를 들어, react와 react-dom 패키지에 의존하는 프로젝트의 package.json 파일의 모습은 대략 다음과 같을 것입니다.
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"react": "^16.8.2",
"react-dom": "^16.8.2"
}
}
이렇게 설치가 필요한 패키지들이 package.json 파일에 등록이 되어 있으면, 프로젝트의 모든 개발자는 패키지 매니저의 설치 커맨드 하나로 모든 패키지를 한번에 설치할 수 있습니다.
아래와 같이 프로젝트에서 사용하고 있는 패키지 매니저에 따라 설치 커맨드를 날리면 package.json 파일에 등록되어 있는 모든 패키지가 npm registry로 부터 다운받아져 node_modules 디렉터리에 저장됩니다.
$ npm i
또는
$ npm install
$ yarn
또는
$ yarn install
참고로, 설치가 끝나고 node_modules 디렉터리 내부에 들어가보면, react와 react-dom 패키지 외에도 생소한 패키지들을 볼 수 있으실 것입니다.
이러한 패키지들은 해당 프로젝트가 직접적으로 필요하지는 않지만, react와 react-dom 패키지가 필요로하기 때문에 간접적으로 의존하게 된 패키지입니다.
이렇게 package.json 파일만 있으면 해당 프로젝트가 의존하고 있는 모든 패키지를 설치할 수 있기 때문에, node_modules 디렉터리는 Git 저장소에 올라가지 않도록 보통 .gitignore 파일에 추가합니다.
그렇다면 package.json 파일만 있으면 프로젝트의 모든 개발자가 패키지 매니저를 이용해서 항상 동일한 버전의 패키지를 설치할 수 있을까요?
안타깝게도 모든 개발자가 정확히 같은 시각 동시에 패키지를 설치하지 않는 이상 개발자들은 서로 상이한 버전의 패키지를 설치할 확률이 발생하게 됩니다. 가장 큰 이유는 package.json 파일에 등록된 패키지의 버전이 ^나 ~ 등을 이용해서 범위로 지정된 경우가 많기 때문인데요.
예를 들어, 위 예제와 같이 react 패키지가 "react": "^16.8.2"이라고 등록되어 있으면, SemVer 규칙에 따라 16.8.2 이상 17.0.0 미만의 범위로 버전이 지정됩니다.
맨 처음 프로젝트에 react 패키지를 설치한 개발자 A가 특정 버전을 지정하지 않았다고 가정하면, 당시 react 패키지의 최신 버전은 16.8.2 였을 것입니다. 만약에 추후 개발자 B가 npm i나 yarn 명령어를 통해 모든 패키지를 설치할 당시 react 패키지의 최신 버전이 16.8.3이였다면 개발자 B의 PC에는 16.8.3이 설치되어 있을 것입니다. 마찬가지로 프로젝트에 몇달 후에 합류한 개발자 C가 react 패키지의 최신 버전이 16.9.1일 때 같은 방법으로 모든 패키지를 설치했다면, 개발자 C의 PC에는 16.9.1이 설치되었을 것입니다. 게다가 프로젝트의 CI 서버는 배포할 때마다 매번 모든 패키지를 설치한다고 가정하면, 애플리케이션이 배포되는 서버에는 항상 그 당시 최신 버전의 react 패키지가 설치되어 사용될 것입니다.
이렇게 서로 다른 버전의 패키지를 설치해서 사용하는 개발자 간에 큰 혼선이 발생할 수 있습니다. (ex. 개발자 A의 PC에서 성공하는 테스트가, 개발자 B의 PC에서는 실패, 개발자 C의 PC에서만 특정 버그 발생) 또한, 실제 서버에 배포된 애플리케이션이 개발자 컴퓨터에서 돌아가는 애플리케이션과 100% 동일하게 작동한다는 보장이 없어지게 되어 디버깅시 매우 난감한 상황에 빠질 수 있습니다. 이러한 상황은 패키지 매니저에서 패키지 잠금이 지원되지 않던 시절에 매우 골칫거리였던 문제이며, yarn에서 패키지 잠금을 지원하고, 추후 npm에서도 패키지 잠금을 지원하게 된 이유이기도 합니다.
패키지 잠금
이렇게 동일한 package.json 파일을 사용해도 시간과 장소에 따라서 서로 다른 버전의 패키지가 설치되는 문제는 패키지 잠금을 통해 해결할 수 있습니다.
yarn이나 비교적 최근에 릴리즈된 npm을 사용해서 프로젝트에 새로운 패키지를 설치하면 package.json 파일에 해당 패키지가 등록될 뿐만 아니라 패키지 잠금 파일이 생성되는 것을 보실 수 있으실 겁니다. package-lock.json이나 yarn.lock과 같은 패키지 잠금 파일에는 프로젝트에 패키지에 최초로 추가될 당시에 정확히 어떤 버전이 설치가 되었는지를 기록됩니다.
예를 들어, 예제 프로젝트에서 npm i 를 실행하면 프로젝트 최상위 디렉터리에 다음과 같이 package-lock.json 파일이 생깁니다.
{
"name": "my-project",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"react": {
"version": "16.11.0",
"resolved": "https://registry.npmjs.org/react/-/react-16.11.0.tgz",
"integrity": "sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
}
},
"loose-envify": { ... 생략 ... },
"object-assign": { ... 생략 ... },
"prop-types": { ... 생략 ... }
}
}
자, 이제 제가 이 package-lock.json 파일을 프로젝트의 Git 저장소에 올려두면, 다른 개발자들은 package.json 파일 뿐만 아니라 package-lock.json 파일까지 내려받게 될 것입니다.
그러면 앞으로 프로젝트의 모든 개발자의 PC뿐만 아니라 애플리케이션이 배포되는 서버까지도, npm registry에 배포된 최신 버전을 무시하고 package-lock.json에 기록된 버전 기준으로 패키지가 설치될 것입니다. 🤗
주의 사항
여러 개발자가 함께 작업하는 프로젝트에서 패키지 잠금 관련해서 불상사가 일어나지 않도록 각별히 주의해야합니다.
우선, 프로젝트를 최초 셋업하는 개발자는 패키지 잠금 파일을 Git 저장소에 반드시 올려서 다른 개발자들이 패키지 잠금 파일을 기준으로 패키지를 설치할 수 있도록 해야합니다.
그리고 패키지 잠금 파일은 패키지 매니저가 신규 패키지를 설치하거나 기존 패키지를 갱신/제거할 때마다 package.json과 자동으로 동기를 맞춰주기 때문에 개발자가 이 파일을 직접 수정해야 할 필요는 없으며 해서도 안 됩니다.
마지막으로 신규 패키지를 설치하거나 기존 패키지를 갱신/제거한 개발자는 package.json과 더불어 함께 업데이트된 패키지 잠금 파일을 반드시 커밋해야 합니다.
그렇게 하지 않으면 다른 개발자들이 npm i나 yarn를 실행했을 때, package.json는 그대로인데 package-lock.json만 업데이트되는 황당한 경우를 겪게 됩니다.
https://www.daleseo.com/js-package-locks/
이 글은 위의 블로그를 온전히 참고한 글입니다.
'💎 React' 카테고리의 다른 글
리액트 lottie (0) | 2022.05.09 |
---|---|
SVG 반응형으로 만들기 (0) | 2022.05.09 |
useStyle makeStyle keyframes에다가 props 로 넘겨주는 법 (0) | 2022.04.18 |
react lazy (0) | 2022.03.31 |
아폴로 클라이언트 (0) | 2022.03.25 |