react-seekbar 라는 라이브러리를 만들었다. progressbar지만 드래그해서 움직일 수 있고 핸들 크기, hover 시 보이는 색상 등 다양하게 커스텀할 수 있다. 이번 글에서는 배포하는 과정에서 생각했던 내용 중심으로 작성해보려 한다.
왜 만들었는데?
이전 개인 프로젝트에서 음악 재생 기능이 있었다. progress bar를 드래그하면 특정 위치로 이동하는 기능이 필요해서 찾아봤는데, 마음에 드는 라이브러리가 없었다. 그런 기능을 갖고 있는 라이브러리는 존재했지만 내 입맛대로 커스텀하기 어려웠다.
그냥 내가 직접 라이브러리로 만들면 되겠네! 해서 무작정 시작했다.
전부터 나만의 라이브러리를 만들어서 배포해볼까하는 생각을 항상 해왔는데, 이번 기회에 배포 경험도 얻어갔다.
세팅
여러 블로그들과 문서들을 많이 참고해서 세팅했다.
대부분 라이브러리 개발할 때 번들러로 rollup을 사용하고 있었다. 왜? 다른 번들러도 많은데 왜 rollup이 많이 채택되었을까?
Rollup 쓰는 이유
Rollup은 작은 코드 조각들을 라이브러리나 애플리케이션과 같이 더 크고 복잡한 것으로 컴파일하는 JavaScript용 모듈 번들러입니다. CommonJS, AMD와 같은 이전의 독특한 솔루션 대신 JavaScript의 ES6 버전에 포함된 코드 모듈을 위한 새로운 표준 형식을 사용합니다. ES Module을 사용하면 즐겨찾는 라이브러리에서 가장 유용한 개별 기능을 자유롭고 원활하게 결합할 수 있습니다.
빌드 결과물을 ES6 모듈 형태로 만들어준다.
이 말은, 라이브러리 전체를 불러오는게 아니라 필요한 부분만 가져올 수 있다는 것이다.
ES Module은 정적 바인딩을 사용한다. 모듈 로드 시점에서 바인딩이 결정되기 때문에 런타임 오류를 줄일 수 있다. 사용한 코드들 제외하고 사용하지 않는 코드들은 제거할 수 있기 때문에, 즉 Tree Shaking이 가능하기 때문에 빌드 크기를 줄일 수 있고, 실행 속도도 향상시킨다!
시행착오
에러 1 : Cannot use import statement outside a module
Rollup 3 버전에서 이런 에러가 떴다. package.json에 "type": "module" 을 설정해도 인식을 못한다.
그리고 package.json을 import 할 때에도 이런 에러가 떴다.
import pkg from './package.json'; // Module "file:///~/package.json" needs an import assertion of type "json"
해결 방법 1
확장자를 mjs로 바꾸기 ex) rollup.config.mjs
package.json은 아래처럼 바꾸기 참조
import pkg from './package.json' assert { type: 'json' };
해결 방법 2
--bundleConfigAsCjs 추가
"build": "rm -rf dist && rollup -c --bundleConfigAsCjs",
해결 방법 3
Rollup 2 버전으로 다운그레이드
나는 1, 2번 처럼 따로 뭔가를 추가하기 찝찝해서 그냥 다운그레이드했다.
에러 2: plugin rpt2) Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
이건 rollup-plugin-typescript2 플러그인을 사용했을 때 뜬 에러이다.
이 플러그인은 타입스크립트를 번들링할 수 있게 하는 플러그인이다.
에러를 못잡고 한참을 고민하다가 타입스크립트 관련 코드가 들어간 tsconfig 파일을 유심히 보았다.
그냥 복사 붙여넣기한 코드라 어떤게 있는지 정확히 몰랐었는데 emitDeclarationOnly 가 true로 되어있었다. 이 설정은 컴파일 시 d.ts 파일만 추출한다는 소리다. 이 설정을 지우니 해결되었다..
Storybook
사용한 이유는 테스트하기 편하고, 자동으로 문서화해주기 때문이다!
Local 테스트
npm link를 통해 로컬에서 테스트할 수 있다.
1. 라이브러리의 루트 디렉토리에서 npm link
2. 테스트할 프로젝트의 루트 디렉토리에서 npm link react-seekbar
3. 테스트할 프로젝트에서 npm i ../react-seekbar
배포를 해보자!
배포는 생각보다 쉬웠다. npm login 후 npm publish 명령어만 입력하면 배포 끝이다.
CI / CD?
배포를 수동으로 할 수는 있지만 만약 혼자가 아닌 여러 사람들과 협업하는 상황이라면 너무 비효율적이라고 생각했다. 그래서 CI / CD를 통해 빌드, 테스트, 배포를 자동화할 수 있게 해보았다.
Github Action을 처음 사용해봤는데 자동화되는게 신기했다. 다음에 팀으로 프로젝트할 때 쓰면 좋겠다고 생각했다.
push했을 때 커밋 메시지 앞에 v가 붙으면 publish하도록 작성했다.
name: Publish
on: push
jobs:
publish-npm:
runs-on: ubuntu-latest
if: startsWith(github.event.head_commit.message, 'v')
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
storybook 또한 chromatic을 통해 publish하도록 설정했다.
결론
이렇게 내가 만든 컴포넌트를 npm에 배포해보았다.
사실 배포도 배포지만, 컴포넌트 개발하는데도 은근 시간이 많이 걸렸다. 자연스럽게 드래그하는 법, 모바일 환경에서 드래그 제대로 작동하는 법, 성능 최적화 등등 애니메이션 부분을 처리하는 과정에서 삽질을 많이 했다. 그리고 다른 사람도 쓴다고 생각하니 좀 더 꼼꼼히 만들고 최적화에 신경쓰느라 개발하는데 꽤 많은 시간이 걸렸던 것 같다.
개발자들이 편하게 이용할 수 있도록 하기 위해 문서화, 네이밍 등을 고려하고, 사용자 경험도 좋게 하기 위해 성능도 고려해야 한다. UX와 DX 둘 다 개선하기 위해 고민을 많이 할 수 있어서 좋은 경험이었다. 아직 개선해야 되는 부분들이 많아서 계속 리팩토링할 예정이다.
'React' 카테고리의 다른 글
[사이드 프로젝트] 우당탕탕 리액트로 크롬 익스텐션 만들기 (Gachon-Tools) (0) | 2023.06.01 |
---|---|
Spotify API 사용기 (3) - Spotify Web Playback SDK를 사용하여 음악 재생 기능 만들기 (0) | 2023.04.02 |
Spotify API 사용기 (2) - SSR에서의 React Query (0) | 2023.03.26 |
Spotify API 사용기 (1) - 앱 생성 및 로그인 기능 구현 (with Next.js) (0) | 2023.03.24 |
[React] 상태 관리 라이브러리의 이해 - Redux 동작 원리 (1) | 2023.02.02 |