기술 스택은 다음과 같이 정했습니다.
React.js
TypeScript
React Query
Zustand
Styled Components
평소에 react로 작업할 때 create-react-app
을 사용해 작업했었어서 번들러로 Webpack
을 사용하게 되는데, 코드의 양이 늘어날수록 빌드 속도가 상당히 느려진다는 것을 알았습니다. 이를 해결하기 위해 Vite
를 사용하기로 했습니다.
저는 타입스크립트 템플릿으로 생성할 예정이기 때문에 다음과 같이 생성하였습니다.
npm create vite@latest [프로젝트 명] -- --template react-ts
만약 npm 버전이 6이하라면 다음과 같이 생성해야 합니다.
npm create vite@latest [프로젝트 명] --template react-ts
dependencies
로 설치
axios
@tanstack/react-query
@tanstack/react-query-devtools
react-router-dom
styled-components
eslint-plugin-import
devDependencies
로 설치
eslint-config-prettier
prettier
eslint는 airbnb와 같은 컨벤션이 아닌 직접 컨벤션을 설정해서 사용합니다.(필요없는 규칙들 일일이 off하기 귀찮)
프로젝트 루트 경로에 .eslintrc.cjs
(eslint 설정), .prettierrc
(prettier 설정) 파일을 생성해 줍니다.
.eslintrc.cjs
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'prettier',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh', 'eslint-plugin-import'],
rules: {
'no-var': 'error',
'no-console': ['error', { allow: ['warn', 'error', 'info'] }],
'no-unused-vars': 'error',
'import/order': [
'warn',
{
groups: ['builtin', 'external', 'internal', 'type'],
pathGroups: [
{
pattern: 'react',
group: 'builtin',
position: 'before',
},
{
pattern: '@(?!(.*\\.style$))',
group: 'internal',
position: 'after',
},
{
pattern: '@**/*.style',
group: 'unknown',
position: 'after',
},
],
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
pathGroupsExcludedImportTypes: ['builtin'],
},
],
},
};
rules
의 다른 규칙들은 빌드 시 오류가 나지 않을 만한 것들로 추렸고, import/order
설정에 공을 들였습니다. 위처럼 사용 시 react 관련 모듈 import문은 최상단에 위치하고, 절대경로로 가져오는 import문(style 관련은 최하단!)는 그 뒤에 위치합니다. 또 해당 import문들을 대소문자 구별없이 알파벳순으로 정렬하도록 했습니다.
이렇게 설정 시 규칙없이 어지럽게 섞여있는 import문들을 조금은 가시성있게 정렬할 수 있습니다.
위처럼 어지럽던 import 문이 ctrl+s만 하면???
예쁘게 짜잔
.prettierrc
{
"singleQuote": true, // 작은 따옴표 사용
"semi": true, // 문장 끝에 항상 세미콜론 사용
"useTabs": false, // 탭 대신 공백으로 들여쓰기
"tabWidth": 2, // 탭 당 공백 수 2로 설정
"trailingComma": "all", // 배열, 객체등의 마지막 요소에 콤마가 붙는 것 허용
"printWidth": 120, // 줄바꿈할 길이
"bracketSpacing": true, // 객체 리터럴 대괄호 사이에 공백이 있도록
"arrowParens": "always", // 화살표 함수 매개변수 항상 괄호로 감싸기
"endOfLine": "auto" // 기존 줄 끝을 유지
}
절대경로는 꼭 설정해두는 게 좋습니다! 아래 예시를 보면 단박에 이유를 아실꺼에요..
상대경로 사용 시
import { useUpcomingMovieListQuery } from '../../../../hooks/react-query/use-query-movie-lists';
절대경로 사용 시
import { useUpcomingMovieListQuery } from '@hooks/react-query/use-query-movie-lists';
vite+react+TS로 프로젝트를 생성하면 tsconfig.app.json
vite.config.ts
파일이 루트에 있을겁니다. 이 파일 둘 다에서 본인의 디렉토리 구조대로 절대경로를 설정해주어야 합니다.
tsconfig.app.json
파일 내의 "compilerOptions"
에 다음과 같이 baseUrl
과 paths
를 추가해 줍니다.
"baseUrl": ".",
"paths": {
"@api/*": ["src/api/*"],
"@assets/*": ["src/assets/*"],
"@components/*": ["src/components/*"],
"@constants/*": ["src/constants/*"],
...
"@styles/*": ["src/styles/*"],
"@/*": ["src/*"]
}
vite.config.ts
파일 내의 defineConfig
에서 resolve
에 경로들을 추가해 줍니다.(tsconfig와 동일하게)
resolve: {
alias: [
{ find: '@api', replacement: '/src/api' },
{ find: '@assets', replacement: '/src/assets' },
{ find: '@components', replacement: '/src/components' },
{ find: '@constants', replacement: '/src/constants' },
...
{ find: '@styles', replacement: '/src/styles' },
{ find: '@', replacement: '/src' },
],
},
이번 프로젝트에서 제가 사용할 디렉토리 구조입니다.
api: axios-interceptor 설정 및 axios호출 함수 설정
assets: 이미지, 아이콘들
components: 공용 컴포넌트들
hooks: react-query 상태 관리 hook 및 공용 hook들
pages: 특정 페이지 관련 폴더들 및 index
- 각 페이지 폴더에는 페이지 index파일과 해당 페이지에서만 쓰는 components, utils, hooks, constants들을 각 폴더를 만들어서 만들어서 관리
pages/
├── home/
| ├── components/
| ├── constants/
| ├── hooks/
| └── utils/
└── index.tsx
stores: Zustand 상태 관리
styles: 스타일 관련 파일들. 저는 공용 애니메이션, 생상 팔레트, reset, 글로벌 스타일, 반응형 breakpoint 픽셀 값, 등을 넣어서 사용하고 있습니다.
styles/
├── animation.ts
├── breakpoints.ts
├── colors.ts
├── global.ts
├── myReset.ts
└── zIndex.ts
이제 개발을 시작해 봅시다!