package.json 톺아보기

2cham_ny·2024년 3월 20일
0

TIL

목록 보기
7/9

01 - WHAT

프로젝트를 한 번이라도 진행해봤다면, package.json이라는 파일을 한 번쯤은 보았을 것이다. package.json는 한마디로 그 프로젝트의 모든 정보를 담은 설정 파일이라고 할 수 있다. 프로젝트에 대한 설명, 종속성 패키지, 실행 스크립트 등의 정보들을 알 수 있는 Manifest 파일이다.

매번 프로젝트를 진행할 때마다 package.json에 대해서는 한번도 꼼꼼하게 뜯어본 적이 없어 오늘은 package.json에 대해 톺아보려고 한다.

우선, 나는 거의 모든 프로젝트에서 yarn을 사용하고 있기에 yarn 기준으로 package.json을 정리해보고자 한다. 아래는 yarn에서 설명하는 package.json 공식 문서이다. 본격적으로 공식 문서를 참고해 정리해보자.

Yarn

📌 package.json 필드 톺아보기

현재 진행 중인 프로젝트 파일 속 package.json과 함께 예시를 들어가며 정리해보자.

{
  "name": "chillin-fe",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "cz": "./node_modules/cz-customizable/standalone.js"
  },
  "dependencies": {
    "@emotion/react": "11.11.3",
    "@emotion/styled": "11.11.0",
    "@headlessui/react": "1.7.18",
    "@material-ui/core": "4.12.4",
    "@mui/icons-material": "5.15.7",
    "@mui/lab": "5.0.0-alpha.165",
    "@mui/material": "5.15.9",
    "@tanstack/react-query": "5.18.0",
    "axios": "^1.6.7",
    "clsx": "2.1.0",
    "date-fns": "3.3.1",
    "next": "14.1.0",
    "react": "^18.2.0",
    "react-dom": "^18",
    "react-hot-toast": "^2.4.1",
    "react-query": "3.39.3",
    "react-slick": "^0.30.1",
    "react-spinners": "0.13.8",
    "recoil": "^0.7.7",
    "slick-carousel": "^1.8.1",
    "tailwind-merge": "2.2.1"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "@types/react-slick": "^0.23.13",
    "@typescript-eslint/eslint-plugin": "^7.2.0",
    "@typescript-eslint/parser": "^7.2.0",
    "autoprefixer": "^10.0.1",
    "commitizen": "^4.3.0",
    "cz-customizable": "^7.0.0",
    "eslint": "^8",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-airbnb-typescript": "^18.0.0",
    "eslint-config-next": "14.1.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.3",
    "postcss": "^8",
    "prettier": "^3.2.5",
    "tailwindcss": "^3.3.0",
    "typescript": "^5"
  },
  "config": {
    "cz-customizable": {
      "config": "cz-config.js"
    }
  }
}

우선 package.json에 필수적으로 필요한 필드는 nameversion이다. 이 두 필드가 하나라도 없으면 패키지가 설치될 수 없고 배포 또한 불가능하다.

[Essentials]

{
	"name": "chillin-fe",
  	"version": "0.1.0",
}

위 코드처럼, 패키지의 이름과 버전을 볼 수 있다.

  • name
    • 패키지 및 프로젝트의 이름
    • URL, command line의 argument, node_modules 내부 디렉토리 이름으로 사용됨
    • @로 시작하여 스코프를 지정할 수도 있음
  • version
    • 패키지의 현재 버전
    • 버전명은 보통 Semantic versioning 규칙을 따라 정해진다.

관련 아티클을 한번 읽어보자.

Software 버전 관리 규칙, 너만 모르는 Semantic versioning

❓Semantic Versioning이란? (semver rule)

우선 이렇게 생겼다. 아마 다들 한 번쯤은 봤을 것이다. iOS 업데이트 시 안 봤을 리가 없다.

Major.Minor.Patch → 오픈소스의 버전 구분

  • 버전 번호는 Major, Minor, Patch의 형태로 배포
  • 각각은 자연수
  • 절대 앞에 0이 붙지 않음
  • 특정 버전으로 패키지를 배포하고 나면, 그 버전의 내용은 절대 변경하지 말아야 함. 만약 변경된 부분이 있다면 반드시 새로운 버전으로 배포해야 함
  • Major가 변경되면, Minor과 Patch는 0으로 초기화됨
  • Minor가 변경되면, Patch는 0으로 초기화됨
  • Major은 호환되지 않는 변화가 생기며 거의 다 바뀌는 것이라면, Minor는 기능 추가 및 약간의 변경, 그리고 Patch는 버그 수정으로 정리할 수 있을 것 같다.

[Info]

  • description
    • description은 그저 사람들이 이 패키지의 목적을 이해할 수 있게 해주는 문자열
  • keywords
    • 패키지 매니저에서 패키지를 검색할 때 유용한 string array
  • license
    • 모든 패키지는 사용자가 사용이 허용되는 방법과 제한 사항을 알 수 있도록 라이선스 지정 필요
    • 특별한 이유가 없는 한 오픈 소스 라이선스를 사용하는 것이 좋음 (OSI 승인)

[Links]

  • homepage
    • 패키지의 방문 페이지 또는 문서에 대한 URL
  • bugs
    • 프로젝트 이슈 트래커의 URL
    • 사용자에게 패키지 문제를 보낼 곳 및 창구 제공
    • 예를 들어 이메일 주소
  • repository
    • 패키지의 실제 코드가 있는 위치

[Maintainers]

  • author
    • 패키지 작성자 정보
    • author는 한 사람
  • contributors
    • 이 패키지에 기여한 사람들 리스트

[Files]

  • files
    • 프로젝트에 포함되는 파일
  • main
    • 프로젝트 기능의 기본 진입점
  • bin
    • 설치될 프로젝트에 포함되는 실행파일
  • man
    • 프로젝트와 관련된 매뉴얼 문서 리스트
  • directories
    • 패키지를 설치할 때 바이너리 파일, 매뉴얼 페이지, 문서, 예제 등을 넣을 정확한 위치 지정 가능

[Tasks]

  • scripts
     "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
        "lint": "next lint",
        "cz": "./node_modules/cz-customizable/standalone.js"
      },
    • 우리가 항상 쓰는 빌드 프로세스 및 개발 툴 등 패키지와 관련된 작업을 자동화하는 아~~주 중요한 역할 수행!
    • 다양한 스크립트 정의 가능
      • ex. yarn dev
      • ex. yarn build
  • config
    • 스크립트에 사용되는 구성 옵션 혹은 매개변수

      	...
      	"config": {
          	"cz-customizable": {
            	"config": "cz-config.js"
          	}	
        	}
        ...
    • 현재 우리 프로젝트에서는 cs-customizable 옵션을 사용하고 있기 때문에 config에 적혀있는 걸 볼 수 있다.

[Dependencies]

아무래도 package.json에서 가장 익숙한 옵션이 바로 Dependencies가 아닐까 싶다.

  • dependencies
    • 패키지의 개발 및 프로덕션 모든 곳에 필요한 종속성을 말한다.

      "dependencies": {
          "@emotion/react": "11.11.3",
          "@emotion/styled": "11.11.0",
          "@headlessui/react": "1.7.18",
          "@material-ui/core": "4.12.4",
          "@mui/icons-material": "5.15.7",
          "@mui/lab": "5.0.0-alpha.165",
          "@mui/material": "5.15.9",
          "@tanstack/react-query": "5.18.0",
          "axios": "^1.6.7",
          "clsx": "2.1.0",
          "date-fns": "3.3.1",
          "next": "14.1.0",
          "react": "^18.2.0",
          "react-dom": "^18",
          "react-hot-toast": "^2.4.1",
          "react-query": "3.39.3",
          "react-slick": "^0.30.1",
          "react-spinners": "0.13.8",
          "recoil": "^0.7.7",
          "slick-carousel": "^1.8.1",
          "tailwind-merge": "2.2.1"
        },

      항상 버전 앞에 붙는 ‘^’표시가 궁금했었는데 드디어 알았다!

      우선 이 ‘^’표시는 캐럿이라고 하며, 아래 사항과 같이 정리할 수 있다.

    • ^1.0.2 : ≥1.0.2 <2.0

    • ^1.0 : ≥1.0.0 <2.0

    • ^1 : ≥1.0.0 <2.0

  • devDependencies
    • 이 친구는 패키지를 개발할 때만 필요하고 배포 및 프로덕션에는 설치되지 않는 패키지를 말한다.

       "devDependencies": {
          "@types/node": "^20",
          "@types/react": "^18",
          "@types/react-dom": "^18",
          "@types/react-slick": "^0.23.13",
          "@typescript-eslint/eslint-plugin": "^7.2.0",
          "@typescript-eslint/parser": "^7.2.0",
          "autoprefixer": "^10.0.1",
          "commitizen": "^4.3.0",
          "cz-customizable": "^7.0.0",
          "eslint": "^8",
          "eslint-config-airbnb": "^19.0.4",
          "eslint-config-airbnb-typescript": "^18.0.0",
          "eslint-config-next": "14.1.0",
          "eslint-config-prettier": "^9.1.0",
          "eslint-plugin-prettier": "^5.1.3",
          "postcss": "^8",
          "prettier": "^3.2.5",
          "tailwindcss": "^3.3.0",
          "typescript": "^5"
        },

여기서 잠깐!

📌 dependencies vs devDependencies 차이를 알고가자.

dependencies에는 주로 애플리케이션 동작과 직접적으로 연관된 라이브러리를 설치하고, devDependencies에는 개발할 때 필요한 라이브러리를 설치한다고 한다.

우선 설치 커맨드는 다음과 같다.

  • dependencies → yarn add something
  • devDependencies → yarn add something --save-dev or yarn add -D something

애플리케이션에 필요한 라이브러리가 아닌데도 dependencies에 넣게 되면 빌드 시간이 낭비된다. 따라서 devDependencies에 넣어 실제 배포할 때 포함시키지 않도록 하여 빌드 시간을 줄일 수 있으니 항상 이 부분을 유의하면 좋을 것 같다.

  • devDependencies에 넣으면 좋을 것들
    • 코드 포맷터 및 린트 툴
      • ex. eslint 및 prettier과 같은 라이브러리
    • @types가 붙은 타입 정의 라이브러리
      • ex. @types/react, @types/node 등
    • 테스트 프레임워크 및 라이브러리
      • ex. Jest, Mocha, Jasmine
    • 빌드 툴 및 태스크 러너와 같이 번들링하기 위한 도구들
      • ex. Webpack, Babel, Gulp, Grunt 등
    • 프로파일링 및 디버깅 툴
      • ex. Redux DevTools Extension, React Developer Tools
    • 테스트 더블 및 목 객체 라이브러리
      • 테스트에서 의존성을 가상으로 대체하는 툴들
      • ex. Sinon.js, Jest Mock(가상)
    • 문서화 툴
      • ex. JSDoc, Storybook 등
    • 개발 환경 설정 도구
      • ex. dotenv, Husky 등

이런 부분도 신경써야 빌드 시간을 효율적으로 사용할 수 있다! 와~

  • peerDependencies
    • 해당 라이브러리에서 직접적으로 의존하지는 않지만, 해당 라이브러리가 사용자 측에서 제대로 작동하려면 사용자가 다른 라이브러리를 설치해주어야 하는 경우 사용
      • ex. plug-in or add-on과 같은 라이브러리
    • 패키지와 다른 패키지 버전의 호환성 명시 가능
  • peerDependenciesMeta
    • peerDependenceis에 메타 데이터 추가
    • 현재 optional 속성만 사용 가능
  • optionalDependencies
    • 필수는 아님
  • bundledDependencies
    • 패키지를 게시할 때 함께 번들로 묶일 패키지의 이름의 배열
  • flat
    • 중복된 패키지를 설치하지 않도록 해주는 속성
    • 서브 디렉토리에서 중복 모듈을 설치하지 않고 최상위 node_modules과 같은 디렉토리에 패키지를 설치하는 데에 도움이 됨
    • 특정 종속성의 한 버전만 허용
  • resolutions
    • 특정 중첩 종속성의 버전 재정의 가능

[System]

  • engines
    • 패키지와 함께 사용해야 하는 클라이언트 버전 지정
    • process.version과 yarn의 현재 버전 체킹
    • semver 규칙 적용
  • os
    • 패키지의 운영 체제 호환성 지정
  • cpu
    • 패키지가 특정 CPU 아키텍처에서만 실행되도록 지정하기 위해 사용 가능

[Publishing]

  • private
    "private" : true
    • true로 설정 시 패키지 배포가 되지 않음
  • publishConfig
    • 패키지를 게시(배포)할 때 사용
    • 패키지 배포 시 몇 가지 설정들 오버라이드 가능

02 - HOW

  • 문제 상황 : 진행 중인 프로젝트 코드 리뷰 후 dependencies와 devDepencies에 대해 짚고 넘어가면 좋을 것 같았다. 그리고 빌드 시간이 빠르진 않았다는 문제가 있었다.
  • 개선 방법 : dependencies와 devDependencies에 대해 먼저 정리를 했었는데, 이참에 package.json을 한번 뜯어보면 좋을 것 같아 이렇게 처음으로 공식 문서와 함께 정리해보았다. 개발을 배운지 1년이 좀 넘었는데, 이제야 세부적으로 뜯어봤다는 점이 아쉬우면서도 반성하게 되는 시간이었던 것 같다.

03 - RETROSPECT

이렇게 package.json에 어떤 속성들이 있는지 알아보았다. 공식 문서에 더 자세히 나와있기에 중요한 속성들만 좀 구체적으로 작성해보았는데, 평소에 당연하게 사용했던 것들에 대한 이유를 알 수 있는 기회가 된 것 같다.

04 - 오늘의 한마디

요즘 잠이 너무 많다!!!!

너무 졸려. . .

profile
😈 기록하며 성장하자!

0개의 댓글

관련 채용 정보