Search
🎍

package.json과 package-lock.json의 차이

Created
2023/04/30
Tags
Etc.
Category
Knowledge
Parent item
Sub-item
2 more properties

 궁금증

Node.js 프로젝트를 시작할 때, 터미널에 'npm install'을 입력하면 아래 사진과 같이 여러 파일들이 기본으로 설치된다.
프로젝트 파일 목록
그런데 여기서 package.json은 무엇이고, 거기다 package-lock.json은 무엇일까?
프로젝트 시작에 앞서 일단 구조부터 알고 시작해 보자.

 package.json

# package.json 예시 { "name": "codingElla", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, ...# 생략 ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }
JSON
복사
package.json 파일은 Node.js 프로젝트에서 사용되는 파일로, 일반적으로 이 안에는 프로젝트의 이름, 버전, 설명, 작성자, 라이센스, 프로젝트 실행에 필요한 서드파티 패키지인 *의존성 목록이 포함된다.
의존성이란, 모듈과 모듈간의 관계를 나타내며 의존성을 관리하는 것은 유지보수나 확장성에 영향을 미치므로 소프트웨어 개발에서 매우 중요하다.
Node.js 프로젝트에서 터미널에 'npm install'라고 입력하면 package.json 파일에 나열된 의존성이 자동으로 설치되므로 프로젝트의 의존성을 쉽게 관리할 수 있고, 필요한 패키지의 동일한 버전을 사용하는 모든 사용자를 보장할 수 있다. (이 말은 지금은 이해가 어려울 수 있으므로 아래에서 자세하게 설명하겠다.)

 package-lock.json

# package-lock.json 예시 { "name": "codingElla", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codingElla", "version": "0.1.0", "dependencies": { "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" } }, "node_modules/@adobe/css-tools": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.2.0.tgz", "integrity": "sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==" }, ...# 생략 } }
JSON
복사
package-lock.json파일은 의존성 트리에 대한 정보를 가지고 있으며,  package-lock.json 파일이 작성된 시점의 의존성 트리가 다시 생성될 수 있다. (이 말 또한 지금은 이해하기 어려울 수 있으니 아래에 자세한 설명을 하겠다.)

 package-lock.json가 필요한 이유

package.json 파일 안에서 의존성 선언에는 'version range'가 사용된다. 이는 특정 버전을 지칭하는 것이 아니라, '특정 버전 이상'이라는 range를 말해준다. (ex. ^18.2.0 === 18.2.0 버전 이상)
이때 package.json 파일로 npm install을 입력하면 현재는 18.2.0 버전의 리액트가 설치되지만, 새로운 패치가 퍼블리시된다면 동일한 package.json 파일로 npm install을 입력해도 이전에 설치한 18.2.0 버전이 설치된다. 대부분의 경우에는 큰 문제가 없으나, 이는 간혹 협업 프로젝트 시 오류를 발생하는 경우가 있다.
# 이해를 돕기 위해 아래에 의존성 트리 예시를 첨부 # 의존성 트리는 'npm ls'로 조회 가능 codingElla@0.1.0 /Users/yeonsuchoi/Workspace/React/blog-project ├── @testing-library/jest-dom@5.16.5 ├── @testing-library/react@13.4.0 ├── @testing-library/user-event@13.5.0 ├── react-dom@18.2.0 ├── react-scripts@5.0.1 ├── react@18.2.0 └── web-vitals@2.1.4
Shell
복사
이때, package-lock.json 파일은 위와 같은 의존성 트리에 대한 정보, 즉 정확한 버전 정보를 가지고 있기 때문에 package-lock.json 파일이 작성된 시점의 의존성 트리가 다시 생성될 수 있도록 보장한다.

예를 들어,

package.json and package-lock.json @Atatus
1.
4월 1일에 18.2.0 버전을 설치했고
2.
4월 30일에 npm install을 하여 업데이트된 18.3.0 버전을 설치하고자 하더라도
3.
package-lock.json 파일 덕분에 18.2.0 버전으로 의존성 트리가 다시 업데이트 되는 것이다. (사실 이 과정은 package.json의 존재만으로도 가능하나, package-lock.json이 정확한 버전 정보를 가지고 있기 때문에 특히 협업 시 필요한 존재라고 볼 수 있다.)

때문에,

위 그림과 같이 협업을 위해서는 package.json 파일뿐만 아니라 package-lock.json 또한 함께 커밋해야 한다.

그렇지 않으면,

1.
내가 4월 1일에 내가 커밋한 소스코드를
2.
동료 개발자가 4월 30일에 pull 한 후 npm install을 실행하면
3.
나의 의존성 트리와 동료의 의존성 트리가 다르게 설치되어 프로그램 실행 시 오류가 발생할 수 있는 것이다.

정리하자면,

package-lock.json 파일 안에는 프로젝트의 의존성 트리를 포함한 각 의존성의 정확한 버전, 버전 충돌 등의 정보가 포함되기 때문에 설치 당시 의존성을 재현하고, 다른 개발자와 공유할 때 일관성을 유지하는 데에 사용된다.
따라서 package-lock.json 파일을 Github 등 버전 관리 시스템에 유지하고 삭제하지 않는 것이 좋다.

 추가 궁금증

package-lock.json 파일을 삭제하면 의존성 트리나 설치된 의존성이 삭제될까?

package-lock.json 파일을 삭제하면 의존성 트리나 설치된 의존성이 삭제되지는 않는다. 앞서 이야기한 것처럼 package-lock.json 파일은 설치된 패키지가 package.json 파일에서 지정된 정확한 버전과 일치하도록 보장하는 데 사용된다. package-lock.json 파일이 삭제되면 npm은 여전히 package.json 파일을 사용하여 필요한 의존성을 설치하지만, 정확히 같은 버전을 설치하는 것을 보장하지 않는 것이라 보면 된다.

애초에 package.json 파일에 정확한 버전명을 적어두면 되지 않을까?

package.json 파일에 정확한 패키지 버전명을 명시한다면,  프로젝트에서 사용하고 있는 패키지의 중요한 버그 수정이 이루어질 때마다 프로젝트의 package.json 파일에 적혀있는 버전도 수정을 해야 하는 번거로움이 생길 수 있다. 즉, 크고 작은 패키지들의 릴리즈에 대해 항상 추적하고 수정해야 하는 번거로움을 version range로 명시함으로써 이를 해결해 주는 것이라고 보면 된다.

 참고 자료