패키지 설치와 버전 관리


컴포저의 패키지 설치와 갱신 과정은 프로젝트 루트(Root) 경로에 작성되는 설정 기술서인 composer.json 파일을 중심으로 실행됩니다.

이 장에서는 컴포저 초기화 방법, 다양한 패키지 설치 커맨드의 쓰임새와 의미 차이, 시맨틱 버저닝(SemVer) 기반의 버전 제약 지정 기법, 그리고 프로젝트의 일관성을 사수해 주는 핵심 파일인 composer.lock에 관해 학습합니다.


1. 컴포저 초기화 (composer.json 생성)


새로운 프로젝트에서 컴포저를 도입하려면 가장 먼저 설정 파일인 composer.json을 만들어야 합니다. 이 파일을 생성하는 방법은 크게 두 가지가 있습니다.

1.1 composer init 명령어로 대화식 생성

터미널에서 초기화 명령을 실행하면 몇 가지 질의 단계를 거쳐 자동으로 문법에 부합하는 파일 형식을 구축해 줍니다.

$ composer init

이후 프롬프트 창에 프로젝트명, 저자, 설명, 라이선스 등을 기입하고, 외부 라이브러리 의존성을 인터랙티브하게 정의할지 묻는 항목(Would you like to define...)에는 no를 입력하고 종료하면 기본 뼈대 파일이 생성됩니다.

1.2 텍스트 에디터로 직접 작성

단순한 형태의 패키지 연동 프로젝트라면, 터미널 명령을 건너뛰고 텍스트 에디터를 열어 수동으로 작성해도 무방합니다.

{
    "name": "myproject/app",
    "require": {}
}


2. 패키지 설치 명령어


컴포저에서 패키지를 설치하는 방법은 목적에 따라 명령어의 성격이 뚜렷이 갈립니다.

2.1 composer require (신규 패키지 추가)

새로운 라이브러리를 검색하여 프로젝트에 연동하고 싶을 때 사용합니다.

$ composer require illuminate/support
  • 작업 흐름: Packagist에서 해당 패키지를 탐색 ➡️ 필요한 파일을 내려받아 vendor/ 폴더에 복사 ➡️ composer.json"require" 블록에 패키지 이름과 호환 버전 자동 갱신 ➡️ 의존성 정보가 보존된 composer.lock 생성 및 갱신.

2.2 composer install (동기화 및 환경 재현)

협업 개발 환경이나 실서비스 배포 시, 기존에 정의된 패키지 목록을 그대로 로컬 컴퓨터에 복원 설치할 때 사용합니다.

$ composer install
  • 작업 흐름: 프로젝트 루트 내에 composer.lock 파일이 존재하는 경우, composer.json을 보지 않고 composer.lock에 기록된 락(Lock) 버전과 정확히 일치하는 패키지를 vendor/에 설치합니다. 만약 lock 파일이 없다면 composer.json 파일의 의존성 정보에 따라 최초 설치 후 composer.lock을 기록합니다.
  • 배포 권장: 웹 서비스 등을 운영 서버에 배포할 때는 반드시 개발 단계에서 검증된 패키지 조합 그대로 동기화되도록 composer install을 작동시켜야 버전 불일치로 인한 오작동을 피할 수 있습니다.

2.3 composer require --dev (개발 전용 패키지 추가)

유닛 테스트 도구(PHPUnit), 코드 포맷터, 정적 분석 도구 등은 실서비스 운영 환경에는 적재될 필요가 없고 오로지 개발 과정에서만 사용됩니다. 이러한 개발 목적 패키지는 --dev 옵션을 붙여 구분 설치합니다.

$ composer require --dev phpunit/phpunit

설치를 완료하면 composer.json 내부에 별도의 "require-dev" 영역이 구성되고 패키지가 할당됩니다.

[!WARNING] 잘못된 오해와 오류: 일부 블로그 등에서 composer require-dev 패키지명 형태로 소개하는 것은 문법적 에러를 유발합니다. 컴포저 내에 require-dev라는 이름의 단독 커맨드는 존재하지 않으며, 반드시 composer require 커맨드 뒤에 옵션 인자인 --dev를 기재해야 함을 기억해 주십시오.


2.4 운영 배포 시 개발용 패키지 제외 (--no-dev)

운영 서버에 배포할 때는 소스 코드 경량화와 보안성을 높이기 위해 개발 패키지를 배포 영역에서 완전 배제해야 합니다. 아래 옵션으로 설치 작업을 수행합니다.

$ composer install --no-dev


3. 시맨틱 버저닝(SemVer)과 버전 제약 연산자


컴포저는 패키지 업그레이드 시 안정성을 해치지 않도록 시맨틱 버저닝(Semantic Versioning, SemVer) 표준 명세를 준수합니다. 버전은 크게 Major.Minor.Patch 형식으로 구성됩니다.

  • Major: 하위 호환성이 깨지는 커다란 API 명세 변경 시 증가합니다. (예: 1.0.0 ➡️ 2.0.0)
  • Minor: 하위 호환성을 완벽히 보장하면서 신규 기능이 추가될 때 증가합니다. (예: 1.2.0 ➡️ 1.3.0)
  • Patch: 하위 호환성을 보장하면서 발견된 내부 버그나 보안 취약점을 수정할 때 증가합니다. (예: 1.2.1 ➡️ 1.2.2)

이를 바탕으로 composer.json 내 패키지 버전 조건에 다양한 기호를 사용하여 업데이트 가용 한계를 제약할 수 있습니다.

3.1 ^ (Caret) 연산자 (기본 설정값)

하위 호환성이 깨지지 않는 안전 범위(Major 버전 변경이 없는 범위) 내에서 최신 업데이트를 허용합니다.

  • ^1.2.3>=1.2.3 <2.0.0을 의미합니다. (Minor, Patch는 유연하게 승급)
  • 예외: 메이저 버전이 0인 패키지(예: ^0.3.0)는 0.x 단위의 마이너 증가도 깨지는 변경(breaking change)으로 인식하므로 >=0.3.0 <0.4.0으로 제약이 엄격해집니다.

3.2 ~ (Tilde) 연산자

지정한 버전 필드 기준 한 단계 하위 필드(가장 우측에 적힌 필드) 내에서의 상승만을 허용합니다.

  • ~1.2.3>=1.2.3 <1.3.0을 타깃으로 삼습니다. (Patch 레벨 변경만 업데이트 가능)
  • ~1.2>=1.2.0 <2.0.0을 타깃으로 삼습니다. (Minor 및 Patch 레벨까지 업데이트 가능)

3.3 * (Wildcard) 연산자

와일드카드 기호가 배치된 버전 위치의 모든 변경 수용을 허용합니다.

  • 1.2.*>=1.2.0 <1.3.0을 의미합니다. (Patch 버전은 최신을 자동으로 찾아 적용)
  • 1.*>=1.0.0 <2.0.0을 의미합니다.

3.4 기타 연산자

  • 고정 버전 (1.2.3): 정확히 1.2.3 특정 버전만 강제로 연동합니다.
  • 비교 조건 (>=2.0 <3.1): 부등호를 나열하여 명시적으로 버전 수치 한계를 수학적으로 제한합니다.


4. 패키지 갱신 (update)과 삭제 (remove)


4.1 패키지 버전 업그레이드

composer.json의 조건 한계 안에서 외부 라이브러리들을 일괄 점검하여 업그레이드하고 싶을 때는 update 명령어를 실행합니다.

$ composer update
  • 이 작업이 실행되면 컴포저는 최신 패키지를 가져온 뒤 변경 사항을 바탕으로 composer.lock 파일에 명시된 버전을 새 스펙으로 수정 갱신합니다.

4.2 패키지 안전 제거

더 이상 쓰지 않는 패키지를 완전 소거할 때 씁니다.

$ composer remove jiny/hello
  • 이 명령은 vendor/ 내 해당 소스 폴더를 지우고 composer.jsoncomposer.lock에서 해당 의존 설정을 깨끗하게 삭제하고 오토로드 맵까지 즉각 자동 정리해 줍니다.


5. 의존성 격리의 핵심: composer.lock 파일의 중요성


많은 초보 개발자들이 composer.json만 있으면 된다고 생각해 composer.lock 파일을 버전 관리 시스템(Git)에서 배제하는 중대한 실수를 하곤 합니다.

  • composer.json: 우리가 “허용할 버전 조건”을 선언해 둔 파일입니다. (예: ^1.2.0)
  • composer.lock: 실제로 해당 프로젝트 디렉터리에 “설치된 패키지들의 한 치의 오차도 없는 정확한 버전 정보(예: 1.2.8)”를 저장해 고정(Lock)해 놓는 파일입니다.

만일 composer.lock 파일을 배포 공유하지 않으면, 개발자 A와 B가 서로 다른 타이밍에 소스를 다운로드받아 빌드할 때 v1.2.0 범위 안에서 미묘하게 빌드된 마이너 버전의 차이(A는 v1.2.1, B는 v1.2.8)가 발생할 수 있습니다. 이는 실서버 배포 시 예기치 못한 크리티컬한 기능 에러를 초래합니다.

따라서 composer.lock 파일은 항상 소스 코드(src/)와 함께 깃허브에 커밋(Commit)하여 공동 작업 및 배포에 동일성을 보장해야 합니다. (단, vendor/ 폴더는 소스 용량 낭비 방지를 위해 .gitignore에 추가하여 버전 관리에서 반드시 제외해야 합니다.)

서브목차