Packwerk는 애플리케이션을 마이크로서비스로 분할하는 것이 아니라, 모놀리식 내부를 논리적으로 격리된 ‘팩(pack)’으로 구분하여 아키텍처적 규율을 강화합니다. 각 팩은 명확한 가시성 규칙, 내부/외부 API, 그리고 제어된 의존성을 가진 자체 포함된 단위가 됩니다. 이는 특히 대규모 팀에서 코드베이스를 이해하고 변경하며 확장하는 것을 용이하게 합니다.
Packwerk가 해결하는 주요 문제점
- 모놀리식의 거대함: Packwerk는 무관한 도메인에 흩어져 있던 파일들을 잘 정의된 팩으로 그룹화하여 애플리케이션을 더 작고, 깔끔하며, 집중된 형태로 느끼게 합니다. 이는 코드 탐색의 복잡성을 크게 줄여줍니다.
- 프라이버시 부재로 인한 우발적 결합:
enforce_privacy: true
설정을 통해 Packwerk는 팩 간의 경계를 명확히 합니다. 다른 팩의public
인터페이스만 사용하도록 강제하며,private
파일에 접근하려 할 경우 빌드 타임에 오류를 발생시켜 예상치 못한 의존성 생성을 방지합니다. - 두려웠던 리팩토링:
package.yml
파일을 통해 각 팩이 의존하는 대상을 명시적으로 선언하도록 합니다. 이는 숨겨진 의존성 도입을 막고, 선언되지 않은 의존성이 발생할 경우 CI에서 풀 리퀘스트를 중단시켜 변경의 안정성을 보장합니다. - CI를 통한 1차 방어선 구축: Packwerk의 강력한 기능 중 하나는 CI 파이프라인과의 통합입니다. 개인 클래스 외부 접근, 미선언 의존성 발생, 아키텍처적 드리프트 도입 등 경계 위반 사항이 발생하면 CI가 즉시 실패합니다. 이는 프로덕션 환경에서 문제를 발견하는 대신 개발 초기 단계에서 오류를 감지하여 디버깅 시간을 절약하고 코드베이스가 혼란에 빠지는 것을 방지합니다.
Packwerk를 적용한 개발자 경험
Packwerk를 적용한 Rails 프로젝트는 마치 각 부서(팩)가 고유한 책임을 가지고 필요한 정보만 외부에 노출하는 회사와 같습니다. 예를 들어, packs/orders
와 packs/users
와 같은 폴더 구조를 통해 각 도메인의 로직이 명확히 분리됩니다. package.yml
파일은 각 팩의 enforce_privacy
, enforce_dependencies
, owner
와 같은 규칙을 정의하여 팀 간의 협업과 코드 소유권을 명확히 합니다. 이를 통해 다른 팩의 public
인터페이스만 접근 가능하며, private
파일에 대한 직접 접근은 Packwerk에 의해 차단됩니다. 이러한 접근 방식은 코드의 프라이버시를 보장하고, 의존성을 명확히 하며, 각 팀이 자신의 코드를 소유하고 유지보수할 수 있도록 합니다.