앞서 기획에서 단순하게 사용만하겠다고 했는데 실제로 어떻게 사용해야할지는 찾아봐야한다.
tailwindcss관련 세팅은 next가 알아서 해줘서 딱히 건든건 없었고,
ShadCN 일단 설치
pnpm add shadcn/ui
이 과정에서 ShadCN이 ui관련 컴포넌트라는 사실을 알게 되었고,
바로 사용할 수 없었다.
프로젝트에 특정 컴포넌트를 추가하는 추가 설정이 필요했는데,
shadcn/ui
를 설치한다고 바로 사용이 불가했다
그래서 좀 더 알아본 ShadCN/ui는
Radix UI 및 Tailwind CSS를 사용해 구축된 '재사용' 가능한 컴포넌트.
컴포넌트 라이브러리가 아닌 앱에 copy and past하여 재사용 가능한 구성요소 모음
따로 pnpm add 하여 종속성 설치를 하진 않음
그렇다면 내 해석상 tailwind를 검색해서 가져오는 것처럼 이것도 비슷한 느낌이지 않을까 싶은데..?
shadcn가 tailwind css 시스템을 도입하고 있고 호환성이 좋아서이다!
공식문서에서는
이렇게 설치하라고 했는데 나는 pnpm만 사용하므로
pnpm add shadcn-ui@latest init
이렇게 추가하니 앞서 shancn/ui로 설치했을땐 package.json에 저장이 안되었는데 이젠 저장이 되었다.
이후 컴포넌트 제이슨 파일을 만들라는 것 같아서 추가해주었고,
너무 직관적으로 도입해서 에러가 떴다 ㅎㅎㅎ
그래서 gpt 도움을 받아
{
"useTypeScript": "no",
"style": "Default",
"baseColor": "Slate",
"globalCSS": "app/globals.css",
"useCSSVariables": "no",
"tailwindConfig": "tailwind.config.js",
"importAlias": {
"components": "@/components",
"utils": "@/lib/utils"
},
"usingReactServerComponents": "no"
}
이런식으로 넣었는데,
나는 typescript를 사용할건데 no? 처음부터 내 프로젝트의 성격상 그냥 무지성으로 도입하는건 좋지 않다 느꼈고,
그냥 공식문서의 3개 정도만 추가시키기로 결정하였다.
{
"style": "Default",
"baseColor": "Slate",
"useCSSVariables": "no"
}
style은 기본 스타일
baseColor 는 Slate - 선택된 색상
useCSSVariables - 색상에 CSS 변수 사용할지? no
여기서 CSS 변수는
:root {
--primary-color: #3498db; /* 블루 색상 */
--secondary-color: #2ecc71; /* 그린 색상 */
--font-size: 16px; /* 기본 글꼴 크기 */
}
이런식으로 어떤 색상을 변수화 시킨다는 의미인데,
하나하나 다 지정해주면 날 샐것같으니 no가 맞는것같다
이후 tailwind와 같이 사용하기 위해
content에 shadCN 컴포넌트 경로 추가
//tailwind.config.ts
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
"./node_modules/shadcn-ui/dist/**/*.{js,ts,jsx,tsx}", // ShadCN 경로 추가
],
theme: {
extend: {
backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"gradient-conic":
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
},
},
},
plugins: [],
};
export default config;
그 다음에 글꼴 설정을 해줘야하는데,
layout.tsx의 폰트 설정과 CSS 클래스를 조정하라고 나와있다.
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
이게 기존 루트레이아웃이였다면
// src/app/layout.tsx
import "@/styles/globals.css";
import { Inter as FontSans } from "next/font/google";
import { cn } from "@/lib/utils"; // `cn` 함수는 클래스 이름을 결합하는 유틸 함수
const fontSans = FontSans({
subsets: ["latin"],
variable: "--font-sans",
});
export default function RootLayout({ children }: RootLayoutProps) {
return (
<html lang="en" suppressHydrationWarning>
<head />
<body
className={cn(
"min-h-screen bg-background font-sans antialiased",
fontSans.variable
)}
>
{children}
</body>
</html>
);
}
이렇게 FontSans와 cn을 변경해서,
오케이 그러면 components.json의
useCSSVariables를 yes로 바꿔서 사용할 수 있도록 바꾸자
근데
이전에 세팅해놓은 alias 때문에 가져오는 방식에 문제가 있었던 것 같다.
근데 그냥 src안에 lib과 utils 파일이 없어서 이것또한 생성해줘야하는 문제인 것 같다... 처음쓰는건 너무 어려워 ㅠㅠ
src/lib/utils.ts 파일 만들어주고
export function cn(...classes: (string | undefined | false)[]) {
return classes.filter(Boolean).join(' ');
}
이 문구를 넣어주는건 왜 공식문서에서 안알려주는데? ;;
저 내용은 cn함수가 일반적으로 클래스 이름을 조건에 따라 결합해주는 함수
나중에 쓰면서 익숙해지면 될듯
근데 애초에 생각해보면
여기서 YES 즉, 절대경로 사용하려고 customize하려고만했고 세팅을 안해줬기 때문에,
baseUrl - 기본 디렉토리 경로 설정
paths - @/ 경로 별칭을 ./src/로 매핑해서 @/로 시작하는 경로를 src/ 디렉토리 내의 파일로 변환
를 추가해준다.
{
"compilerOptions": {
"baseUrl": ".", //추가
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"] //이미추가되어잇넹
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
이제 나는 절대 경로를 사용할 것이기 때문에
src/lib/utils.ts에 export function 을 가져온다치면
import { cn } from "@/lib/utils"; // 절대경로 사용
@ 로 src에 접근해서 바로 뽑아올 수 있다 상대경로 아니여도
이후 제대로 노드모듈스 적용하려고
rm -rf node_modules
pnpm install
지웠다 재설치했는데,
확실히 진짜 빠르다 pnpm install이 ㄷㄷ
근데??
어휴 머가 이리 오류가 많이 뜨냐 ;;
이 부분을 위해서
types에 tailwindcss 추가 해도
에러는 계속되어있음
그래서 말이 안된다 에러가 생길 수 없는 구조다 생각해서
껏다 켰더니 해결 ㅎㅎㅎㅎ 개짜증나네
이제 버튼 한번 컴포넌트 가져와서 사용해봅시다~!
공식문서 참고해서
src/components/ui/button.tsx
에서 저렇게 선언하니까 바로 안되고 있음
type에 대해서 문제가 있는 듯 함
그래서 src/types/shadcn-ui.d.ts에서
해당 코드 선언해주니
이젠 Button이 없다
그래서 공식 홈페이지에서
pnpm add shadcn-ui@latest add button
로 해도 계속 형식 선언을 찾을 수 없다고 떠서
pnpm과 호환성에 문제가 있다고 생각해
어쩔 수 없이 npx로 설치하였다
npx
node.js 패키지를 일회성으로 실행할 수 있게 해주는 도구
약간 yarn, npm, pnpm과 다른 역할로 생각됨
패키지를 글로벌로 설치하지 않고 명령어를 한번만 실행할 때 사용하는 도구
npx shadcn-ui@latest add button
결국 이걸로 해도 에러가 떠서
직접 src/components/ui에 button.tsx
파일 만들어서 선언해줬더니
제대로 button에 대해서 import해졌고,
현재 이런 에러가 뜨고 있음
찾아보니 globals.css가 src 바로 밑에 있지 않고 src/app 안에 있는 파일이라서 에러가 떳었음 그래서
@/app/globals.css 로 import해서 해결!
이젠 해결했더니 이런 에러가 뜸
이건 다행히 client component 에서 버튼을 사용할 수 있는 것이므로
'use client'
클라이언트 컴포넌트로 사용하겠다 라고 해서
겨우 겨우 진짜 겨우 완성...ㅋㅋㅋ;;
언제 해 이래서 ㅋㅋㅋㅋ
이제 대충 shadCN은 사용해보면서 익히고
진짜 진행해보자
멋있어요~