vite로 리액트 프로젝트 생성
Vite란?
모던 웹 프로젝트 개발 환경에 초점을 맞춰 탄생한 빠르고 간결한 빌드 툴
다시 말해 프론트엔드 개발용 빌드 도구, 개발할 때 빠르게 화면에 반영되게 도와줌
전통적인 방식(예 : Webpack)보다 시작 속도와 변경 반영 속도가 훨씬 빠른 것이 특징이다.
사이트 참조 : https://ko.vite.dev/
Vite
Vite, 프런트엔드 개발의 새로운 기준
ko.vite.dev
깃허브 참조 : https://github.com/vitejs/vite
GitHub - vitejs/vite: Next generation frontend tooling. It's fast!
Next generation frontend tooling. It's fast! Contribute to vitejs/vite development by creating an account on GitHub.
github.com
React 프로젝트 생성 시 npx create-react-app과 Vite의 차이
1️⃣ 목적
| 항목 | create-react-app | Vite |
| 개발용 빌드 도구 | 내장(Webpack 기반) | 별도(Vite 자체 빌드) |
| 속도 | 느림 (특히 시작 시, HMR 느림) | 빠름 (Hot Module Replacement 즉시 반영) |
| 최신 문법 지원 | 오래된 설정 때문에 최신 JS/TS 기능 바로 사용 불편 | 최신 ES 모듈 기반, 최신 JS/TS 바로 사용 가능 |
2️⃣ 설치 및 프로젝트 생성 속도
- CRA (create-react-app)
- 프로젝트 생성 후 node_modules 설치가 꽤 오래 걸림
- Webpack과 Babel 등 여러 패키지를 함께 설치
- 개발 서버 시작까지 시간이 비교적 김
- Vite
- 프로젝트 생성이 매우 빠름
- 불필요한 번들링 없이 ES 모듈 기반 개발 서버 사용 → 변경 즉시 반영
3️⃣ 설정과 커스터마이징
| Webpack 설정 | 숨겨져 있음 (react-scripts 내부) | 설정 파일 vite.config.js 직접 사용 가능 |
| 설정 확장성 | ejected 해야 함 → 복잡 | 플러그인으로 쉽게 확장 |
| Typescript 지원 | 가능하지만 옵션 선택 필요 | 지원 내장, 바로 선택 가능 |
4️⃣ Hot Reload & Dev 서버
- CRA: 변경 사항 반영 조금 느릴 수 있음, 전체 번들 재생성 발생
- Vite: ES 모듈 기반이라 변경된 모듈만 즉시 반영, 거의 실시간
5️⃣ 한눈에 보는 비교
| 설치 속도 | 느림 | 매우 빠름 |
| 개발 서버 | 느림 | 매우 빠름 |
| 최신 JS/TS 지원 | 제한적 | 최신 기능 지원 |
| 설정 커스터마이징 | 어렵거나 ejected 필요 | 쉽고 유연 |
| 추천 시점 | 레거시 프로젝트나 안정성 우선 | 새 프로젝트, 빠른 개발 경험 원할 때 |
npm init vite로 리액트 프로젝트를 만들었다 =
Vite를 기반으로, 바로 개발할 수 있는 React 앱 뼈대를 만들어준 것
npm init vite
Project name:
│ ./
│
◇ Select a framework:
│ React
│
◇ Select a variant:
│ TypeScript
│
◇ Use rolldown-vite (Experimental)?:
│ No
│
◇ Install with npm and start now?
│ Yes
구조 생성
※ 상태관리 라이브러리 종류
: Redux, Mobx, Zustand, Recoill, React Context
컴포넌트 생성
리액트 컴포넌트 사용 : tsx
그냥 타입스크립트 사용 : ts
※ES7+ React/Redux/React-Native snippets : 익스텐션 다운로드
- 리액트 템플릿 자동완성 스니펫
- 참조 : https://github.com/r5n-labs/vscode-react-javascript-snippets/blob/HEAD/docs/Snippets.md
중요한 패키지들 설치하기
@reduxjs/toolkit
redux
clsx : className 동적만들기
@vanilla-extract/css : 타입스크립트에서의 css 쓰기
@vanilla-extract/css-utils
@vanilla-extract/vite-plugin
react-icons : 리액트 아이콘
uuid : 유니크 아이디 만들기
react-beautiful-dnd : 드롭다운리스트 라이브러리
➡️ React 19에서 지원하지 않음. @hello-pangea/dnd 로 대체
react-redux
리덕스 사용을 위한 준비
리덕스 개념과 사용법 Slice와 reducer
2025.11.17 - [프레임워크\라이브러리/React] - [라이브러리] 상태관리 라이브러리 Redux
[라이브러리] 상태관리 라이브러리 Redux
리덕스란?Redux란 상태 관리 라이브러리(선택사항)로 State, Props 상태를 여러 컴포넌트와 공유할 때 쓴다.앱이 커지면 관리 힘들어지고 소스코드 지저분해지는데 이름 방지하고 효율적인 관리를
thinktank911.tistory.com
슬라이스(Slice) 만들기 - modalSlice.ts
modalSlice.ts
- type만 import 시에는 import type으로 import 해야 한다.
import { ITask } from "../../types";
➡️ import type { ITask } from "../../types";
import { createSlice } from "@reduxjs/toolkit";
import type { ITask } from "../../types";
type TModalState = {
boardId: string;
listId: string;
task: ITask;
}
const initialState : TModalState = {
boardId : "board-0",
listId : "list-0",
task: {
taskId: "task-0",
taskName: "task 0",
taskDescription: "task description",
taskOwner: "kyj"
}
}
const modalSlice = createSlice({
name : 'modal',
initialState,
reducers: {
}
})
export const ModalReducer = modalSlice.reducer;
ITask 타입만들기
- types/intex.ts
export interface ITask {
taskId: string;
taskName: string;
taskDescription: string;
taskOwner: string;
}
export default : 경로만 맞으면 어떤 이름으로도 가져올 수 있다. {} 안 씀
export 차이 : export한 이름으로만 {} 안으로 가져와야 함
Reducer 컨바인 하기
- 만들어놓은 모든 Slice의 Reducer를 한군데에 모아 reducer로 export하기
- store/reducer/reducer.ts
import { boardsReducer } from "../slices/boardsSlice";
import { loggerReducer } from "../slices/loggerSlice";
import { ModalReducer } from "../slices/modalSlice";
const reducer = {
logger: loggerReducer,
boards: boardsReducer,
modal: ModalReducer
}
export default reducer;
- Redux 스토어 생성
- Redux 어플리케이션의 모든 상태(데이터)를 저장하는 단 하나의 중앙저장소
- configureStore 함수로 Redux 스토어 생성
- reducer.ts 에서 합친 reducer를 reducer로 받기
- getState()로 상태를 읽고, dispatch(action)으로 상태를 업데이트하며, subscribe(listener)로 상태 변화 감지
- store/index.ts
import { configureStore } from "@reduxjs/toolkit";
import reducer from "./reducer/reducer";
const store = configureStore({
reducer
})
export default store;
슬라이스(Slice) 만들기 - boardsSlice.ts
boardsSlice.ts
import { createSlice } from "@reduxjs/toolkit";
import type { IBoard } from "../../types";
type TBoardsState = {
modalActive: boolean;
boardArray: IBoard[]
}
const initialState : TBoardsState = {
modalActive: false,
boardArray: [
{
boardId: 'board-0',
boardName: "첫 번째 게시물",
lists: [
{
listId: 'list-0',
listName: "List 1",
tasks: [
{
taskId: "task-0",
taskName: "Task 1",
taskDescription: "Description",
taskOwner: "kyj",
},
{
taskId: "task-1",
taskName: "Task 2",
taskDescription: "Description",
taskOwner: "kyj",
},
]
},
{
listId: 'list-1',
listName: "List 2",
tasks: [
{
taskId: "task-3",
taskName: "Task 3",
taskDescription: "Description",
taskOwner: "kyj",
}
]
}
]
}
]
}
const boardsSlice = createSlice({
name: 'boards',
initialState,
reducers: {
}
})
export const boardsReducer = boardsSlice.reducer;
IBoard, IList 타입 만들기
export interface IBoard {
boardId : string;
boardName : string;
lists: IList[];
}
export interface IList {
listId: string;
listName: string;
tasks: ITask[];
}
리덕스 Hooks 생성
- 타입스크립트에서 useSelector와 useDispatch를 쓸 때 state와 action에 대한 타입을 커스텀 훅으로 지정해줘야 한다.
- store/index.ts
- RootState와 AppDispatch의 타입 생성
import { configureStore } from "@reduxjs/toolkit";
import reducer from "./reducer/reducer";
const store = configureStore({
reducer
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch;
export default store;
- hooks/redux.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import { AppDispatch, RootState } from "../store";
export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector
export const useTypeDispatch = () => useDispatch<AppDispatch>();
2025.11.17 - [프레임워크\라이브러리/React] - [Redux] 리덕스 Hooks 생성
[Redux] 리덕스 Hooks 생성
1️⃣ 기본 개념: useSelector와 useDispatch useSelector()리덕스 스토어에 있는 상태 데이터 가져올 때 쓰는 훅 예:const count = useSelector(state => state.counter.value);여기서 문제는 TypeScript를 쓰면 state의 타입을
thinktank911.tistory.com
※ 제너릭 타입 사용법
interface Obj<T>{
name: T;
}
interface State {
state: {
data: string,
loading: boolean
}
}
const obj: Obj<State> = {
name : {
state: {
data: 'abcd',
loading: false
}
}
}
전역 스타일 생성
vite.config.ts에 플러그인 셋팅
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), vanillaExtractPlugin()],
})
App.css.ts 생성
- App.tsx 스타일을 위한 파일 생성
- createGlobalTheme, style 을 @vanilla-extract/css 에서 호출
import { createGlobalTheme, style } from "@vanilla-extract/css";
export const vars = createGlobalTheme(":root", {
color: {
main: "#ffa726",
mainDarker: "#f57c00",
mainFaded: "#ffb74d",
mainFadedBright: "#ffb74da6",
list: "rgb(235, 236, 240)",
task: "rgb(255, 255, 255)",
taskHover: "rgb(245, 245, 245)",
brightText: "rgb(255, 255, 255)",
darkText: "rgb(24, 42, 77)",
seconarDdarkText: "rgb(94, 108, 132)",
seconarDdarkTextHover: "rgb(218, 219, 226)",
selectedTab: "rgb(137, 176, 174)",
updateButton: "rgb(237, 180, 88)",
deleteButton: "rgb(237, 51, 88)",
},
fontSizing: {
T1: "32px",
T2: "24px",
T3: "18px",
T4: "14px",
P1: "12px",
},
spacing: {
small: "5px",
medium: "10px",
big1: "20px",
big2: "15px",
listSpacing: "30px"
},
font: {
body: "arial",
},
shadow: {
basic: "4px 4px 8px 0px rgba(34, 60, 80, 0.2)"
},
minWidth: {
list: '250px'
}
})
export const appContainer = style({
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
height: 'max-content',
width: '100vw'
})
export const board = style({
display: 'flex',
flexDirection: 'row',
height: '100%',
})
export const buttons = style({
marginTop: 'auto',
paddingLeft: vars.spacing.big2
})
App.tsx에 스타일 적용
import { appContainer, board, buttons } from './App.css'
function App() {
return (
<div className={appContainer}>
<div className={board}></div>
<div className={buttons}>
<button>이 게시판 삭제하기</button>
<button>활동목록 보이기 </button>
</div>
</div>
)
}
export default App'프로젝트 > Task 어플리케이션' 카테고리의 다른 글
| 1120 Firebase로 배포하기 (0) | 2025.11.21 |
|---|---|
| 1120 드래그 앤 드롭 기능 만들기 (0) | 2025.11.20 |
| 1119 EditModal, LoggerModal, LogItem 컴포넌트 생성, 게시판 삭제 기능 (0) | 2025.11.19 |
| 1118 Board List 생성, Side Form 생성, Style 생성 - vanilla extract (0) | 2025.11.18 |