이번 학기에 동아리에서 찬휘의 '나만의 작고 소중한 UI 라이브러리 만들기' 세션을 들으며 UI 라이브러리를 만들어볼 기회가 있었습니다. 전부터 만들어보고 싶다고는 생각했었는데 킹갓찬휘가 떠먹여준다? 당장 달려갔습니다.
일단 주 목적은 내가 쓸 것을 만들기였습니다.
번들러, UI 컴포넌트 개발 도구 선택과 세팅
우선 번들러는 우리가 js, jsx나 ts, tsx 등으로 작성한 여러개의 코드 파일들을 하나 또는 여러 개의 파일로 묶어주는 역할을 합니다. 이 과정에서 문자를 압축해서 코드 파일의 용량을 줄여주기도 하고 트리 셰이킹을 통해 안 쓰는 부분을 없애주기도 합니다. 가장 유명한 웹 번들러는 아무래도 Webpack일텐데요. 웹팩의 가장 큰 유용한 점 중 하나는 Hot Module Replacement입니다. 공식 문서에도 나와있듯 모든 종류의 모듈을 새로고침 할 필요 없이 런타임에 업데이트 할 수 있습니다. 소스코드를 수정하면 새로고침을 하지 않아도 바로 반영이 됩니다. 또, Code Splitting은 코드를 다양한 번들로 분할하고, 요청에 따라 로드하거나 병렬로 로드할 수 있도록 해줍니다. 바로 로드할 필요 없는 코드는 나중에 로드해서 로딩 속도의 개선을 도모할 수 있는 등의 장점이 있습니다.
하지만 이번 프로젝트에서 선택한 라이브러리는 Rollup입니다. 웹팩과의 주요 차이점은, 롤업은 모듈 호이스팅을 통해 모든 모듈들을 동일한 수준으로 끌어올려 번들링을 합니다. 라이브러리 만들 때 많이 쓴다고 하여 선택했습니다. 결과적으로 js로 컴파일된 파일 하나, 타입들이 정의된 d.ts 파일이 남게 됩니다.
처음에는 React + Vite로 세팅을 했습니다. 또 UI 컴포넌트 테스트를 위해 무거운 Storybook 대신 빠르고 간단한 Ladle을 선택했는데.. Next.js로 라이브러리 기반을 바꾸면서 결국 Storybook으로 가게 됩니다.
설정은 찬휘의 레포를 참고해주세요..
그 외에 자잘한 세팅들은 아래와 같습니다.
- tailwind config를 export해서 preset을 만들어서 라이브러리를 가져다 쓰는 곳에서 적용할 수 있도록 합니다.
- 각 컴포넌트들을 라이브러리의 진입점에서 export해줍니다.
무엇을 만들까
일단 제일 필요하고 자주 쓰는 컴포넌트부터 만들어보기로 했습니다. 모달, 토스트과 버튼인데요. 버튼이야 그냥 스타일 적용하면 되고.. 모달과 토스트는 전역에서 사용할 수 있게 하기 위해 Layout에 넣어두고 zustand로 state를 관리해서 어디서든 useAlert()로 사용할 수 있게 했습니다.
처음에는 실제로 써보면서 확인을 하기 위해.. npm에 배포를 해서 다운받아 썼는데요. 버전이 0.0.20이 넘어가자.. 이건 좀 아닌 것 같아서 로컬에 있는 파일들을 패키지로 쓰면서 체크하는 게 낫겠다 싶었습니다.
npm 배포는
{
...
"name": "@r-4bb1t/rabbit-ui",
"private": false,
"version": "0.0.44",
"type": "module",
"author": "r-4bb1t",
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
"description": "Rabbit UI: UI components for Next.js with Tailwind CSS",
"repository": {
"type": "git",
"url": "https://github.com/r-4bb1t/rabbit-ui.git"
},
...
}
package.json에 위와 같이 정보를 작성해주고
npm publish --access=public
npm 로그인 된 상태에서 위의 라인을 터미널에 치면 됩니다.
로컬 파일을 패키지로 쓰려면.. 사용할 곳의 package.json에
{
...
"dependencies": {
"@r-4bb1t/rabbit-ui": "로컬의 dist 주소",
...
},
"pnpm": {
"overrides": {
"@r-4bb1t/rabbit-ui": "로컬의 dist 주소"
...
}
},
이런 식으로 해주면 됩니다. 짱 편했어요.
Next.js와 Storybook으로 이주
일단 제가 많은 프로젝트를 Next.js로 만들기 때문에, 위와 같이 작성을 하면 Layout으로 감쌀 경우 내부에 server component를 쓸 수가 없게 됩니다. 모달과 토스트가 client component라서,, 그걸 명시를 해주고 싶었어요. 그래서 기반을 Next.js로 바꾸고,,
import preserveDirectives from "rollup-preserve-directives";
const sourceOptions: RollupOptions = {
...
output: { ..., preserveModules: true },
plugins: [..., preserveDirectives()]
...
}
rollup-preserve-directives 플러그인을 활용해 'use client' 등의 directives를 냅두도록 합니다.
그리고... preserveModules가 false이면(default) 파일을 다 하나로 합칩니다. 당연함. 근데 이렇게 하면 모든 것들이.. 클라이언트 컴포넌트가 되어버립니다.. 결국 파일 합치기의 이점을 포기하고 preserveModules를 true로 했습니다.
Next.js로 바꾸고 ladle도 다시 세팅을 하다가.. 공식 문서를 참고해봐도 잘 작동이 안되는 것 같아서 그냥 Storybook으로 이주했습니다. 빌드 완전 오래 걸림.
뭔가 얼렁뚱땅이지만.. 아무튼 열심히 배포까지 해놓았고.. 계속 써보면서 개선하고 있습니다. 재밌다.
https://www.npmjs.com/package/@r-4bb1t/rabbit-ui
'Web > Frontend' 카테고리의 다른 글
[React] [번역] 리액트 엘리먼트, 자식 컴포넌트, 부모 컴포넌트 그리고 리렌더링에 관한 미스터리 (0) | 2024.06.22 |
---|---|
[Next.js] 1시간만에 OpenAI로 영어 회화 도우미 만들기 (3) | 2024.04.07 |
[Next.js] API route와 firebase로 인증과 글 쓰기 구현하기 (0) | 2024.01.21 |
[Web] 초보 웹 프론트엔드 개발자가 백엔드와 통신할 때 오류가 난다면? (3) | 2023.11.22 |
[Next.js] AWS Polly API를 사용해 TTS 서비스 만들기 (2) | 2023.11.15 |
댓글