절대경로를 사용해서 React 경로 깔끔하게 정리하기

허재원·2022년 12월 25일
1
post-custom-banner

haoshop-refactoring

개인 프로젝트 리팩토링 시작!🚀

오늘부터 본격적으로 쇼핑몰 프로젝트 HAO Shop을 리팩토링해보려고 한다. 첫 스타트가 중요하다고 아래처럼 매번 다른 경로에서 컴포넌트들을 불러오기 보다는 절대 경로를 설정하고 한 파일로 경로를 묶어 경로를 깔끔하게 정리하려고 한다.

절대경로 설정

JavaScript의 경우에는 jsconfig.json에 루트폴더를 설정할 수 있다. 해당 파일을 생성하고, 다음처럼 루트폴더를 설정하면 절대경로 작성 시src폴더에서부터 경로를 찾는다.

// jsconfig.json
{
	"compilerOptions": {
		"baseUrl": "src"
    }
}

tsconfig.json

나의 경우에는 TypeScript로 프로젝트를 진행하려 하기 때문에(긴장..😨) tsconfig.json에 절대경로를 설정하였다.

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    // ...
    "baseUrl": "src"
  },
  "include": [
    "src"
  ]
}

index.ts에 경로 지정

기존 프로젝트의 경로 상태

import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import Layout from "./components/Layout";
import ProtectedRoute from "./components/ProtectedRoute";
import ScrollToTop from "./components/ScrollToTop";
import ForgotPassword from "./pages/auth/forgotPassword/ForgotPassword";
import ResetPassword from "./pages/auth/resetPassword/ResetPassword";
import Signin from "./pages/auth/signin/Signin";
import Signup from "./pages/auth/signup/Signup";
import Brand from "./pages/brand/Brand";
import Cart from "./pages/cart/Cart";
import Checkout from "./pages/checkout/Checkout";
import Collection from "./pages/collections/collection/Collection";
import Collections from "./pages/collections/Collections";
import Contact from "./pages/etc/contact/Contact";
import Missing from "./pages/etc/missing/Missing";
import Success from "./pages/etc/success/Success";
import UnAuthorized from "./pages/etc/unauthorized/Unauthorized";
import Home from "./pages/home/Home";
import Lookbook from "./pages/lookbooks/lookbook/Lookbook";
import Lookbooks from "./pages/lookbooks/Lookbooks";
import Addresses from "./pages/mypage/addresses/Addresses";
import Mypage from "./pages/mypage/Mypage";
import Profile from "./pages/mypage/profile/Profile";
import Order from "./pages/mypage/orders/order/Order";
import Orders from "./pages/mypage/orders/Orders";
import Product from "./pages/product/Product";
import Search from "./pages/search/Search";
import Shopping from "./pages/shopping/Shopping";
import Stripe from "./pages/stripe/Stripe";
import { ROLES } from "./utils/roleList";
import Reviewables from "./pages/mypage/reviewables/Reviewables";
import Reviews from "./pages/mypage/reviews/Reviews";
import ReviewForm from "./pages/mypage/reviews/submit/ReviewForm";
import Review from "./pages/mypage/reviews/review/Review";
import Kakao from "./pages/auth/kakao/Kakao";

function App() {
  return (
    <Router>
      <ScrollToTop />
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="search/:keyword" element={<Search />} />
          <Route path=":slug/:cid" element={<Shopping />} />
          <Route path="brands/:name" element={<Brand />} />
          <Route path="collections" element={<Collections />} />
          <Route path="collections/:id" element={<Collection />} />
          <Route path="lookbooks" element={<Lookbooks />} />
          <Route path="lookbooks/:id" element={<Lookbook />} />
          <Route path="products/:id" element={<Product />} />
          <Route path="cart" element={<Cart />} />
          <Route path="contact" element={<Contact />} />
          <Route element={<ProtectedRoute allowedRoles={[ROLES.USER]} />}>
            <Route path="checkout" element={<Checkout />} />
            <Route path="success" element={<Success />} />
            <Route path="mypage/" element={<Mypage />}>
              <Route path="orders" element={<Orders />} />
              <Route path="orders/:id" element={<Order />} />
              <Route path="reviewables" element={<Reviewables />} />
              <Route path="reviews" element={<Reviews />} />
              <Route path="reviews/:id" element={<Review />} />
              <Route path="reviews/submit" element={<ReviewForm />} />
              <Route path="addresses" element={<Addresses />} />
              <Route path="profile" element={<Profile />} />
            </Route>
          </Route>
        </Route>
        <Route element={<ProtectedRoute allowedRoles={[ROLES.USER]} />}>
          <Route path="/stripe" element={<Stripe />} />
        </Route>
        <Route path="/signin" element={<Signin />} />
        <Route path="/signup" element={<Signup />} />
        <Route path="/kakao/callback" element={<Kakao />} />
        <Route path="/forgot_password" element={<ForgotPassword />} />
        <Route path="/reset_password/:resetToken" element={<ResetPassword />} />
        <Route path="/unauthorized" element={<UnAuthorized />} />
        <Route path="*" element={<Missing />} />
      </Routes>
    </Router>
  );
}

export default App;

그대로 가져와봤지만 어지럽다..😅 이걸 하나의 경로로 정리하면 좋을까 생각하다 이번 리팩토링을 통해 정리해보자!

components/index.ts

처음부터 다시 만들다보니 일단 Layout컴포넌트부터 시작해보자!

// components/common/Layout
import { Outlet } from 'react-router-dom';

export const Layout = () => {
  return <Outlet />;
};
export * from 'components/common/Layout';
// ...

components에 여러 폴더 및 파일들을 만들고 index.ts에 다음과 같이 export * from './common/Layout으로 다시 모듈을 내보내면 Router.ts에서는 아래처럼 깔끔하게 경로가 지정되고 앞으로 컴포넌트 생성하면 이 과정을 따르면 된다.

// routes/Routes.ts
import { Layout } from 'components';
import { Home } from 'pages';
import { BrowserRouter, Route, Routes } from 'react-router-dom';

const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route element={<Layout />}>
          <Route index element={<Home />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
};

export default Router;

위에 보는 것처럼 각기 다른 파일 경로를 가졌던 것과는 달리 componentsindex.ts에서 불러오기만 하면 되니 하나의 경로에서 컴포넌트들을 관리할 수 있게 되었다! 거기다 절대경로를 src로 설정하여 components 또는 pages로 경로를 설정하면 된다..! 깔끔하다..!!

폴더 구조

- 📂src
	- 📂components
    	- 📂common
        	- 📂Layout
            	- index.tsx
        - index.ts
    - 📂pages
    	- 📂Home
        	- index.tsx
        - index.ts
    - 📂routes
    	- Router.tsx
	- App.tsx
    - index.tsx

나중에는 PublicRoutes와 PrivateRoutes로 따로 파일을 만들어 분리해보자!

export default로 모듈을 내보내는 경우

export * from './common/Layout'가 아닌
export { default * Layout } from './common/Layout으로 작성해주어야 한다.

post-custom-banner

0개의 댓글