logoTomalab
홈블로그소개

Built with Next.js, Bun, Tailwind CSS and Shadcn/UI

ReactTypescript

TypeScript 프로젝트 초기 설정 가이드

Toma
2026년 3월 16일
목차
⚙️ TypeScript 프로젝트 초기 설정 완전 가이드
📦 1. 패키지 설치
🎨 2. .prettierrc
🚫 3. .prettierignore
🔍 4. eslint.config.js
규칙 설명
➕ import 정렬 추가 (선택)
🖥️ 5. .vscode/settings.json
❌ / ✅ 설정 비교
🐶 6. Husky + lint-staged
Husky란?
주요 Hook 종류
lint-staged란?
.husky/pre-commit
package.json — lint-staged 설정
동작 흐름
📋 7. tsconfig.json 체크리스트
🗂️ 8. 설정별 역할 요약
레이어 구조

목차

⚙️ TypeScript 프로젝트 초기 설정 완전 가이드
📦 1. 패키지 설치
🎨 2. .prettierrc
🚫 3. .prettierignore
🔍 4. eslint.config.js
규칙 설명
➕ import 정렬 추가 (선택)
🖥️ 5. .vscode/settings.json
❌ / ✅ 설정 비교
🐶 6. Husky + lint-staged
Husky란?
주요 Hook 종류
lint-staged란?
.husky/pre-commit
package.json — lint-staged 설정
동작 흐름
📋 7. tsconfig.json 체크리스트
🗂️ 8. 설정별 역할 요약
레이어 구조

⚙️ TypeScript 프로젝트 초기 설정 완전 가이드

💡 Next.js / React / Nest.js 등 TypeScript 기반 프로젝트를 새로 시작할 때마다 반복되는 설정을 한번에 정리합니다.


📦 1. 패키지 설치

bash
# Prettier
pnpm add -D prettier

# Tailwind CSS를 사용하는 경우
pnpm add -D prettier-plugin-tailwindcss

# ESLint (Flat Config 기준)
pnpm add -D eslint @eslint/js globals typescript-eslint

# React 프로젝트 추가
pnpm add -D eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-react-refresh

# Prettier와 ESLint 충돌 방지
pnpm add -D eslint-config-prettier

# import 정렬 (선택)
pnpm add -D eslint-plugin-perfectionist

# Git hook
pnpm add -D husky lint-staged
npx husky init

⚠️ ESLint v9부터 Flat Config(eslint.config.js)가 기본입니다. 기존 .eslintrc.* 포맷은 deprecated 되었습니다.


🎨 2. .prettierrc

json
{
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "arrowParens": "always",
  "plugins": ["prettier-plugin-tailwindcss"]
}
옵션값이유
semitrue세미콜론 명시 — 압축 시 ASI 오류 방지
singleQuotefalseJSX 속성은 더블쿼트가 기본 — 일관성 유지
tabWidth2업계 표준, 중첩 코드 가독성
trailingComma"es5"배열/객체 끝 쉼표 — Git diff 최소화
printWidth10080은 너무 좁고 120은 너무 넓음 — 100이 실무 적합
arrowParens"always"매개변수 항상 소괄호 — 일관성
pluginsprettier-plugin-tailwindcssTailwind 클래스 자동 정렬 (사용 시)

🚫 3. .prettierignore

javascript
dist
node_modules
build
*.lock
pnpm-lock.yaml
coverage
.next
.cache
public

✅ *.lock / pnpm-lock.yaml은 자동 생성 파일이므로 반드시 제외하세요. public/은 외부 에셋이나 빌드 결과물이 포함될 수 있어 제외하는 것이 안전합니다.


🔍 4. eslint.config.js

javascript
import js from "@eslint/js";
import prettier from "eslint-config-prettier";
import react from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import { defineConfig, globalIgnores } from "eslint/config";
import globals from "globals";
import tseslint from "typescript-eslint";

export default defineConfig([
  globalIgnores(["dist", "node_modules", "build", ".cache"]),

  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      js.configs.recommended,
      ...tseslint.configs.recommended,
      react.configs.flat.recommended,
      react.configs.flat["jsx-runtime"],
      reactHooks.configs.flat.recommended,
      reactRefresh.configs.vite,
      prettier, // ← 반드시 마지막에!
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
      parserOptions: {
        ecmaFeatures: { jsx: true },
      },
    },
    settings: {
      react: { version: "detect" },
    },
    rules: {
      // React
      "react/react-in-jsx-scope": "off",
      "react/prop-types": "off",

      // TypeScript
      "@typescript-eslint/no-explicit-any": "warn",
      "@typescript-eslint/no-unused-vars": [
        "warn",
        { argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
      ],

      // HMR
      "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],

      // React Compiler 사용 시
      "react-hooks/preserve-manual-memoization": "warn",
    },
  },
]);

규칙 설명

규칙설정이유
react/react-in-jsx-scopeoffReact 17+는 JSX에 import 불필요
react/prop-typesoffTypeScript로 타입 검사하므로 불필요
@typescript-eslint/no-explicit-anywarnerror는 초기 개발 시 너무 엄격 — 점진적 적용
@typescript-eslint/no-unused-varswarn_ 접두사는 의도적 미사용으로 허용
react-hooks/preserve-manual-memoizationwarnReact Compiler 도입 시 false positive 방지

⚠️ **eslint-config-prettier**는 반드시 extends 마지막에 위치해야 합니다. Prettier와 충돌하는 모든 ESLint 포매팅 규칙을 비활성화합니다.

➕ import 정렬 추가 (선택)

source.organizeImports는 TypeScript Language Server 기반으로 미사용 import 제거 + 알파벳 정렬만 합니다. 그룹 구분(react → 외부 라이브러리 → 내부 @/)이 필요하다면 eslint-plugin-perfectionist를 추가하세요.

javascript
import perfectionist from "eslint-plugin-perfectionist";

// rules에 추가
"perfectionist/sort-imports": ["warn", {
  type: "natural",
  order: "asc",
  groups: ["react", "external", "internal", "parent", "sibling", "index"],
}],

🖥️ 5. .vscode/settings.json

json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.formatOnPaste": false,
  "editor.formatOnType": false,

  "editor.tabSize": 2,
  "editor.insertSpaces": true,
  "editor.detectIndentation": false,
  "editor.autoIndent": "full",
  "editor.wordWrap": "on",

  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "explicit"
  },

  "files.eol": "\n",
  "files.insertFinalNewline": true,
  "files.trimTrailingWhitespace": true,

  "eslint.useFlatConfig": true,
  "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],

  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.enablePromptUseWorkspaceTsdk": true
}

❌ / ✅ 설정 비교

항목❌ 피할 설정✅ 권장 설정이유
formatOnPastetruefalse붙여넣기 시 의도치 않은 포매팅 방지
언어별 defaultFormatter각 언어별로 반복 선언전역 설정만 사용전역 defaultFormatter로 커버됨 — 중복 불필요

💡 언어별 defaultFormatter를 각각 명시하는 패턴은 흔히 볼 수 있지만, 전역 editor.defaultFormatter를 이미 설정했다면 중복입니다. [css] 등 특정 언어에서 다른 포매터를 써야 할 때만 오버라이드하세요.


🐶 6. Husky + lint-staged

Husky란?

Husky는 Git Hook을 쉽게 설정할 수 있게 해주는 도구입니다.

Git은 커밋, 푸시 등의 이벤트 전후에 스크립트를 실행할 수 있는 Hook 기능을 기본 제공합니다. 그런데 이 Hook 파일(.git/hooks/)은 git이 추적하지 않아 팀원과 공유가 되지 않습니다.

Husky는 Hook 스크립트를 .husky/ 디렉토리에 저장하고, prepare 스크립트를 통해 pnpm install 시 자동으로 Git Hook에 등록되도록 만들어줍니다.

javascript
.git/hooks/    ← Git이 실제로 실행하는 Hook (공유 불가)
.husky/        ← Husky가 관리하는 Hook 원본 (git 추적, 팀 공유 가능)

주요 Hook 종류

Hook실행 시점주요 용도
pre-commitgit commit 직전lint, format, 테스트
commit-msg커밋 메시지 작성 후커밋 메시지 컨벤션 검사
pre-pushgit push 직전전체 테스트, 빌드 검증

lint-staged란?

lint-staged는 git add로 staged된 파일에만 lint/format을 실행합니다.

Husky의 pre-commit에서 eslint .을 직접 실행하면 프로젝트 전체 파일을 검사하므로 느립니다. lint-staged를 사용하면 현재 커밋에 포함된 파일만 검사해서 속도를 크게 줄일 수 있습니다.

✅ Husky (언제 실행할지) + lint-staged (무엇을 실행할지) = 빠르고 안전한 pre-commit

.husky/pre-commit

bash
pnpm lint-staged

package.json — lint-staged 설정

json
{
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "eslint --fix --no-warn-ignored",
      "prettier --write"
    ]
  }
}

동작 흐름

javascript
git commit
  └─ Husky pre-commit
       └─ lint-staged (staged 파일만 대상)
            ├─ eslint --fix    → 자동 수정 가능한 lint 오류 수정
            └─ prettier --write → 포매팅 통일

💡 --no-warn-ignored 플래그는 globalIgnores에 포함된 파일이 staged될 때 경고를 숨깁니다.


📋 7. tsconfig.json 체크리스트

json
{
  "compilerOptions": {
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  }
}
옵션권장값이유
stricttruestrictNullChecks, strictFunctionTypes 등 전체 활성화
noUnusedLocalstrueESLint no-unused-vars와 이중 방어
noUnusedParameterstrue함수 시그니처 정리 강제

⚠️ strict: true로 설정했다면 ESLint의 @typescript-eslint/no-explicit-any를 error로 올리는 것도 고려하세요.


🗂️ 8. 설정별 역할 요약

파일역할적용 시점
.prettierrc코드 스타일 규칙 정의저장 시 / 커밋 시
.prettierignore포매팅 제외 경로항상
eslint.config.js코드 품질 규칙 정의저장 시 / 커밋 시
.vscode/settings.jsonIDE에서 위 설정을 자동 실행저장 시 (IDE 레이어)
.husky/pre-commit커밋 시 lint-staged 실행커밋 시 (Git 레이어)
package.json lint-stagedstaged 파일에만 lint/format 실행커밋 시
tsconfig.json컴파일 타임 타입 검사빌드 시 / IDE 실시간

레이어 구조

javascript
[ 개발 중 ]     VSCode settings.json
                  → formatOnSave (Prettier)
                  → codeActionsOnSave (ESLint fix + organizeImports)

[ 커밋 시 ]     Husky pre-commit
                  → lint-staged
                       → eslint --fix
                       → prettier --write

[ 빌드 시 ]     tsc (tsconfig strict)
                  → 타입 오류 최종 검증

✅ IDE 설정 없이 다른 에디터를 사용하는 팀원도 커밋 시점에는 동일한 품질 기준이 강제됩니다.