카카오스타일 프론트엔드 챕터가 사내 npm 패키지 저장소를 구축하며 겪은 시행착오를 정리한 글이다. git+ssh 방식의 한계에서 출발해 npm 유료 플랜과 GitHub Packages 를 검토했지만 스코프 충돌로 막혔고, 결국 Sonatype Nexus 로 hosted npm 저장소를 세웠다.
핵심 포인트- 기존에는 git+ssh 로 특정 저장소의 태그 내용을 받아 쓰고 있었다. 컴파일된 파일뿐 아니라 개발 환경 코드와 설정이 전부 포함돼 용량이 커지고, 모노레포에서는 패키지별 파일 분기 스크립트 같은 부가 작업이 필요했다.
- npm 유료 플랜은 읽기 권한 사용자까지 포함해 인당 월 7달러다. 참여자가 70명이면 월 490달러라 부담이 컸다.
- GitHub Packages 는 이미 조직을 쓰고 있어 전송과 스토리지 비용만 추가되는 조건이라 나쁘지 않았지만, 스코프 충돌에서 막혔다.
- registry 설정은 패키지 이름이 아니라 스코프 단위로만 할 수 있어, 같은 스코프의 비공개 패키지와 공개 패키지를 서로 다른 저장소에서 가져올 수 없었다.
- 최종 선택은 Sonatype Nexus 다. 직접 구축하는 저장소라 여러 스코프를 쓸 수 있고, 타 팀이 이미 구축해 쓰고 있었다.
상세 정리- 스코프를 바꿔 회피하려 했지만 GitHub Packages 는 조직 이름과 다른 스코프를 쓸 수 없어 그것도 막혔다.
- 기존 공개 패키지를 GitHub Packages 로 옮기는 방안도 떠올렸으나 이번에는 시도하지 않았다.
- Verdaccio 도 후보였다. 주변에 써본 사람이 많고 설정도 어렵지 않으며 안정성도 보장돼 보였지만, 이미 사내에 있는 Nexus 를 먼저 도입하기로 했다.
- 저장소 생성은 Repository 메뉴에서 hosted 타입 npm 저장소를 만들고, 생성 후 표시되는 URL 을 registry 설정에 쓴다.
- 권한은 Roles 에서 browse 와 read 권한을 묶은 읽기 역할을 만들고, 같은 방식으로 add 와 edit 권한을 담은 쓰기 역할을 만든 뒤 읽기 역할을 포함시킨다.
- delete 는 일부러 넣지 않았다. 보안상 패키지 작업자도 삭제는 별도 요청을 통해서만 하도록 했다.
- 로컬에서는 npm login 으로 Nexus 계정 인증을 하고, 배포할 패키지의 package.json 에 publishConfig registry 를 설정한다.
- 그런데 로그인과 권한이 다 맞는데도 배포가 되지 않았고, Nexus 의 Realms 설정이 필요하다는 것을 알게 돼 그것을 켜자 배포가 됐다.
- GitHub Actions 배포는 npm login 대신 .npmrc 에 base64 로 인코딩한 인증 값을 넣는 방식을 썼다. 사용자명과 비밀번호를 콜론으로 이어 인코딩한 값이다.
- 인코딩 값은 Actions secrets 에 넣고, 워크플로 중간에 .npmrc 파일을 생성하는 job 을 추가한다.
- 저장소 URL 을 .npmrc 에 적을 때는 앞의 프로토콜 부분을 빼고 슬래시 두 개로 시작하는 형태로 쓴다.
- 프로젝트에서 내부 패키지를 받으려면 루트에 .npmrc 를 만들고 해당 스코프가 자체 저장소를 바라보게 지정한다.
- 마지막 권고는 내부 패키지를 반드시 스코프로 관리하라는 것이다. 스코프가 없으면 설치할 때마다 registry 를 일일이 지정해야 한다.
왜 읽나비공개 패키지를 git 의존으로 버티다 정식 저장소를 세우려는 팀에게, 후보별 탈락 사유와 Nexus 설정에서 걸리는 지점을 순서대로 짚어주는 구축기.