1. 패키지를 공유할 때, 그 안의 node_modules 디렉토리는 공유하지 않는다.
하나의 패키지는 여러 명의 개발자가 협력해서 만드는 게 일반적입니다.
그럼 이때 협력하는 개발자들끼리는 패키지를 어떻게 공유할까요?
패키지는 package.json 파일이 있는 디렉토리니까 이 디렉토리를 서로 주고받으면 되는데요. 이때 중요한 점이 하나 있습니다.
패키지를 공유할 때, 패키지 안에 있는 node_modules 디렉토리는 보통 공유하지 않는다는 점입니다.
node_modules 디렉토리가 뭐였죠? 현재 작업 중인 패키지에서 이런저런 패키지들을 설치하면 그것들이 설치되는 곳이었습니다. 그런데 이렇게 중요한 node_modules 디렉토리를 왜 공유하지 않는 걸까요? 왜냐하면 보통 패키지를 몇 개 정도만 설치해도 node_modules 디렉토리 내부의 용량은 매우 커지게 되고, 이것들을 매번 공유하는 것은 비효율적(용량 문제)이기 때문입니다.
하지만 그렇다고 해서 현재 패키지가 의존하는 다른 패키지들이 없으면, 현재 패키지가 정상적으로 실행될 수 없을텐데 대책이 있는 걸까요? 바로 이때 package.json 파일이 필요합니다.
패키지를 공유할 때는 그 안의 package.json 파일만 제대로 공유하면 됩니다.
그리고 공유받은 측은, 해당 패키지 안에서 npm install 이라고 쓰고 실행하면, npm이 package.json 파일의 dependencies 필드에 적힌
- 의존 패키지들의 이름과
- Semantic Version / Version Range Syntax를 보고
알맞은 패키지들을 자동으로 설치해줍니다.
이전에 우리가 배운 것처럼 package.json 파일에는
현재 패키지가 의존하는 패키지들(dependencies)들의 정보가 이렇게 잘 나와있기 때문에 npm이 이 정보를 기반으로 필요한 패키지들을 설치할 수 있는 겁니다. 한마디로 정리하면, 패키지를 공유할 때 무거운 용량의 node_modules 디렉토리는 굳이 직접 공유하지 않고, 패키지를 공유받는 사람이 npm install 명령어를 실행해서 공유받은 package.json 파일을 기반으로 직접 생성하는 것입니다.
2. package.json 파일과 package-lock.json 파일
방금 package.json 파일을 기반으로 한 패키지 공유 방식에 대해 설명했습니다. 그런데 가끔 이 방식이 문제가 될 때가 있습니다. 그건 바로 개발자 A가 갖고 있던 패키지를 받아서 개발자 B가 npm install 명령어로 그 안의 node_modules 디렉토리를 재현해도, 그 내부의 패키지들이 동일하지 않을 때가 있기 때문입니다. 이런 일이 발생하는 가장 주된 원인은 우리가 배운 Version Range Syntax 때문입니다. package.json 파일의 dependencies 필드를 보면 버전 부분에 3.5.2 이런 식으로 딱 Semantic Version만 적혀있는 부분도 있지만 우리가 배운 Tilde Range(~3.5.2), Caret Range(^3.5.2) 같은 Version Range Syntax가 적혀있는 경우도 많습니다. 그리고 이런 경우에는 해당 패키지의 특정 버전 뿐만 아니라 일정한 버전 범위 내에 있는 패키지면 설치가 가능하기 때문에 문제가 되는 겁니다.
예를 들어,
- 개발자 A가 sample이라는 패키지에 관한 작업을 할 때,
- 그것이 의존하는 helper라는 패키지의 Version Range가 ^3.5.2였다고 생각해봅시다.
그럼 3.5.2≥ <4.0.0 버전 안의 패키지들은 모두 설치가 가능하겠죠?
A가 sample 패키지를 만들 때는 helper 패키지의 최신 버전이 3.5.4였다고 해봅시다. 그리고 시간이 지나 helper 패키지의 3.6.0 버전이 나왔다고 생각해보세요. 이 시점에 만약 개발자 B가 이 패키지를 공유받는다면 어떻게 될까요? 위에서 말한 대로 node_modules 디렉토리는 공유하지 않고 package.json 파일만 공유하기 때문에, 이제 개발자 B의 경우에는 npm install을 실행했을 때 3.6.0 버전의 helper 패키지가 설치될 겁니다. 분명, 둘 다 sample 패키지를 갖고 작업을 하고 있는데
- 개발자 A는 3.5.4 버전의 helper 패키지,
- 개발자 B는 3.6.0 버전의 helper 패키지
를 갖고 작업하게 되는 겁니다.
일반적인 경우에는 이러한 것들이 별 문제가 없을 수도 있습니다. 하지만
- sample 패키지를 공동 개발하는 중이라 모든 개발자가 똑같은 환경을 보장받아야하는 경우
- helper 패키지의 새 버전에 버그 등은 없는지 점검한 후에 써야하는 경우
등에는 공유하는 측과 공유받는 측에서 이렇게 dependency의 차이가 발생해서는 안 됩니다.
그럼 이 문제를 어떻게 해결할 수 있을까요? 그렇다고 node_modules 디렉토리를 통째로 공유하는 건 용량 때문에 너무 비효율적인데 말이죠.
정답은 바로 package-lock.json 파일에 있습니다. package-lock.json 파일에 대해서는 배운 적이 있는데요.
잠깐 저의 nodeStudy 패키지 내부를 보겠습니다.
지금 보면 package-lock.json 파일과 pakcage.json 파일이 보이는데요. 각각 어느 시점에 생긴 파일들인지 기억나시나요?
- package-lock.json 파일은 맨 처음 패키지를 설치했을 때(당시에는 패키지를 배우기 전이라 '서드파티 모듈'이라고 불렀었죠?) 생겼던 파일이고(참조)
- package.json 파일은 제가 npm init 명령어를 사용해서 nodeStudy 디렉토리를 하나의 패키지로 만들었을 때 생긴 파일인데요.(참조)
package-lock.json 파일에는 dependencies 필드에, 현재 패키지 안에 어떤 패키지들이 설치되어 있는지 그 정보가 담겨있다고 배웠습니다. package.json 파일도 마찬가지로 dependencies 필드가 있고, 여기에는 어떤 패키지들이 설치되어야 하는지에 대한 정보가 있다고 했습니다.
혹시 방금 위의 설명에서 둘 간의 미묘한 차이를 눈치채셨나요?
package-lock.json에는 현재 패키지 안에 '실제로 설치된' 패키지들의 정확한 버전들이 기록되어 있습니다.
위 이미지에 나온 package-lock.json 파일의 dependencies 필드를 보면, '실제로 설치된' 패키지들의 이름과 '정확한' 버전들을 볼 수 있습니다.
반면에 packag.json 파일의 내용을 보면
dependencies 필드에 보이는 패키지의 이름 옆에는 Version Range Syntax가 존재하는 경우도 있다는 것을 알 수 있습니다. 즉, 이 dependencies 필드가 의미하는 것은 특정 패키지의 특정 버전이 아니라(특정 버전이 적혀있는 경우도 물론 있습니다) Version Range Syntax를 만족하는 버전의 패키지라면 언제든지 업데이트된 버전의 패키지가 설치되어도 괜찮다는 뜻입니다.
그러니까
- package.json 파일의 dependencies 필드에는 '현재 패키지가 동작하기 위해 필요한 다른 패키지들의 버전 범위'가 적혀있는 것이고,
- package-lock.json 파일의 dependencies 필드에는 '현재 패키지에 실제로 설치되어 있는 다른 패키지들의 버전'이 적혀있는 것입니다.
그리고 바로 이 package-lock.json 파일이 아까 말한 'package.json 기반의 패키지 공유 방식'이 발생시킬 수 있는 문제에 대한 해결책입니다. 패키지를 공유할 때, 이 package-lock.json 파일도 package.json 파일과 함께 공유하면 npm install 을 실행했을 때 npm은 package-lock.json 파일의 dependencies를 보고, 특정 버전의 패키지들을 정확히 동일하게 설치합니다. 그럼 어느 상황에서든 해당 패키지를 공유받는 사람이나 공유해준 사람은 동일한 버전의 dependency들을 설치하게 됩니다. 즉, 동일한 node_modules 디렉토리를 갖게 되는 것입니다.
그러니까 만약 패키지를 공유할 때 정확히 똑같은 패키지를 상대방도 가져야 할 때는 반드시 이 package-lock.json 파일도 package.json과 함께 공유해줘야 합니다. 그 정도까지는 아니고 공유받는 측에서 패키지가 동작만 잘 해도 되는 경우라면 package.json 파일만 공유해줘도 되고요.
[정리]
패키지를 공유할 때는 보통 그 안의 node_modules 디렉토리를 제외하고 공유합니다.
이때 패키지 안의 package.json 파일 내용 중 dependencies 필드의 정보가 공유받는 측에서 node_modules 디렉토리를 재생성(npm install)하는 데 사용되며
이때 공유해준 사람과 공유받은 사람 간에 node_modules 디렉토리 내부의 차이가 발생하지 않도록 방지하려면 package-lock.json 파일도 package.json 파일과 함께 공유해줘야 합니다.
'Archive' 카테고리의 다른 글
export / export default (0) | 2021.10.02 |
---|---|
--save-dev ? (0) | 2021.09.25 |
[JS] Error (Try catch & throw) (0) | 2021.09.22 |
[JS] 삼항연산 / spread / Optional Chaining / Destructuring (0) | 2021.09.22 |
[JS] querySelector (0) | 2021.09.18 |