Skip to main content
패키지가 고유한 메타데이터를 미리 생성하는 경우, 사용자에게 배포 절차에 전용 명령어를 추가해 달라고 안내하는 것만으로는 업데이트 시 실행을 빠뜨리기 쉽습니다. ServiceProvider::optimizes()를 사용하면 생성과 삭제 명령어를 Laravel의 optimize와 optimize:clear에 포함시킬 수 있습니다. 이 페이지에서는 패키지 개발의 기초를 전제로 Laravel Framework v13.35.0의 구현을 살펴봅니다. 캐시 파일의 형식이 아니라 등록과 운영에 관한 계약을 다룹니다.

명령어 등록과 태스크 등록을 구분하기

commands()는 Artisan에서 호출할 수 있는 명령어 클래스를 등록합니다. optimizes()는 이미 실행 가능한 명령어 이름을 최적화 태스크로 등록하는 별개의 처리입니다. 후자만 호출해서는 명령어 클래스가 등록되지 않습니다. 다음 예는 패키지에 CacheMetadataCommand와 ClearMetadataCommand가 이미 구현되어 있고, 각각의 $signature가 courier:cache와 courier:clear-cache라는 것을 전제로 합니다.
optimizes()의 인수는 모두 nullable이므로 생성만, 또는 삭제만 등록할 수도 있습니다. 다만 생성한 캐시를 어떤 절차로 무효화하는지는 반드시 사용자에게 안내하세요.

등록 키도 사용자에 대한 계약이 된다

ServiceProvider는 생성 명령어를 정적 배열 $optimizeCommands에, 삭제 명령어를 $optimizeClearCommands에 저장합니다. 두 배열 모두 key가 배열 키가 됩니다. key를 생략하면 프로바이더의 클래스 이름에서 이름이 생성됩니다. 예를 들어 CourierServiceProvider라면 courier가 됩니다. 클래스 이름만 사용하므로, 다른 네임스페이스에 있는 같은 이름의 프로바이더와도 충돌할 수 있습니다. 같은 키로 다시 등록하면 해당 쪽의 명령어가 나중 값으로 덮어써집니다. 여러 태스크를 등록하려면 서로 다른 키를 지정하세요. 또한 config나 routes 같은 Laravel 표준 태스크의 키는 피합니다. 표준 태스크와 패키지 태스크를 합칠 때도 같은 문자열 키는 덮어써지기 때문입니다.
acme-courier처럼 패키지를 식별할 수 있는 키를 명시하고, 릴리스 간에 유지하세요. 키는 태스크의 표시 이름이 되며, 사용자가 --except로 지정하는 값이기도 합니다.

표준 태스크 다음에 실행된다

확인한 구현에서는 두 명령어 모두 표준 태스크 배열에 패키지의 등록 배열을 펼쳐 넣은 뒤 순서대로 호출합니다. 충돌하지 않는 키를 사용한 경우, 패키지 태스크는 표준 태스크 뒤에 추가됩니다. 이 순서를 전제로, 생성 명령어는 다른 표준 캐시를 다시 만들지 말고 패키지가 소유한 데이터만 생성합니다. 여러 패키지 간의 의존 순서를 제어하는 API로 optimizes()를 사용하지 말고, 엄밀한 순서가 필요하다면 전용 명령어를 명시적으로 나열하세요.
optimize:clear에는 cache:clear도 포함되어 있어 기본 캐시 스토어의 데이터도 삭제합니다. 패키지 전용 캐시만 지우고 싶다면 courier:clear-cache를 직접 실행하세요. 패키지의 삭제 명령어 자체도 공유 스토어 전체를 flush하지 않고, 소유한 키나 파일만 삭제하도록 설계합니다.

키 또는 명령어 이름으로 제외하기

두 명령어의 --except는 쉼표로 구분된 값을 받습니다. 각 값의 앞뒤 공백을 제거한 뒤, 태스크의 키 또는 명령어 이름과 일치하는 것을 제외합니다.
처음 두 줄은 같은 생성 태스크를 제외합니다. 세 번째 줄은 패키지의 삭제 태스크와 표준 cache:clear를 제외합니다. cache는 태스크의 키이며, 패키지 전용 이름이 아닙니다. 제외 지정은 해당 실행에만 적용됩니다. 프로바이더의 등록을 비활성화하거나, 이전에 만든 패키지 캐시를 자동으로 삭제하는 설정이 아닙니다.

태스크의 FAIL과 상위 명령어의 종료 코드를 구분하기

OptimizeCommand와 OptimizeClearCommand는 각 태스크를 callSilently()로 호출하고, 종료 코드가 0인지 여부를 태스크 표시에 전달합니다. 일반적인 하위 명령어의 출력은 표시되지 않으므로, 원인을 조사할 때는 전용 명령어를 직접 실행합니다. Laravel v13.35.0의 두 handle()은 하위 명령어가 0이 아닌 값을 반환해도 그 값을 상위 명령어의 반환값으로 돌려주지 않습니다. 화면에 FAIL이 표시되어도 루프는 계속되며, 예외가 없으면 상위 명령어의 종료 코드는 0이 됩니다. 반면 던져진 예외는 태스크 표시 컴포넌트에서 다시 던져지므로, 같은 방식으로 계속 진행되지 않습니다.
php artisan optimize의 종료 코드가 0이라는 것만으로 패키지 캐시 생성이 성공했다고 판단하지 마세요. 이 동작은 확인한 버전의 구현에 근거하므로, 지원하는 Laravel 버전을 업데이트할 때도 다시 확인합니다.
패키지 캐시 생성이 배포의 필수 조건이라면, 하위 명령어의 종료 코드를 직접 확인할 수 있는 절차로 구성합니다. 예를 들어 다음은 패키지 태스크를 일괄 실행에서 제외하고, 표준 태스크 다음에 한 번만 직접 실행하는 예입니다.
이 예는 courier:cache의 실패를 종료 코드에 반영하지만, 표준 태스크의 0이 아닌 종료를 집계하지는 않습니다. 표준 태스크도 엄밀하게 감지해야 하는 배포라면, 필요한 명령어를 개별적으로 실행해 종료 코드를 확인하세요.

업데이트에 견디는 캐시 설계와 확인

등록뿐 아니라 명령어와 읽기 측의 책임도 정해 둡니다.
  • 생성은 반복 실행해도 같은 입력에서 같은 상태가 되며, 도중에 실패해도 불완전한 데이터를 유효하게 만들지 않는다.
  • 삭제는 캐시가 존재하지 않는 경우에도 정상적으로 완료되며, 사용자가 배포한 설정이나 영속 데이터를 삭제하지 않는다.
  • 생성에 실패한 명령어는 오류를 보고하고 0이 아닌 값을 반환한다. 읽기 측도 손상된 캐시를 무조건 정상으로 취급하지 않는다.
  • 캐시 형식을 변경하면 사용자에게 재생성이 필요하다는 것을 안내하고, 장시간 실행되는 프로세스의 재시작도 검토한다.
패키지 테스트와 더불어, 패키지를 사용하는 애플리케이션에서는 다음을 확인합니다. 등록 배열은 정적이므로, 같은 프로세스 내의 테스트 간에 등록 상태가 이어지지 않는지도 주의합니다.

관련 페이지

패키지 설정 병합과 캐시

배포된 설정의 보완과 설정 캐시 재구축의 관계를 확인합니다.

Orchestra Testbench로 Laravel 패키지를 테스트하기

프로바이더와 Artisan 명령어를 테스트 환경에 등록합니다.

참조한 1차 자료

마지막 수정일 2026년 10월 6일