ESLint는 코드의 정확성과 일관성을 자동으로 지켜주는 도구이며, AI가 코드를 대량 생산하는 시대일수록 품질의 마지노선 역할을 한다.
ESLint란 무엇인가
-
자바스크립트는 동적 타입 언어로, 실행하기 전까지 오류를 알기 어려운 특성이 있다.
-
그래서 개발자가 실수로 선언하지 않은 변수를 쓰거나, 사용하지 않는 변수를 남겨도 실행 시점에서야 문제가 드러난다.
-
또한 팀 단위 협업에서는 사람마다 코드 스타일이 달라, 따옴표 종류나 세미콜론 사용 같은 사소한 부분에서 충돌이 자주 발생했다.
-
이런 문제를 해결하기 위해 등장한 것이 정적 분석 도구이며, 그중 가장 널리 쓰이는 것이
ESLint이다. -
ESLint는 코드를 실행하지 않고도 문법적 오류와 잠재적 버그, 스타일 위반을 미리 잡아주는 린터(Linter)이다. -
즉, 코드를 작성하는 순간 “이 코드는 규칙에 어긋난다”라고 알려주는 자동 코드 검사기 역할을 한다.
ESLint의 작동 방식
-
ESLint는 코드를 문자열이 아닌 AST(Abstract Syntax Tree, 추상 구문 트리)로 변환해 분석한다. -
즉, 코드를 단순 텍스트가 아니라 구조로 이해하기 때문에 “이 변수는 선언만 되고 사용되지 않았다” 같은 의미 단위 검사가 가능하다.
-
설정 파일(
.eslintrc,eslint.config.js등)에 어떤 규칙을 적용할지 정의하면, 그 규칙대로 코드를 검사한다. -
규칙 위반 시
error,warn,off세 가지 수준으로 경고를 표시한다.
React에서 ESLint 사용하기
-
React 프로젝트에서는 기본
ESLint규칙만으로는 부족하므로, React 전용 플러그인을 함께 사용한다. -
대표적으로
eslint-plugin-react,eslint-plugin-react-hooks,@typescript-eslint/eslint-plugin이 자주 쓰인다. -
Vite나Create React App같은 도구는 설치 시 기본ESLint설정을 함께 제공한다. -
설정 파일은 보통 아래와 같은 구조로 작성한다.
// eslint.config.js export default [ { plugins: { react, // React 관련 규칙을 사용하기 위한 플러그인 등록 'react-hooks': reactHooks, // React Hooks 규칙을 사용하기 위한 플러그인 등록 }, rules: { 'react/jsx-uses-react': 'off', // React 17+ 에서는 JSX 사용 시 React import가 불필요하므로 끔 'react/react-in-jsx-scope': 'off', // 위와 같은 이유로 'React가 스코프에 있어야 한다'는 규칙도 끔 'react-hooks/rules-of-hooks': 'error', // 훅을 조건문/반복문 안에서 호출하면 에러 처리 (호출 순서 보장) 'react-hooks/exhaustive-deps': 'warn', // useEffect 등의 의존성 배열 누락 시 경고 표시 }, }, ]; -
위 설정에서
react/react-in-jsx-scope를 끈 이유는, React 17 이후로 JSX를 쓰기 위해import React를 명시하지 않아도 되기 때문이다.
실무에서 자주 쓰는 규칙
-
첫 번째로
react-hooks/rules-of-hooks는 훅을 조건문이나 반복문 안에서 호출하지 못하게 막는다. -
이 규칙은 React의 Hook 호출 순서 보장을 위해 반드시
error수준으로 둔다.// 잘못된 예 - 조건부 훅 호출 function Component({ flag }) { if (flag) { const [count, setCount] = useState(0); // ESLint error } } -
두 번째로
react-hooks/exhaustive-deps는useEffect같은 훅의 의존성 배열이 누락되지 않았는지 검사한다. -
이 규칙 덕분에 “의존성에 빠진 변수 때문에 발생하는 stale closure” 같은 버그를 사전에 막을 수 있다.
useEffect(() => { fetchUser(userId); }, [userId]); // userId가 빠지면 ESLint가 경고함 -
세 번째로
no-unused-vars는 사용되지 않는 변수를 잡아낸다. -
TypeScript 환경에서는 동일한 역할을 하는
@typescript-eslint/no-unused-vars를 대신 쓰는 것이 정확하다. -
네 번째로
react/jsx-key는 리스트 렌더링 시key속성을 빠뜨리지 않도록 강제한다.items.map((item) => <li key={item.id}>{item.name}</li>); -
다섯 번째로
no-console은 배포 코드에console.log가 남는 것을 방지한다. -
보통 개발 중에는
warn, 배포 직전에는error로 단계적 운영을 한다.
Prettier와의 관계
-
ESLint는 코드의 “정확성”을 검사하고,Prettier는 코드의 “모양”을 정리한다. -
두 도구의 역할이 겹치는 부분이 있으므로,
eslint-config-prettier를 함께 설치해 충돌을 막는 것이 일반적이다. -
즉, 포맷팅은
Prettier에 맡기고, 논리적 검사만ESLint가 담당하도록 분리한다.
AI 시대에 Lint의 중요성
-
최근에는 ChatGPT, Claude 같은 AI 도구가 코드를 직접 작성해주는 시대가 되었다.
-
그래서 “이제는 린트가 필요 없는 것 아닌가?”라는 의문이 생길 수 있다.
-
그러나 오히려 AI 시대에 린트의 중요성은 더욱 커졌다.
-
첫째, AI가 만든 코드는 그럴듯해 보이지만 잘못된 패턴이나 사용하지 않는 import, 잘못된 의존성 배열 같은 미세한 오류를 포함하기 쉽다.
-
사람이 일일이 검수하기 어려운 양의 코드가 생성되므로, 자동화된 검사가 필수가 된다.
-
둘째, AI는 프로젝트의 컨벤션을 완벽히 따르지 않을 수 있다.
-
ESLint설정은 “이 프로젝트는 이런 규칙을 따른다”라는 명시적 기준이 되어, AI 결과물을 프로젝트 스타일로 정렬시키는 가드레일 역할을 한다. -
셋째, AI 코드 생성의 신뢰성을 검증하는 첫 단계가 정적 분석이다.
-
테스트 코드가 잡지 못하는 영역, 예컨대 타입 추론 오류나 React 훅 규칙 위반을 사전에 차단하는 역할을 한다.
-
넷째, AI에게 더 좋은 코드를 요구하기 위한 피드백 루프로도 쓰인다.
-
린트 결과를 다시 AI에게 입력하면, AI가 스스로 코드를 수정해 품질을 점진적으로 높일 수 있다.
-
결국 AI가 코드를 “쓰는” 시대일수록, 사람은 “검증과 기준 설정”에 집중해야 하며, 그 중심에
ESLint같은 정적 분석 도구가 존재한다.