[React] 프로젝트 초기 세팅하기

DoHyeon Kim·2026년 1월 2일

React

목록 보기
1/15
post-thumbnail

리액트로 웹 개발을 하기 위해 프로젝트를 생성하고 초기 세팅을 진행해야 한다. 아마 개발이 처음인 경우에는 어디에서부터 어떻게 진행해야 할지 몰라 막막할 수 있는데, 이런 분들에게 조금이나마 도움이 되고자 예전에 진행했던 프로젝트의 초기 세팅 방식을 공유하려고 한다.

해당 프로젝트의 기술 스택은

  • 언어: JavaScript
  • 스타일링: Styled-Components
  • 상태 관리: Redux

위와 같이 진행되므로, 프로젝트 세팅 시 참고하기 바란다.

Repository 생성 후 clone

우선 프로젝트 생성을 위해 깃허브에서 리포지토리를 하나 생성한다.
필요한 내용들을 입력 후 Create Repository 버튼을 클릭해 리포지토리를 생성하고,
VS코드로 돌아와 다음 명령어로 방금 생성한 리포지토리를 클론 한다.

git clone https://github.com/ehgus0526/Test-Project.git

그럼 다음과 같이 깃허브 리포지토리와 로컬 환경이 연결된 것을 확인할 수 있다.

React 프로젝트 생성

다음 명령어로 리액트 프로젝트를 생성한다.

npm create vite@latest

명령어를 입력하면 여러 옵션 선택 질문이 나오는데, 본인 상황에 맞춰 세팅을 진행하면 된다. 나는 다음과 같이 세팅했다.
모든 옵션을 설정하면 프로젝트 빌드가 실행되는데, 초기 화면은 다음과 같을 것이다.
이로써 프로젝트 설치 및 실행은 완로되었다. 하지만 우리는 이 화면을 그대로 사용할 수 없으니, 이제 헤더가 존재하는 보편적인 웹 뷰의 레이아웃까지 구현해보자.

필요한 라이브러리 설치

웹 개발에 필요한 기능들을 위해 최소한의 라이브러리를 설치한다.

# styled-components
npm i styled-components
# router
npm i react-router-dom
# redux
npm i redux react-redux @reduxjs/toolkit
# axios
npm i axios
# icon
npm i vite-plugin-svgr --save-dev
# font
npm i @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons @fortawesome/free-brands-svg-icons

.gitignore 파일 수정

프로젝트 최상위에 특정 파일의 git 추적을 방지하기 위한 .gitignore 파일이 존재할 텐데, 이를 다음과 같이 보완한다.

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

# Build artifacts
node_modules
dist
dist-ssr
*.local
.env
*.env

# DS_Store
.DS_Store
._.DS_Store
**/.DS_Store
**/._.DS_Store

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

vite.config.js 수정

svg 사용을 위해 vite.config.js 파일을 다음과 같이 수정한다.

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import svgr from 'vite-plugin-svgr';

// https://vitejs.dev/config/
export default defineConfig({
		plugins: [react(), svgr()],
})

폴더 구조 확립

안정적인 협업을 위해선 폴더 구조를 확립하여 정리해 놓는 것이 좋다. 해당 프로젝트에선 다음과 같이 폴더 구조를 잡았다.

/Test-Project
├── /node_modules
├── /public
│   └── logo.svg
├── /src
│   ├── /assets
│   │   ├──/font
│   │   ├──/icons
│   │   └──/images
│   ├── /components
│   │   ├── /common
│   │   │   ├── Footer.jsx
│   │   │   └── Header.jsx
│   │   ├── /loginPage
│   │   ├── /mainPage
│   │   └── ...
│   ├── /features
│   │   ├── /auth
│   │   │   ├── authSlice.js
│   │   │   ├── LoginForm.jsx
│   │   │   └── ...
│   │   ├── /posts
│   │   │   ├── postsSlice.js
│   │   │   └── ...
│   │   └── ...
│   ├── /hooks
│   │   ├── useAuth.js
│   │   └── useDevice.js
│   ├── /layout
│   │   └── MainLayOut.jsx
│   ├── /pages
│   │   ├── LoginPage.jsx
│   │   ├── MainPage.jsx
│   │   └── ...
│   ├── /store
│   │   └── store.js
│   ├── App.jsx
│   ├── main.jsx
│   └── ...
├── .gitignore
├── index.html
├── package.json
├── README.md
└── vite.config.js

위 폴더 구조의 핵심 폴더들은 각각 다음과 같은 기능을 한다.

  • assets: 프로젝트 전반에서 재사용되는 이미지·아이콘·폰트 등 정적 리소스 관리
  • components: 도메인별 UI 컴포넌트 관리
  • features: 기능 담당 파일 관리
  • hooks: 공통으로 사용 가능한 커스텀 훅 로직 관리
  • layout: 페이지 구조(레이아웃) 관련 파일 관리
  • pages: 실제 라우팅 되는 화면 단위 파일 관리
  • store: 전역 상태의 루트 스토어 설정 및 중앙 관리

MainPage, Header 구현

이제 본격적으로 UI 작업을 진행해 보자. 우선 MainPageHeader를 구현한다.

// src/pages/MainPage.jsx

import styled from "styled-components";

function MainPage() {
    return (
        <PageWrapper>
            // 내용 추가
        </PageWrapper>
    );
};

export default MainPage;

// CSS
const PageWrapper = styled.div`
    color: white;
`;
// src/components/common/Header.jsx

import styled from "styled-components";
import LogoImg from "../../assets/images/common/logo.png"; // 로고 이미지는 임의로 저장
import { useNavigate } from "react-router-dom";

function Header() {
    // navigate
    const navigate = useNavigate();
    
    return (
        <HeaderWrapper>
            <StyledLogoImg src={LogoImg} alt="logo image" onClick={() => navigate("/")}/>
            <ButtonWrapper>
                <Button onClick={() => navigate("/")}></Button>
                <Button onClick={() => navigate("/board")}>게시판</Button>
                <Button onClick={() => navigate("/mypage")}>마이페이지</Button>
                <Button onClick={() => navigate("/login")}>로그인</Button>
            </ButtonWrapper>
        </HeaderWrapper>
    );
};

export default Header;

// CSS
const HeaderWrapper = styled.div`
	position: fixed;
    padding: 0 3em;
    width: 100%;
    height: 6em;
    display: flex;
    justify-content: space-between;
    align-items: center;
    z-index: 100;
    box-sizing: border-box;
`;

const StyledLogoImg = styled.img`
    height: 5.3125em;
    cursor: pointer;
`;

const ButtonWrapper = styled.div`
    height: 5.3125em;
    line-height: 5.3125em;
    display: flex;
`;

const Button = styled.div`
    margin-left: 4em;
    font-size: 1.375em;
    cursor: pointer;
`;

MainLayout 구현

웹 페이지의 전체적인 레이아웃을 잡을 MainLayout을 구현해준다.

// src/layout/MainLayout.jsx

import { Outlet } from "react-router-dom";
import Header from "../components/common/Header";
import styled from "styled-components";

function MainLayout() {
    return (
        <>
            <Header/>
            <ContentWrapper>
                <Outlet/>
            </ContentWrapper>
        </>
    );
};

export default MainLayout;

// CSS
const ContentWrapper = styled.div`
    padding-top: 6em;  // 헤더 높이만큼 작성
`;

main.jsx, App.jsx, App.css, index.css 수정

프로젝트 최상위에 존재하는 기존 전역 구조 관련 파일들을 프로젝트 구조에 맞춰 수정한다.

// main.jsx

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
import './index.css';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { store } from './store/store.jsx';

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <BrowserRouter>
      <Provider store={store}>
        <App />
      </Provider>
    </BrowserRouter>
  </StrictMode>
)
// App.jsx

import './App.css';
import { Routes, Route } from "react-router-dom";
import MainLayout from './layout/MainLayout';
import MainPage from './pages/MainPage';

function App() {
  return (
    <Routes>
      {/* 메인 레이아웃 적용 */}
      <Route element={<MainLayout/>}>
        
        {/* 메인 페이지 */}
        <Route path="/" element={<MainPage/>} />
        
        {/* 로그인 페이지 */}
        <Route path="/login" element={<MainPage/>} />

        {/* 위치 페이지 */}
        <Route path="/location" element={<MainPage/>} />

        {/* 숙련도 페이지 */}
        <Route path="/level" element={<MainPage/>} />

        {/* 장르 페이지 */}
        <Route path="/genre" element={<MainPage/>} />

        {/* 게시판 페이지 */}
        <Route path="/board" element={<MainPage/>} />

        {/* 마이 페이지 */}
        <Route path="/mypage" element={<MainPage/>} />

      </Route>
    </Routes>
  )
}

export default App;
/* App.css */

#root {
  width : 100%;
  height : 100%;
  margin: 0 auto;
}
/* index.css */

body {
  width : 100%;
  height : 100%;
  margin: 0 auto;
  position: relative;
  overflow-x: hidden;
  background-color: #F4F4F5;

	/* 스크롤 설정 */
  &::-webkit-scrollbar {
    width: 8px;
    height: 8px;
    background: none;
  }
  &:hover::-webkit-scrollbar-thumb {
      border-radius: 30px;
      background-color: darkgray;
  }
}

store 파일 생성

Redux를 통한 전역 상태 관리를 위해 store 파일을 생성한다.

// src/store/store.jsx

import { configureStore } from "@reduxjs/toolkit";

export const store = configureStore({
	reducer: {
    	// 내용 추가
	},
});

구현 결과

여기까지 진행한다면 다음과 같은 결과가 나오게 된다.
초기 화면보다 좀 더 보편적인 웹 페이지 느낌의 화면이 만들어졌다. 이렇게 해서 리액트 프로젝트 초기 세팅을 진행해 보았다. 예전에 작성해 놓은 내용이라 프로젝트 구조나 코드에서 수정해야 할 부분이 많이 보이긴 하지만, 리액트를 처음 접해보는 입문자들에게 조금이나마 도움이 되길 바란다.

profile
끄적끄적

0개의 댓글