이 글은 "private npm registry" 를 의미하는 사내 npm 저장소를 다룬다. 이를 위해 Verdaccio 를 이용하는데, 전반적인 이해와 사용 방법을 알아본다. 본인은 실제로 우리가 사용하는 npm 에 대해 조금 더 알게 된 계기가 되었다. 사내 npm 저장소를 구축할 일이 없어도 유용한 글이 될것이라 생각한다. Verdaccio -https://github.com/verdaccio/verdaccio
private npm registry는 무엇인가?
우리는 현재 npm 을 통해 많은 모듈들을 이용한다.
npm 에서 많은 모듈을 우리는 그저 편하게 install 하여 사용하고 있다.
우리가 이렇게 사용할 수 있는 건, npm 은 public 하게 제공해주기 때문이다.
반대로 private 이라면, 의미 그대로 외부적으로 노출되지 않는 npm registry 를 뜻한다.
private npm registry은 왜 필요한가?
정확히는 private package 를 원하는 것이다.
회사 사내에서 많은 프로젝트를 진행하다보면, 재사용할 수 있는 모듈이 많을 것이다.
팀 내부 또는 다른 팀에서도 충분히 사용할 수 있을거라 판단된다면, 많은 곳에서 쓰이길 바랄 것이다.
우리는 이러한 모듈들을 npm 에 통해 패키지화해서 공유할 수 있다.
하지만 보안상외부에 노출하기 어려운 것들도 있고, 너무 오픈되어 있어 관리 이슈가 좋지 못하다.
이를 위해, 오직 본인이 속한 조직을 위한 npm registry 를 구축하는 것을 private npm registry 라고 할 수 있다.
private npm registry은 어떻게 구축하는가?
역시나 이미 누군가 잘 만들어주셨다.
verdaccio 라는 것을 활용하면 된다.
이전에는sinopia를 많이 사용했고, 현재는 이를 기반으로 발전해온 verdaccio 를 사용한다.
우리가 아는 create-react-app, storybook, angluar cli, babel 등 많은 곳에서 이를 활용하고 있다.
하지만 이들이 사용하는 목적은 완전히 private npm 을 위함은 아니다.
즉, verdaccio 또한 이를 위해서만 존재하는 것은 아니다.
유스케이스 중 private npm 을 포함하고 있을 뿐이다.
문서에서 명시된 이점은 다음과 같다.
Use private packages
Cache npmjs.org registry
Link multiple registries
Override public packages
E2E Testing
간략히 설명하겠고,자세한 건 공식 문서를 참고하길 바란다.
Use private packages
위에서 언급한 내용이자 이 글의 주제이다.
Cache npmjs.org registry
만약 npmjs.org 서버가 느리거나, 죽게 되면 어떻게 될까?
이러한 이슈를 방지하기 위해 미리 필요한 패키지들을 캐시하여 대비할 수 있다.
Link multiple registries
하나의 프로젝트에서여러 개의 registry 의모듈을 가져올 수 있다.
verdaccio 에서 제공하는 기능인 uplinks 를 참고하면 된다.
Override public packages
본인의 프로젝트에 오픈 소스를 사용하고 있었는데, 버그를 발견하여 PR 를 날렸지만 승인되지 않거나 지연되고 있을 경우가 존재한다.
이러한 경우 본인이 구축한 npm 서버에 반영된 코드를 올려놓고 사용할 수 있다.
E2E Testing
여기서 E2E 테스트는 publish 하는 패키지들에 대해 체크를 의미한다. *publish - npm 서버에 업로드 하는 행위
local npm registry 를 통해 publish 를 시뮬레이션 할 수 있다.
위에서 언급한 create-react-app, storybook 등에서 사용하고 있는 방식이다.
권한이 $all 이라면, 누구나 install 할 수 있을 것이고, $authenticated 라면, 로그인을 해야한다.
여기까지 기본적인 기능들을 사용할 수 있다.
하지만 한가지 문제가 존재한다.
우리가 원하는 건 말 그대로 Private 한 것이다.
하지만 사실 npm adduser 는 누구나 가능하다는 점이 private 하지않다.
결과적으로는 npm adduser 를 막아야한다.
이는 config.yaml 에서 제공해준다.
auth: htpasswd: file: ./htpasswd # Maximum amount of users allowed to register, defaults to "+inf". # You can set this to -1 to disable registration. max_users: -1
max_users 에 대해 주석처리를 풀고 값을 -1 로 지정해주면 된다.
그러면 서버는 npm adduser 는 요청을 거부하게 된다.
그리고 서버에 있는 htpasswd 파일에 직접 접근하는 방식으로 사용자 관리를 private 하게 할 수 있다.
Vue.js의 Vuex Store 패턴에서 Vue.js Component에 Store를 바인딩 시키는 여러가지 방법을 알아보자. Vuex의 Store를 Component에 바인딩하는 방법에는 여러가지가 있으며 상황에 따라 그 쓰임이 다르다. 그 중에서 가장 실무에 적합하고 가독성이 좋은 방법이 무엇인지 알아보고 활용해보자.
해당 포스트에서는 Vuex의 설명과 사용법에 대해서는 언급하지 않았으며, 오로지 Vuex Store를 컴포넌트에 바인딩하는 방법을 설명한다.
프로젝트의 규모가 크거나 작든Vuex를 사용할 때는 Store를 Module 별로 분리하는 것이 바람직하다. 그렇지 않으면 각 컴포넌트마다 바인딩 된 Store의 state들이 다른 컴포넌트의 루틴에 의해 오염될 가능성과 코드의 복잡성이 높아지게 되어 있다.
이번 포스트에서는 모듈별로 분리된 Store를 각 컴포넌트에서 효율적으로 바인딩시키는 여러 가지 방법들과 코드 스타일을 알아보자.
Basic
Vue 공식 API에서는 명시된 기본 Store 바인딩 방법이다.
위 내용은mapState라는 Helper를 이용하여 객체의 형태로count를 바인딩 한 형태이고 아래처럼 state의 이름을 그대로 상속받아 정의할 수도 있다.
기본적인 바인딩 방법은 가장 단순한 구조를 가진 Store를 바인딩하였을 때이다. 하지만 Store가 여러 모듈별로 분리되어 있고 하나의 컴포넌트에서는 여러 Store 모듈을 바인딩해야 한다면 매우 복잡해질 것이다.
아래 가정을 가지고 각 바인딩 Style을 살펴보자.
각각User,Book이라는 Store 모듈이 존재하고,User는A/B경로에 있으며,Book은A/B/C경로에 위치한다.
프로젝트 구조는 다음과 같다.
Style 1 - Vuex Helper
또는
특정 경로에 포함된 Store 모듈을 사용하기 위해서는 해당 경로를 모두 명시해줘야 한다. 이렇게 사용을 한다면 어느 경로에 있든 서로 다른 Store 모듈을 하나의 컴포넌트 또는 여러 컴포넌트에서 바인딩하여 사용이 가능하다. 하지만 위 예제에서 A/B/C의 단순하고 짧은 명칭이지만 폴더나 Store 모듈의 명칭이 꽤나 길다면 역시나 가독성이 좀 떨어질 것이다. 그래서 우리는 Vuex에서 제공하는 Namespace Helper를 생성할 수 있는createNamespacedHelpers이용하여 바인딩하는 것을 가장 인상적으로 볼 수 있다.
Style 2 - createNamespacedHelpers 1
또는
모듈의 이름이 길고 구조가 복잡하다면createNamespacedHelpers를 사용하여 바인딩한다면 computed 또는 methods가 간결하고 뛰어난 가독성을 보이는 것을 알 수 있다.
Store 모듈들의 경로를 computed와 methods에 정의를 안 했을 뿐이지 무엇이 다르겠냐고 한다면 생각해보자. 우리는 개발을 하면서 코드를 살펴볼 때나 구현을 할 때 가장 상단에 삽입하거나 명시해 놓은 구현체는 자주 보지 않는다. 오히려 data, computed, methods를 가장 많이 볼 것이다. 이러한 상황에서 수많은 모듈의 경로가 명시되어 있다면 state나 mutation, action의 개체들을 찾기 어려울 것이다.
Style 3 - createNamespacedHelpers 2
그러면 여기서 좀 더 깊이 한번 보자.
만약createNamespacedHelpers를사용을 한다고 하지만 만약 하나의 컴포넌트에 서로 다른 경로에 있는 Store 모듈을 여러 개 바인딩할 경우에는 어떻게 해야 할까? 지금까지Book이라는 모듈만을 가지고 예제를 보았지만, 여기에서User모듈을 추가해보자.
아래처럼 정의도 가능하다.
이렇게 한다면 하나의 컴포넌트에서도 많은 모듈을 바인딩하기가 쉬우며, 코드의 가독성 역시 좋아진다.
각 개발자마다 코드 스타일은 모두 다르고 해당 포스트에 언급한 내용 이외에 더 좋은 방법이 있을 수 있다. 다만 중요한 것은 개발하기 전 또는 하면서 어느 방법이 가장 좋은지 몸소 느끼며 차근차근 수정해 나아가는 것이 중요하다고 본다. 어느 스타일이든 결과는 같겠지만 업무/개발의 속도는 확연히 차이가 날 것이다.