1. 문제
컴포넌트 소스 변경 시 스토리북에서 즉시 반영되지 않는 이슈 (HMR 동작하지 않음)
기존 설정
- 모노레포 구조
apps/docs # 스토리북으로 구성된 디자인 시스템 문서
├── .storybook
├── src
└── package.json # 스토리북 실행 (dev: storybook dev -p 6006)
packages/ds-components # 디자인 시스템 컴포넌트
├── src
├── dist
└── package.json # 라이브러리 빌드 (build: vite build)
- 스토리 파일(apps/docs/src/stories/button.stories.jsx)
import { Button } from '@ds/components';
export default {
title: 'Components/Button',
component: Button,
}
2. 원인
스토리북이 컴포넌트 패키지의 dist 폴더를 참조하고 있어서 컴포넌트 소스 변경 시, 다시 빌드해야만 변경사항이 반영됨.
3. 해결
컴포넌트 패키지에 dev script 추가
컴포넌트 패키지를 개발 모드에서 실행할 수 있도록 설정하기. Vite는 라이브러리 모드에서도 내부적으로 server.watch 기능을 지원하기 때문에 실제 UI를 띄우지 않더라도 파일 변경을 감지하고 HMR을 트리거 할 수 있음.
// packages/ds-components/package.json
"scripts": {
"dev": "vite dev"
}
스토리북 패키지의 alias 설정 추가
/dist
대신 /src
를 직접 참조할 수 있도록 설정하기.
// apps/docs/.storybook/main.js
async viteFinal(config) {
return {
...config,
resolve: {
alias: {
'@ds/components': path.resolve(__dirname, '../../../packages/components/src/components'),
'@ds/hooks': path.resolve(__dirname, '../../../packages/components/src/hooks'),
...
},
},
}
}
이 때 주의해야할 점은 내 경우, 컴포넌트 패키지에서 아래와 같이 alias 설정을 해놨기 때문에 스토리북 설정에서도 동일한 구조의 alias 설정을 해야 모듈을 제대로 찾을 수 있다는 것이다. 즉, '../../../packages/components/src'
대신 '../../../packages/components/src/components'
와 같이 하위 경로를 명확하게 지정해줘야 함!
// packages/ds-components/vite.config.js
resolve: {
alias: {
'@ds/components': path.resolve(__dirname, 'src/components'),
'@ds/hooks': path.resolve(__dirname, 'src/hooks'),
...
},
},
뽀나스 삽질 후기
터보레포에서 제공하는 design-system 예제가 있다. 구조는 완전히 동일하지만, 예제에서는 tsup --watch
를 사용하고 변경사항이 스토리북에 즉시 반영되고 있었다. 그래서 나도 "파일이 변경될 때마다 빌드를 다시 해야 한다"는 생각에 꽂혀서 처음엔 vite build --watch
를 사용해서 빌드 파일을 업데이트하려고 했다. 하지만 이건 프로덕션 빌드이기 때문에 HMR이 동작하지 않았다.
모노레포 구조를 바꿔야하나 번들러를 바꿔야하나 고민을 하던 찰나, vite에선 HMR을 시키려면 vite dev
를 사용해야한다는 걸 알았다. 그렇지만 저 명령어는 페이지를 띄울 때만 사용하는 거라 생각해서 답을 코앞에 두고 점점 삼천포로 빠지기 시작했다. 결론은 vite와 tsup 번들링 방식의 차이를 모르고 삽질을 했던 것...ㅎ 허무하지만 아차 싶었다! 다음에는 이 부분에 대해 더 깊이 파악해보면 좋을 것 같다.
++ 여기서 vite의 server.watch 옵션과 chokidar 같은 파일 감시 기능은 불필요하므로 혹시나 눈에 띄더라도 과감히 패스할 것.
'개발자의 하루' 카테고리의 다른 글
[Module Federation] 여러 패키지에서 React Context Instance 공유하기 (1) | 2022.07.31 |
---|