package.json이란?
Node.js 기반 프로젝트의 정보를 포함하고, 패키지 매니저(npm, yarn)를 통해 설치한 모듈들의 의존성을 관리하는 파일입니다.
이 파일은 JSON 형식이며, 필수 항목으로 name과 version이 있으며, 그 외에도 다양한 설정이 가능합니다.
대부분의 자료가 패키지 배포에 초점을 맞추고 있어서 최대한 웹 개발에서 유용한 package.json 활용법을 중심으로 정리해보았습니다.
“name”
- 프로젝트 이름으로, 가장 중요합니다. 중앙 저장소에 배포할 때 version과 함께 필수 항목입니다.
- url로 사용되고, 설치할 때 디렉토리 이름이 되기 때문에 url이나 디렉토리에서 쓸 수 없는 이름을 사용하면 안 됩니다.
- name은 214자보다 짧아야 하며, 점( . )이나 밑줄( _ )로 시작할 수 없습니다.
“version”
- 프로젝트의 현재 버전을 정의합니다.
- 버전은 항상 세 자리로 이루어져 있습니다. 이는 SemVer 방식의 버전 넘버링을 따르기 때문입니다.
Senver는 Semantic Versioning(유의적 버전)의 약어로 버전을 구성하는 세 자리 모두 의미를 가지고 있다는 뜻입니다.
{ "version": "2.7.4" }
- 첫 번째 자리 2는 Major 버전을 의미합니다. 0이면 초기 개발(beta) 중이라는 거을 의미하고, 1부터는 정식 버전을 의미합니다. Major의 버전에 변경된다는 것은 하위 호환이 안될 정도의 수정 또는 업데이트가 되었다는 것을 의미합니다.
- 두 번째 자리 7은 minor 버전을 의미합니다. 하위 호환이 가능한 기능 업데이트 시 minor 버전을 올립니다.
- 세 번째 자리 4는 patch 버전을 의미합니다. 기존 기능에 문제가 있어서 수정 업데이트 시 patch 버전을 올립니다.
“description”
- 프로젝트 설명으로, 문자열로 기술합니다.
- npm search로 검색된 리스트에 표시되기 때문에 사람들이 패키지를 찾아내고 이해하는 데 도움이 됩니다.
“keywords”
- 프로젝트를 검색할 때 참조되는 키워드입니다.
- description과 마찬가지로 npm search로 검색된 리스트에 표시됩니다.
{ "keywords": ["fruits", "Apple", "Persimmon", "Pomegranate", "Jujube", "Mango", "Yuja"] }
“scripts”
- npm 명령어를 저장하고 실행할 수 있습니다.
- npm run script-name으로 실행할 수 있습니다.
{ "scripts": { "start": "node server.js", "dev": "nodemon server.js", "test": "jest", "build": "tsc", "build-and-start": "next build && next start" } }
- npm start → node server.js 실행
- npm run dev → nodemon server.js 실행
- npm run build-and-start -> next 빌드 및 실행 한번에 가능
“dependencies”
- 프로젝트 의존성 관리를 위한 부분이며, npm 종속성으로 설치된 패키지 목록을 설정합니다.
- npm 또는 yarn을 사용하여 패키지를 설치하면 dependencies 목록에 자동으로 등록됩니다.
{ "dependencies": { "express": "^4.17.1", "mongoose": "^7.0.0" } }
버전 규칙
version : 명시한 버전만 설치.
>version : 명시한 버전보다 높은 버전만 허용.
>=version : 명시한 버전과 같거나 높은 버전만 허용.
<version : 명시한 버전보다 낮은 버전만 허용.
<=version : 명시한 버전과 같거나 낮은 버전 허용.
~version : 명시한 버전과 근사한 버전 허용 (패치 버전만 변경 가능).
^version : 명시한 버전과 호환되는 버전 허용 (마이너 버전까지 변경 가능).
1.2.x : x 자리에 아무 숫자나 올 수 있음
* : 모든 버전 허용
" " : * 과 동일
version1 - 지정된 범위 내 버전만 허용
range1 || range2 : range1 또는 range2 범위 내 허용
path/path/path : 로컬 경로에서 패키지를 설치
“devDependencies”
- 개발 환경에서만 필요한 패키지 목록입니다
- npm install –production 실행 시 설치되지 않습니다.
{ "devDependencies": { "typescript": "^5.0.0", "jest": "^29.0.0" } }
“optionalDependencies”
- 특정 패키지가 설치되지 않아도 프로젝트 실행에는 문제가 없는 경우 사용됩니다.
- 패키지 설치가 실패해도 에러 없이 계속 진행됩니다.
{ "optionalDependencies": { "fsevents": "^2.0.0" } }
- fsevents는 macOS에서만 필요한 패키지이므로, Windows나 Linux에서는 설치되지 않아도 무방합니다.
“overrides”
- 특정 패키지의 버전을 강제로 변경할 수 있습니다.
- 프로젝트에서 사용하는 모든 하위 패키지(의존하는 패키지들)까지 해당 버전으로 강제 변경됩니다.
- 강제로 변경하면 하위 패키지에서 예상치 못한 오류가 발생할 수 있으므로, 신중하게 적용해야 합니다.
{ "overrides": { "express": "4.17.21" } }
“engines”
- 프로젝트가 실행될 Node.js 및 npm 버전을 지정할 수 있습니다.
{ "engines": { "node": ">=16.0.0", "npm": ">=8.0.0" } }
“browserslist”
- 지원할 브라우저 목록 설정 (프론트엔드 프로젝트에서 유용함)
{ "browserslist": [ "last 2 versions", "not dead", "> 0.5%" ] }
- last 2 versions = 각 브라우저의 마지막 2개 버전을 지원합니다.
- not dead = 사용자가 거의 없는 브라우저(죽은 브라우저)를 제외
- > 0.5% = 전 세계에서 시장 점유율이 0.5% 이상인 브라우저만 포함
“type”
- “module”로 설정하면 .js 파일에서도 import/export를 사용할 수 있습니다.
- “commonjs”로 설정하면 기존의 require() 방식을 사용할 수 있습니다.
- package.json에서 “type”: “module”을 설정하면, 모든 .js 파일이 ESM 방식으로 동작합니다.
{ "type": "module" }
“workspaces”
- 모노레포(Monorepo) 프로젝트를 관리할 때 사용됩니다.
- 프론트엔드 + 백엔드 + 공통 패키지 한 번에 설치 가능
- 코드 재사용 증가 (공통 UI, 공통 유틸 관리 가능)
{ "workspaces": [ "apps/*", "packages/*" ] }
“repository”
- 프로젝트의 원본 코드 저장소를 나타냅니다.
- 보통 GitHub, GitLab, Bitbucket과 같은 저장소의 URL을 등록합니다.
- npm info package-name 명령어를 실행하면 해당 정보를 확인할 수 있습니다.
{ "repository": { "type": "git", "url": "https://github.com/user/repo.git" } }
- type -> 저장소 종류
- url -> 저장소 URL
“config”
- npm 스크립트 실행 시 사용할 사용자 정의 설정 값을 저장하는 필드입니다.
- npm_package_config_설정값이름 형식으로 접근할 수 있습니다.
{
"config": {
"port": "3000"
},
"scripts": {
"start": "next start --port=$npm_package_config_port"
}
}
“bugs”
- 버그 리포트 URL을 지정할 수 있습니다.
{ "bugs": { "url": "https://github.com/user/repo/issues" } }
“코드 품질 자동 유지 (husky + lint-staged)”
- Git 커밋 전에 자동으로 eslint + prettier 실행
- 코드 스타일 강제 적용 (팀원 간 코드 일관성 유지)
- 코딩 컨벤션을 자동으로 맞추고, 코드 깨짐 방지
{ "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.ts": "eslint --fix", "*.tsx": "eslint --fix", "*.json": "prettier --write" } }
우리는 보통 package.json을 자동으로 생성된 그대로 사용하면서, 깊게 고민하지 않고 넘어가는 경우가 많습니다. 하지만 오늘 배운 내용을 통해, 단순한 설정 파일이 아니라 프로젝트를 더 체계적으로 관리하고, 협업을 원활하게 할 수 있는 중요한 도구라는 걸 알게 되었습니다. 이제부터는 package.json의 다양한 항목들을 적극적으로 활용해서, 더 효율적인 패키지 관리와 안정적인 개발 환경을 만들어 봅시다.