-
Notifications
You must be signed in to change notification settings - Fork 2
shadcn ui을 이용해 UI 개발 생산성 높이기
shadcn/ui는 Vercel의 shadcn이 만든 UI 도구로 **Radix UI(Primitives)**와 Tailwind CSS를 기반으로 하는 Component Collection이다. 여기서 주목할 점은 component library가 아니라 재활용 가능한 component collection이라고 소개했다는 점이다.
This is NOT a component library. It's a collection of re-usable components that you can copy and paste into your apps.
왜 이렇게 말했을까?
그 답은 shadcn/ui에서 [Get Started](https://ui.shadcn.com/docs)를 누르자마자 답을 알 수 있었다. shadcn/ui는 npm을 통해 설치할 수 없다. 즉, 종속성으로 설치하지 말라는 말이다.
shadcn/ui가 이런 방식으로 사용하도록 만든 이유는 바로 사용자에게 코드에 대한 소유권과 제어권을 부여하여 구성 요소를 어떻게 빌드하고 스타일을 지정할지 결정할 수 있도록 만들기 위해서이다.
기존의 전통적인 컴포넌트 라이브러리들은 번들된 소스 코드를 패키지 매니저를 통해 프로젝트 의존성에 추가하여 사용한다. 이와 달리 shadcn/ui는 번들되지 않은 컴포넌트 소스 코드를 프로젝트의 의존성에 추가하지 않고, 말 그대로 복붙해서 컴포넌트 코드를 온전히 사용할 수 있다.
기존의 라이브러리들과 다른 방식으로 사용자가 원하는 컴포넌트만 가져와서 커스텀해서 사용할 수 있기에 “library”가 아닌 “collection”이라고 칭하는 것이다.
- 패키지 사용자 입장: 기존 외부 컴포넌트 라이브러리를 사용할 때 존재하던 커스터마이징 제약, 불필요한 번들 크기 증가와 같은 문제점을 해소할 수 있다. 필요한 컴포넌트만 복붙하고 자유롭게 커스터마이징하여 사용할 수 있다.
- 패키지 제작자 입장: 컴포넌트 커스터마이징 지원, 번들링 및 배포에 대한 부담이 사라진다. 커스텀 컴포넌트를 제작하고, 소스 코드를 어딘가에 올리고, 이를 다운로드할 수 있는 npx script만 제공하면 된다.
https://ui.shadcn.com/docs/installation/vite
shadcn/ui 공식문서를 참고했고, 프로젝트에서 패키지 매니저로 pnpm을 사용하고 있으므로 pnpm을 사용하는 코드로 정리했다.
-
Tailwind CSS 설치 및 Vite와 TS 설정 파일
-
Tailwind와 필요한 의존성들을 설치해준다. 두번째 명령어까지 실행하면
tailwind.config.js
와postcss.config.js
파일이 생성된다.pnpm add -D tailwindcss postcss autoprefixer npx tailwindcss init -p
-
메인 css 파일(ex.
src/index.css
)에 아래의 중요한 헤더들을 추가해준다.@tailwind base; @tailwind components; @tailwind utilities; /* ... */
-
tailwind.config.js
에서 tailwind 템플릿 경로를 구성한다./** @type {import('tailwindcss').Config} */ module.exports = { content: ["./index.html", "./src/**/*.{ts,tsx,js,jsx}"], theme: { extend: {}, }, plugins: [], }
Vite의 현재 버전은 TypeScript 구성을 세 개의 파일로 분할하는데, 그 중 두 개는 편집해야 한다.
tsconfig.json
과tsconfig.app.json
의 compilerOptions에baseUrl
과paths
속성을 추가한다./** tsconfig.json */ { "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ], "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./src/*"] } } }
/** tsconfig.app.json */ { "compilerOptions": { // ... "baseUrl": ".", "paths": { "@/*": [ "./src/*" ] } // ... } }
우선 이 명령어를 실행하여 path를 resolve할 때 에러가 발생하지 않도록 하자.
# (so you can import "path" without error) npm i -D @types/node
그리고 vite.config.ts를 업데이트 해준다.
import path from "path" import react from "@vitejs/plugin-react" import { defineConfig } from "vite" export default defineConfig({ plugins: [react()], resolve: { alias: { "@": path.resolve(__dirname, "./src"), }, }, })
-
위 토글에 있는 설정들이 다 되어 있는 상태라면 아래 단계부터 하면 된다.
pnpm dlx shadcn@latest init
❗모노레포에서는 다음과 같이 워크스페이스 경로를 지정할 수 있다.
pnpm dlx shadcn@latest init -c ./apps/www
components.json
을 설정하기 위해 다음과 같은 질문들이 표시될 것이다.
Which style would you like to use? › New York
Which color would you like to use as base color? › Zinc
Do you want to use CSS variables for colors? › no / yes
-
질문 정리
- Would you like to use TypeScript (recommended)? › no / yes 2- Which style would you like to use? › Default 3- Which color would you like to use as base color? › Slate 4- Where is your global CSS file? › src/index.css 5- Do you want to use CSS variables for colors? › no / yes 6- Are you using a custom tailwind prefix eg. tw-? 7- Where is your tailwind.config.js located? › tailwind.config.js Leave blank if not) › 8- Configure the import alias for components: › @/components 9- Configure the import alias for utils: › @/lib/utils 10- Are you using React Server Components? › no / yes
- 순서대로 아래와 같은 의미를 지닌다.
- TypeScript 사용 여부
- component style (default와 new-work이 존재함)
- 기반 color pallete
- tailwind import 등이 들어갈 global css file
- CSS variable 사용 여부
- 사용하는 tailwind prefix
- tailwind config 위치
- component가 저장될 path
- utils 파일이 저장될 path
- RSC 사용 여부
- 순서대로 아래와 같은 의미를 지닌다.
이건 본인 상황에 맞게 설정하면 된다. 나는 아래와 같이 설정했다. 혹시 color base가 궁금하다면 [여기로](https://ui.shadcn.com/colors)
위 단계까지 하면 더이상 할 건 없다. 이제 필요한 컴포넌트를 가져다 사용하면 된다. 예를 들어 버튼 컴포넌트를 갖고 오고 싶다면 다음과 같이 입력한다.
pnpm dlx shadcn@latest add button
❗모노레포에서의 사용
pnpm dlx shadcn@latest add alert-dialog -c ./apps/www
이 커맨드는 Button
컴포넌트를 프로젝트에 추가해준다. 그러면 아래와 같이 import하여 사용할 수 있다.
import { Button } from "@/components/ui/button"
export default function Home() {
return (
<div>
<Button>Click me</Button>
</div>
)
}
- Mediasoup 포트 매핑 문제
- swagger 같은 응답 코드에 다양한 응답 보여주기
- Sudo가 계속 비밀번호를 요청함
- Docker 이미지가 너무 크다
- Git action에서 도커 이미지 빌드 시간을 단축시켜보자
- Docker compose를 이용해서 메모리 사용률을 줄여보자
- 방송 녹화 시 CPU 과부하 문제를 해결해보자
- Release 브랜치? 너 필요해?
- 로딩이 너무 짧아…!
- NestJS ORM으로 무엇을 사용해야 할까?
- WebRTC를 이용한 1:N 스트리밍 서비스에서 시그널링 서버가 필요할까?
- 실시간 채팅 구현: 인메모리 방식을 선택한 이유
- MySQL 아키텍처 개선: DB 의존성 분리와 서버 역할 명확화
- 브라우저 창이 최소화되면 비디오 송출이 안된다…!
- Mediasoup 기본 개념
- DLTS와 Signaling
- Tell, Don't Ask (TDA) 원칙이란
- VPC(Virtual Private Cloud) 학습 정리
- 순환참조: A 서비스 ‐ B 서비스 vs. A 서비스 ‐ B 레포지토리
- Dto 메서드 전략
- WebRTC란?
- 자바스크립트 패키지 매니저(npm, yarn, pnpm)
- shadcn/ui을 이용해 UI 개발 생산성 높이기
- React 이벤트 핸들러 네이밍(on vs handle)
- React-router-dom의 createBrowserRouter을 사용해보기
- fetch vs axios