ESLint (Flat Config) 세팅 정리
Vite + React + TypeScript 프로젝트에서 코드 스타일을 통일하고, 팀/개인 작업에서 실수 방지를 위해 ESLint를 설정했다.
Flat Config란?
ESLint 설정을 정리하다 보니, 현재 방식은 Flat Config라고 불린다는 것을 알게 되었다.
기존 .eslintrc 방식과 무엇이 다른지는 글 하단에서 비교 정리했다.
Flat Config는 ESLint의 새로운 설정 방식으로, 기존 방식보다 명시적이고 예측 가능한 구조를 제공하며 파일 단위로 규칙을 세밀하게 제어할 수 있다.
사용한 플러그인/패키지
@eslint/js: ESLint 기본 추천 규칙typescript-eslint: TS 문법/타입 관련 규칙eslint-plugin-react-hooks: Hooks 규칙 강제eslint-plugin-react-refresh: Vite HMR(리프레시) 관련 규칙eslint-config-prettier: Prettier와 충돌하는 ESLint 규칙 비활성화eslint-plugin-simple-import-sort: import/export 정렬eslint-plugin-unused-imports: 사용하지 않는 import/변수 정리@tanstack/eslint-plugin-query: TanStack Query 실수 방지
최종 eslint.config.ts 예시
export default defineConfig([
// 린트 대상 제외
globalIgnores(['dist', 'node_modules']),
{
// TS/TSX 파일만 적용
files: ['**/*.{ts,tsx}'],
// 기본 추천 규칙 + prettier 충돌 방지
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
prettier,
],
// JS 환경 설정
languageOptions: {
ecmaVersion: 2020,
sourceType: 'module',
globals: globals.browser,
},
// 플러그인 등록
plugins: {
react,
'react-hooks': reactHooks,
'simple-import-sort': simpleImportSort,
'unused-imports': unusedImports,
'@tanstack/query': query,
},
// React 버전 자동 감지
settings: {
react: {
version: 'detect',
},
},
// 규칙: 목적별로 묶어서 관리
rules: {
// Import 정리
'simple-import-sort/imports': 'warn',
'simple-import-sort/exports': 'warn',
// 사용하지 않는 import/변수 제거
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
// JS 기본 안정성
'no-var': 'error',
'prefer-const': 'warn',
'no-unused-vars': 'off',
// TypeScript
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
// TanStack Query
'@tanstack/query/exhaustive-deps': 'error',
'@tanstack/query/no-unstable-deps': 'error',
// React 기본 설정
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
'react/jsx-uses-react': 'off',
// Vite HMR 최적화
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
// console / debugger 기본
'no-console': ['warn', { allow: ['warn', 'error'] }],
'no-debugger': 'warn',
},
},
]);왜 이런 규칙들을 넣었나?
Prettier 충돌 방지 (eslint-config-prettier)
Prettier는 포맷터고, ESLint는 규칙 검사 도구다.
둘이 겹치는 규칙이 있으면 서로 고치면서 충돌이 날 수 있기 때문에, eslint-config-prettier로 충돌 규칙을 비활성화했다.
import 정렬 + unused 제거 자동화
simple-import-sort: import/export 순서 정리unused-imports: 쓰지 않는 import / 변수 정리
이 두 개를 같이 쓰면 PR에서 정리 코멘트가 줄고, 코드가 항상 일정한 형태를 유지한다.
TanStack Query 규칙(실수 방지)
린트 설정을 찾아보는 과정에서 전용 ESLint 플러그인이 있다는 것을 알게 되어 함께 적용했다.
특히 다음 두 규칙은 공식 문서와 여러 블로그에서 “초기에 꼭 켜두면 좋은 규칙”으로 추천되고 있어서 error로 설정했다.
'@tanstack/query/exhaustive-deps': 'error',
'@tanstack/query/no-unstable-deps': 'error',이 규칙들을 error로 둔 이유는, queryKey나 의존성 누락 문제가 초반에는 잘 드러나지 않다가
캐싱이 꼬이면서 디버깅이 매우 어려워지기 때문이다!
기존 방식 vs Flat Config
기존 방식 (.eslintrc)
{
"extends": ["eslint:recommended"],
"plugins": ["react"],
"rules": {
"no-console": "warn"
}
}문제점
- 설정 파일이 여러 개로 분산될 수 있다.
.eslintrc.js.eslintrc.json.eslintrc.ymlpackage.json내부 설정
- 플러그인/설정이 암묵적으로 로드된다.
- 경로 해석이 복잡하다.
- TypeScript 지원이 설정에 따라 불안정한 경우가 많다.
Flat Config 방식 (eslint.config.js / eslint.config.ts)
export default defineConfig([
{
files: ['**/*.{ts,tsx}'], // 특정 파일만 적용
rules: {
'no-console': 'warn',
},
},
{
files: ['**/*.test.ts'], // 파일 타입별로 규칙을 다르게 줄 수 있음
rules: {
'no-console': 'off',
},
},
]);특징
- 배열 형태로 설정을 명시적으로 관리
- 파일 타입별로 규칙을 다르게 적용하기 쉽다.
- 플러그인/설정이 자동 로딩이 아니라 직접 import 방식이다.
장점
Flat Config는 ESLint의 차세대 설정 방식으로, 기존 .eslintrc 방식보다 명시적이고 예측 가능한 구조를 제공한다.
특히 Vite + TypeScript 환경에서 설정 충돌을 줄이고, 파일별 규칙 적용을 세밀하게 제어할 수 있다는 장점이 있다.