-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat] Pnpm Workspace를 통한 모노레포 도입 #332
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
모노레포 도입 정말 고생많으셨습니다 🚀✨
apps/landing/public/next.svg
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
next 초기 세팅할 때 수반되는 불필요한 파일들은 제거해주는 게 좋을 것 같습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋습니다 !
apps/landing/tsconfig.json
Outdated
"compilerOptions": { | ||
"target": "ES2017", | ||
"lib": ["dom", "dom.iterable", "esnext"], | ||
"allowJs": true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요 옵션 true로 해준 이유가 있나요 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어.. 따로 없는데 landing
에서의 tsconfig 파일은 추후에 tsconfig
패키지의 next.json
으로 대체할 예정이라 남겨두었습니다 !
} | ||
case 'team': { | ||
return variant.logoUrl ? ( | ||
<img src={variant.logoUrl} alt="팀 프로필 이미지" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
스크린 리더기가 이미 img
태그를 이미지로 인식하고 있기 때문에 alt
메시지에 -이미지 라는 워딩은 불필요하다고 합니다 ! 참고해서 수정해주심 좋을 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋습니다 !!
해당 이슈 번호
closed #330
체크리스트
💎 PR Point
pnpm workspace
를 통해 모노레포를 도입하였어요 ! 모노레포를 도입하는 과정을 순서대로 한 번 작성해볼게요.도입하게 된 과정
먼저 모노레포를 어떻게 도입하게 되었느냐를 말씀드리고 싶어요. 먼저 저희 티키는 랜딩 페이지가 있어요. 지금은 현재 '/'이라는 Url의 루트에 라우팅되어 있는데, 프로덕트를 분리해야겠다라는 필요성을 느꼈습니다. 왜냐면 랜딩이라는 하나의 서비스는 사용자에게 티키에 대한 서비스를 홍보하고 설명하며, 다른 가이드를 제공해주고, 최종적으로 데스크탑 앱으로 출시될 티키의 메인 서비스를 설치할 수 있는 페이지에요.
즉, 랜딩 페이지는 퍼블릭 웹사이트에요. 모든 사용자들이 구글과 같은 브라우저 엔진을 통해 검색하여 드나들 수 있는 도메인이여 하고, 따라서 SEO 측면으로도 데스크탑 앱인 메인 서비스보다 신경써서 구현할 필요가 있을 것이라는 생각을 했습니다. (그래서 Next로 개발할 생각입니다.)
따라서 프로덕트를 아예 분리해버리는 것이 관심사 분리라는 측면에서도 효과적이라고 생각했고, 배포 주기나 개발의 진행도 또한 랜딩과 티키 메인 서비스라는 두 가지 도메인이 분명 분리되어 관리될 것이라는 생각을 했기 때문에 모노레포를 도입하였습니다.
두 번째 이유는 저희의 UI 컴포넌트 볼륨이 점점 커져가는 것이였습니다. 즉 컴포넌트 하나를 개발하더라도 전체 티키 프로덕트를 다시 빌드해야하는 단점이 있었어요. 모든 코드가 하나의 프로덕트 안에 종속되어 있기 때문에, 사소한 코드 하나를 변경하거나 일부 기능을 구현한다 하더라도 전체 프로덕트를 모두 빌드하는 것은 효과적이지 못하다고 생각했습니다.
따라서
ui
와 같은 패키지를 따로 생성하여 그곳에서 관리하도록 구현하였어요. 또한icon
,utils
패키지를 추가적으로 설정하여 각 패키지가 관리하는 코드들은 해당 패키지의 빌드를 통해서 사용할 수 있도록 하였습니다.도입 과정
1️⃣ 워크스페이스 설정
먼저 프로젝트 루트 디렉토리에
pnpm-workspace
파일을 통해 패키지를 명시해주어야 합니다. 저는 서비스를 담당하는apps
와 유틸 혹은 UI 패키지를 제공하는packages
로 분리하였어요. 루트에도package.json
이 존재하는데 워크스페이스 특성 상, 루트 디펜던시에 지정한 라이브러리들은 하위 모든 패키지에서 사용이 가능합니다.따라서 필수적이라고 생각하는 라이브러리들만 루트에 설치하여 의존성으로 명시하였습니다.
또한
scripts
도 중요한데,--filter
옵션을 통해 특정 하위 패키지의 명령어로 해당 커멘드를 제한시킬 수 있습니다. 이 말은 즉슨 그냥pnpm add react
를 한다면 에러가 발생해요. 왜냐하면 내가 루트에 특정 라이브러리를 설치할 것이라면pnpm add react -w
커멘드를 사용해야 해요. 루트뿐만 아니라 하위의 다른 패키지들이 존재하기 때문에 어느 패키지에서 설치할 것인지를 명시해주어야 합니다.라고 한다면
client
라는 하위 패키지에react
를 설치하겠다 라는 의미입니다. 따라서 루트의package.json
스크립트에 특정 하위 패키지에 쉽게 커맨드를 입력할 수 있도록scripts
를 만들어두었습니다.위의 커맨드는 다음과 같아요
라고 입력한다면
client
패키지에 리액트가 설치되게 됩니다.만약 특정 패키지에 다른 워크스페이스 내의 패키지를 설치하고 싶다면 다음과 같이 명령하면 됩니다.
이렇게 입력한다면
client
라는 패키지에@tiki/tsconfig
라는 워크스페이스 내 패지키를 설치하겠다는 것입니다. 설치 후package.json
을 보면 다음과 같아요.즉 워크스프에스 내에 있는
@tiki/tsconfig
라는 패키지를dev
의존성으로 설치했다라는 의미입니다.2️⃣ 각 패키지 세팅
pnpm init
을 통해 특정 디렉토리에package.json
을 생성해줄 수 있어요. 그렇다면 이때부터 해당 디렉토리는 하나의 패키지로 사용할 수 있게 됩니다.apps/client
가 기존의 티키 프로덕트에요. 특정 패키지의 패키지명은package.json
의 "name" 프로퍼티 값입니다.apps/landing
에는 랜딩 프로덕트를 개발할 예정이에요. SEO 최적화를 위해서next
로 개발할 예정이기 때문에,next
초기 세팅을 해주었습니다.3️⃣ tsconfig 설정
가장 애먹었던 부분입니다. 해당 패키지가 어떻게 타입스크립트 환경에서 컴파일될 것인지, 모듈을 어떻게 정의할 것인지 등등을 해당 설정 파일에서 작성해주어야 해요.
일단 패키지 중에
@tiki/tsconfig
를 설정하여 모든 프로덕트 혹은 패키지가 tsconfig 패키지 안에 있는 특정json
파일을 상속하여 사용하도록 하였습니다. 기본은base.json
이에요.tsconfig
의 각 속성에 대해서는 너무 많기도 하고, 아직은 저도 어떤 속성이 다른 속성에 의존성을 갖고 있는지, 세부적인 속성에 대한 정확한 이해를 하고 있지 못한 것 같아서 추후에 정리하여 다시 올리겠습니다.4️⃣ tsup을 통한 번들링
icon
과ui
패키지는tsup
이라는 번들 툴을 사용하였습니다.번들링이라는 것들은 모듈에 필요한 각 파일들을 하나의 파일로 결합하는 행위입니다. 사실 티키라는 프로덕트 안에서만 사용할 패키지라면, 번들링이 필요하지 않을 수도 있을 것이라고 생각했어요. 브라우저에서 다양한 모듈 시스템의 사용을 지원하기 위해 결국 번들링을 하는 것인데, 저희 티키의 메인 서비스에서만 사용할 것이라면 그냥
esmodule
만을 지원하면 되기 때문이에요. (현재 클라이언트 패키지가 es모듈)하지만
icon
과ui
패키지는 추후npm
배포까지 고려하고 싶었습니다. 그렇다면 저희의 아이콘과 UI 패키지를 사용하려는 모든 모듈 시스템을 지원해야 하며 또한 최적화까지 신경써야 할 것이라고 생각했어요. 여기서 최적화는 코드 스플리팅이나 트리쉐이킹과 같은 현대 번들러들이 지원하는 최적화 기능들이에요.따라서
tsup
이라는 번들러를 도입했습니다. 해당 툴을 사용하면cjs
혹은esm
과 같은 다양한 모듈 시스템 지원이 가능하고, 당연히 기존 번들러들이 지원했던 최적화까지 해줄 수 있었어요.5️⃣ 패키지 활용법
tsconfig
와utils
는 기본적으로 그냥 워크스페이스 내의 로컬 의존성이라 해당 패키지에서 작성한 코드들은 바로client
나landing
패키지에서 활용 가능합니다.하지만
icon
과ui
는 기본적으로 빌드 후 생성된dist
폴더를 기준으로 다른 패키지에서 사용하는 것이라, 변경사항이 있다면build
를 해주고 다른 패키지에서 사용해야합니다 !icon
패키지는 먼저svgr
을 통해assets
폴더 내의svg
파일들을src
폴더 아래에 컴포넌트로 만들어주고,generate
명령을 통해index.ts
파일에서export default
처리를 해주어야 합니다. 그 후build
해주고 다른 패키지에서 사용하면 돼요 !!ui
패키지 또한 컴포넌트를 추가/삭제/변경한다면 다시build
해주고 사용하면 됩니다 !build
dist
내에index.js
와 같이 번들된 파일이 생성됨package.json
에서main
과module
프로퍼티에 적혀있듯이 해당 패키지는dist
내의index
파일을 진입점으로 여긴다라는 의미. 즉 다른 패키지에서는 빌드되어 번들링된 해당 파일 코드를 사용하는 것.참고
파일 변경이 너무 많은데 기존 코드 중에는
SideNavBar
컴포넌트만 보시면 될 것 같아요.Item
컴포넌트의 prop 구조를 일부 수정했습니다.각 패키지에서
tsconfig
나package.json
는 기본적으로 확인 부탁드려요 !ui
패키키지와utils
패키지는 기존의 컴포넌트 혹은 훅들을 옮긴 것 뿐입니다.icon
패키지에서는svgr
활용한 거나generateIcon
파일 정도 확인해주시면 감사하겠습니다 !