프론트 초기 프로젝트 세팅
서론
이글은 리엑트, 넥스트, 타입스크립트, 테일윈드를 사용하는 프론트 협업 초기 기본셋팅에 대해 다룹니다.
- 조직생성 및 프로젝트 생성
- eslint 및 prettier 설정
- 허스키 설정
- 깃헙 pr템플릿 설정
- 깃헙 default 브랜치 설정
package.json
조직생성
프론트 FE 레포지 생성
프로젝트 생성
리엑트, 넥스트, 타입스크립트 ,테일윈드
npx create-next-app@latest my-project --typescript --tailwind --eslint
위의 명령어를 입력시 다음의 프로젝트 옵션 설정 물음이 나옵니다.
1. Would you like your code inside a `src/` directory? » No / Yes
NO
my-project/
├── app/
├── components/
├── pages/
├── styles/
└── public/
YES
my-project/
├── src/
│ ├── app/
│ ├── components/
│ ├── pages/
│ └── styles/
└── public/
2. Would you like to use App Router? (recommended) » No / Yes
넥스트 앱라우터 와 페이지라우터 중 택1 선택.
3. Would you like to use Turbopack for `next dev`? » No / Yes
Turbopack은 Rust로 작성된 새로운 번들러로, Webpack의 후속작으로 Vercel이 개발 중
next dev (개발 서버)에서의 주요 차이:
No (Webpack 사용)
- 안정적이고 검증된 번들러
- 모든 기능이 완벽하게 지원됨
- 상대적으로 느린 개발 서버 시작과 HMR(Hot Module Replacement)
Yes (Turbopack 사용)
- Webpack보다 훨씬 빠른 개발 서버 시작 (700배까지)
- 더 빠른 HMR
- 아직 베타 단계로 일부 기능이 불안정할 수 있음
- 특정 npm 패키지나 설정과 호환성 문제가 있을 수 있음
현재는 프로덕션 용도가 아닌 개발 서버(next dev)에만 적용되는 옵션
4. Would you like to customize the import alias (`@/*` by default)? » No / Yes
파일경로 설정관련
NO(기본)
import { Button } from '@/components/Button'
import { useAuth } from '@/hooks/useAuth'
YES - 원하는 prefix로 커스텀 가능
import { Button } from '#/components/Button'
import { useAuth } from '#/hooks/useAuth'
기본값인 @/*가 업계 표준처럼 많이 사용되고 있어서, 특별한 이유가 없다면 No 선택
초기 프로젝트 생성
린트설정
npm install -D @eslint/eslintrc @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y eslint-config-prettier eslint-plugin-prettier
@eslint/eslintrc - ESLint의 설정 파일을 다루는 기본 패키지
@typescript-eslint/parser -TypeScript 코드를 ESLint가 이해할 수 있게 해주는 파서
@typescript-eslint/eslint-plugin - TypeScript 관련 린팅 규칙을 제공하는 플러그인
eslint-plugin-react - React 관련 린팅 규칙을 제공 / JSX 문법 검사 등 React 특화 규칙 포함
eslint-plugin-react-hooks - React Hooks 관련 규칙을 검사/ Hooks의 의존성 배열 체크 등
eslint-plugin-jsx-a11y - 웹 접근성(accessibility) 관련 규칙을 제공 / JSX 요소들의 접근성 검사
eslint-config-prettier - ESLint와 Prettier 간의 충돌을 방지 / Prettier와 충돌할 수 있는 ESLint 규칙을 비활성화
eslint-plugin-prettier- Prettier를 ESLint 규칙으로 실행할 수 있게 해줌 / 코드 포맷팅을 ESLint 실행 시 함께 처리
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import { FlatCompat } from '@eslint/eslintrc';
import tsParser from '@typescript-eslint/parser';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
import typescriptPlugin from '@typescript-eslint/eslint-plugin';
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
import prettierPlugin from 'eslint-plugin-prettier';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: {},
});
const eslintConfig = [
{
ignores: ['node_modules/', 'dist/', 'public/'],
},
...compat.extends(
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended',
'plugin:prettier/recommended',
'next/core-web-vitals',
),
{
files: ['**/*.{js,jsx,ts,tsx}'],
languageOptions: {
parser: tsParser,
parserOptions: {
ecmaVersion: 2023,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
project: './tsconfig.json',
},
},
plugins: {
react: reactPlugin,
'react-hooks': reactHooksPlugin,
'@typescript-eslint': typescriptPlugin,
'jsx-a11y': jsxA11yPlugin,
prettier: prettierPlugin,
},
rules: {
'prettier/prettier': ['error', { endOfLine: 'auto' }],
'react/jsx-filename-extension': [
'warn',
{ extensions: ['.tsx', '.jsx'] },
],
'@typescript-eslint/no-unused-vars': [
'warn',
{
args: 'after-used',
varsIgnorePattern: '^_',
},
],
'jsx-a11y/label-has-associated-control': [
'error',
{
required: { some: ['nesting', 'id'] },
},
],
'no-console': 'warn',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'react/jsx-no-useless-fragment': 'warn',
},
settings: {
react: {
version: 'detect',
},
},
},
{
files: ['*.tsx', '*.jsx'],
rules: {
'@typescript-eslint/no-use-before-define': 'off',
},
},
];
export default eslintConfig;
프리티어 설정
npm install -D prettier prettier-plugin-tailwindcss @trivago/prettier-plugin-sort-imports
prettier
- 코드 포맷터
- 일관된 코드 스타일을 자동으로 적용
- 들여쓰기, 줄바꿈, 따옴표 등의 스타일을 자동으로 정리
prettier-plugin-tailwindcss
- Tailwind CSS 클래스를 정리해주는 Prettier 플러그인
- Tailwind 클래스의 순서를 일관되게 정렬
- 공식 권장 순서대로 클래스를 자동 정렬해줌
@trivago/prettier-plugin-sort-imports
- import 구문을 자동으로 정렬해주는 Prettier 플러그인
- import 문을 그룹화하고 알파벳 순으로 정렬
- 일관된 import 순서를 유지하도록 도와줌
{
"singleQuote": true,
"semi": true,
"useTabs": false,
"tabWidth": 2,
"printWidth": 80,
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "lf",
"plugins": ["prettier-plugin-tailwindcss"],
"importOrder": [
"^@utils/(.*)$",
"^@apis/(.*)$",
"^@hooks/(.*)$",
"^@recoils/(.*)$",
"^@pages/(.*)$",
"^@base/(.*)$",
"^@common/(.*)$",
"^@components/(.*)$",
"^@styles/(.*)$",
"^[./]"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true
}
husky 설정
허스키란? Husky는 Git hooks를 쉽게 관리할 수 있게 해주는 도구
일반적인 사용 사례:
- 커밋하기 전에 자동으로 lint 검사
- 코드 포맷팅 실행
- 테스트 실행
패키지 설치
npm install -D husky lint-staged
허스키 초기화
npx husky-init
그러면 터미널에
Ok to proceed? (y) 엔터
이제 husky 성공적으로 설정. git Commit 전에 실행될 훅 설정가능
++ 스크립트 및 린트 스테이지드 설정(package.json)
"prepare": "husky install" // 다른 개발자들이 클론 후 자동으로 husky 설치
{
"name": "my-project",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint:fix": "eslint --fix \"**/*.{js,jsx,ts,tsx}\"",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx}\"",
"prepare": "husky install"
},
"dependencies": {
"next": "14.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3.0.0",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"eslint": "^8.56.0",
"eslint-config-next": "14.1.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^9.0.7",
"lint-staged": "^15.2.0",
"postcss": "^8",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.11",
"tailwindcss": "^3.4.1",
"typescript": "^5"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint --fix"
]
}
}
허스키 pre-commit
허스키 설치후 최상단에 .husky폴더 내에 pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
이렇게 설정하면:
- 커밋할 때마다 변경된 ts, tsx 파일들에 대해
- ESLint로 코드 검사 및 자동 수정
- Prettier로 코드 스타일 정리 가 자동으로 실행
깃헙 pr 템플릿 설정
(이슈템플릿은 jira에서 관리)
.github/pull_request_template.md
# 🎯 PR 내용
## 작업 내용
<!-- 작업 내용을 상세히 설명해주세요 -->
## 스크린샷
### 작업 결과물
<!-- 실제 구현 화면을 캡쳐해주세요 -->
### 관련 이슈
<!-- JIRA 이슈의 스크린샷을 첨부해주세요 -->
## ✅ PR 포인트
### 리뷰어 참고사항
<!-- 리뷰어가 참고해야 할 내용을 작성해주세요 -->
-
### 중점 리뷰 요소
<!-- 중점적으로 리뷰받고 싶은 부분을 작성해주세요 -->
-
## 🔍 관련 이슈
<!-- 연결된 이슈 번호를 작성해주세요 -->
close #
깃헙 조직 레포 연결하기
하기전에~ 경고 하나만 처리
warning: in the working copy of 'eslint.config.mjs', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'package-lock.json', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'package.json', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of '.husky/pre-commit', LF will be replaced by CRLF the next time Git touches it
이는 Windows와 Linux/Mac의 줄바꿈 문자(line ending) 차이 때문에 발생하는 경고
- Windows는 CRLF (Carriage Return + Line Feed)
- Linux/Mac은 LF (Line Feed) 를 사용
현재 프로젝트에 적용하기위해 git 설정 변경
git config core.autocrlf true
해당 명령어를 실행하면
- 파일을 Git에 넣을 때 (commit할 때): CRLF -> LF로 자동 변환
- 파일을 Git에서 가져올 때 (checkout할 때): LF -> CRLF로 자동 변환
- .git/config 파일에 다음 설정이 추가됨:
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hooksPath = .husky
autocrlf = true <------
다시 레포지 연결
git add .
git commit -m "커밋메시지"
(허스키돌고)
git remote add origin 조직레포지주소
git branch -M main
git push -u origin main
프로젝트 생성은 끝
dev 레포지 및 브랜치 설정
# 로컬에서 dev 브랜치 생성 및 푸시
git checkout -b dev
git push -u origin dev
그리고 깃헙 settings로 이동
브랜치 룰 설정
네이밍은 데브 프로텍션하고, 활성화시켜주고, default브랜치로 설정. (현재 dev가 default)
필자는 지정된 인원 승인후 머지설정 옵션
Require a pull request before merging 하위 옵션 설명
Dismiss stale pull request approvals when new commits are pushed
- 새로운 커밋이 푸시되면 이전 승인들을 모두 초기화
- 변경된 코드에 대해 새로운 리뷰를 강제할 수 있음
Require review from Code Owners
- 특정 파일에 지정된 코드 오너의 승인이 필수
- CODEOWNERS 파일에 정의된 담당자의 리뷰 필요
Require approval of the most recent reviewable push
- 가장 최근 푸시한 코드는 푸시한 본인이 아닌 다른 사람의 승인이 필요
- 자신의 코드를 자신이 승인할 수 없게 함
Require conversation resolution before merging
- PR의 모든 코드 리뷰 대화가 해결되어야 머지 가능
- 열려있는 토론이나 의견이 없어야 함
Request pull request review from Copilot
- 새 PR이 생성되면 자동으로 Copilot에게 리뷰 요청
- Copilot 코드 리뷰 접근 권한이 있는 사용자에게만 적용
Allowed merge methods
PR 머지 시 허용할 방법 선택
- Merge: 일반적인 머지 (모든 커밋 히스토리 유지)
- Squash: 여러 커밋을 하나로 압축
- Rebase: 커밋을 한 줄로 정리
- 최소 하나는 선택해야 함
마지막으로 브랜치 병합시 브랜치 삭제
sttings 하단에
초기 설정 끝