lerna를 이용해 모노레포로 eslint-config 파일 npm에 배포하기
❓상황
프로젝트를 진행하면서 반복적으로 eslint 구성파일을 작업했던 것이 너무 귀찮았다.
eslint 구성파일을 보일러플레이트가 아닌 npm으로 설치하여 사용할 수 있도록 npm을 배포해보았다.
npm 배포를 하기로 마음먹은 이유
이번에 eslint 구성파일을 npm으로 배포하기 전까지 단 한번도 npm으로 배포해보지를 않았다.
내가 다녔던 부트캠프에서도, 인턴십을 했을 때도, 혼자서 공부했을 때도 npm 배포하는 방법 대신 자바스크립트 또는 타입스크립트로 리액트를 어떻게 잘 구성하는지를 배우는게 주 목적이었다.
시간이 흘러 회사를 다니게 되면서 리액트로 작업했던 작업물들을 공통으로 많이 쓰였던 것들을 깃허브에 유틸함수, 훅, 컴포넌트 등을 담은 레파지토리를 보일러플레이트로 관리하고 있었다.
그러던 와중에 내가 만든 보일러플레이트를 목적에 맞게 레파지토리로 분리하여 npm으로 배포하여 다른사람들도 사용할 수 있도록 생태계에 도움을 주고 싶어졌다.
그래서 npm으로 배포를 해봐야겠다는 생각을 갖게 되었다.
npm 배포하기 전에 빌드하는 방법을 여럿 시도해보았다.
npm으로 배포하려고 마음을 먹어도 누군가 알려주지도, 지금까지 공부를 딱히 하지 않은 상태였기 때문에 어디서 부터 해야할지 감이 잡히지 않았다.
무작정 npm 배포를 어떻게 하는지 구글 검색을 통해 간단한 유틸함수를 npm 배포를 따라해 보면서 감을 익히기 시작했다.
그래서 내가 만들었던 컴포넌트, 훅, 유틸함수를 빌드하여 npm으로 배포할 수 있었지만 어떻게 빌드되도록 설정하는지 딱히 설정하지 않았기 때문에 파일의 크기는 크고 불필요한 파일들까지 빌드되는 대참사가 발생했다.
그래서 나는 npm 배포부터 접근해야하는게 아니라 빌드하는 것 부터 시작해야겠다는 생각을 하게되었고 하나하나 계단을 밟아 나가는 식으로 부딪혔다.
먼저 컴파일러나 번들러없이 자바스크립트, 타입스크립트를 배포하는 것을 시작을 했다.
babel, weback, rollup, esbuild 그리고 vite를 마지막으로 트랜스파일러와 번들러를 접해보면서 빌드할때 발생한 오류들을 트러블슈팅해보면서 빌드경험을 축적했다.
가장 기억에 남는것은 package.json에 type을 module로 설정했고 빌드하려는 파일도 esm 문법으로 사용했음에도 commonjs 문법을 사용하고 있다고 오류가 발생한 것이다.
알고보니 bable.config.js 파일이 commonjs 문법으로 사용되고 있었던 문제였고 esm 문법으로 고치니 문제를 해결할 수 있었다.
해당 문제는 하루종일 애를 먹어서 고생했던것이 가장 기억에 남는다.
번들러들을 사용해보면서 느꼈던 점은, esbuild처럼 빠르게 빌드할 수 있고 rollup처럼 하나의 구성파일에서 관리를 할 수 있는 vite가 대단하다고 느끼게 되었다.
하지만 eslint-config 구성파일을 배포할 때는 별도의 번들러를 사용하지 않았는데, 그 이유는 아래에서 서술하겠다.
컴포넌트를 npm 배포하다가 eslint-config 구성파일로 급 선회한 이유
실제로는 컴포넌트 패키지를 먼저 배포를 했지만, eslint-config 구성파일을 가장 먼저 완성도 있게 만들어 배포했다.
컴포넌트, 훅, 유틸함수 등을 각 레파지토리에 만들어서 vite 번들러로 npm 배포까지 성공했다. 야호!
하지만 인간의 욕심은 끝이 없다 했는가? 내가 배포한 각 프로젝트마다 동일한 구성파일을 만들어 줘야 했다.
그렇기 때문에 동일한 작업을 하지 않기위해 eslint-config 파일을 npm으로 우선적으로 배포해야겠다는 생각을 하게 되었다.
eslint-config 구성파일에 모노레포를 도입한 이유
또한 프로젝트마다 컴포넌트에서 사용되는 훅이 업데이트 될 경우 훅 패키지를 업데이트해서 npm 배포하고, 컴포넌트 패키지에서 훅 패키지의 버전을 올린 이후에 컴포넌트 패키지의 버전을 올려서 npm 배포해야했다.
이러한 작업방식은 혼자서 개발한 나에게 실수가 빈번하게 발생했고, 작업 피로도가 높아져서 패키지를 수정하는게 굉장히 두려웠다.
그래서 이 문제를 해결하기 위해서 다른 팀이나 회사들은 패키지를 어떻게 관리하는지 궁금해서 여러 패키지들을 참고하게 되었다.
컴포넌트 개발에 가장 큰 영감을 주었던 mantine과 유틸함수 개발에 가장 큰 영감을 주었던 slash의 레파지토리를 참고하게 되었다.
위의 레파지토리는 전부 하나의 레파지토리안에 여러개의 패키지를 관리하는 모노레포 방식을 사용하고 있었고, 나는 이것을 도입해봐야겠다는 생각을 하게되었다.
위에 서술한 레파지토리들은 참고하여 lerna + pnpm을 도입했다.
그 이유를 적으면 한도끝도 없이 길어질거 같아서 짧게 적자면, 가장 레퍼런스가 많은 lerna와 심볼릭 링크로 의존성 설치를 줄이는 pnpm을 선택했다고 보면 될거 같다.
eslint-config 구성파일에 번들러를 사용하지 않은 이유
가장 큰 이유는 패키지를 번들링 해야할 만큼 파일이 크지 않기 때문이다.
그리고 트러블슈팅하기에 좋을거 같아서 번들러를 사용하지 않았다.
번들러를 사용하면 해당 파일을 난독화시켜서 사람이 읽기는 어렵지만 파일 크기를 줄이는 장점이 있다는 것을 알고 있다.
그렇게 될 경우 해당 패키지에서 오류가 발생할 경우 디버깅을 하기 어렵다는 단점이 있다.
물론 난독화를 하지 않도록 설정하거나, 정 안되면 레파지토리를 들어가서 소스코드를 읽어보면 그만이다.
그치만 내가 만든 패키지를 배포하고 나서 오류가 발생했을 때, 오류를 수정하기 위해 난독화를 해제하거나 레포지토리에 들어가지 않고도, node_modules에 설치한 패키지의 소스코드를 읽어서 트러블슈팅하는게 시간도 짧았기 때문에 번들러를 사용하지 않는 쪽으로 가게 되었다.
물론 리액트를 사용하여 만드는 패키지의 경우에는 파일크기가 크기때문에 번들러를 해야한다는 생각이다.
마무리
사실 블로그에 작성하고 싶은게 남아 있는데 그건 컴포넌트, 훅, 유틸함수 패키지를 관리하고 있는 레파지토리에 관한 내용이다.
eslint 구성파일을 루트에서 작성해서 패키지별로 적용시키기, 테스트 파일을 루트에 작성하기, docusaurus를 이용해서 패키지별 문서 만들기, 패키지에 있는 README.md 복사하기, turborepo 도입(미정) 등 정말 하고 싶은 얘기가 굉장히 많다.
그치만, 아직 작업이 진행중이고 언제든지 바뀔 가능성이 굉장히 높기 때문에 아직은 풀어내지 못하고 있다.
작업이 끝나는 대로 해당 레파지토리를 public으로 변경하고 블로그 글도 작성해봐야겠다.
'공부 > 프론트엔드' 카테고리의 다른 글
공부 | Tailwindcss 더 잘 사용하기(class-variance-authority, tailwind-merge) (0) | 2024.04.24 |
---|---|
공부 | CSR, SSR 그리고 Next.js (0) | 2023.07.05 |
오류 | addEventListener 이벤트 탐지 (0) | 2022.10.25 |
공부 | HTML, CSS 말 줄임(단일 행, 다중 행) 스타일 정리 (0) | 2022.10.12 |
공부 | HTML, CSS 웹 접근성(스크린리더) 정리 (0) | 2022.10.11 |