린트는 사실 그동안 GPT나 팀원들이 세팅해준 설정을 그대로 가져다 쓰는 경우가 많았다.
예전에 한 번 린트를 전혀 사용하지 않고 프로젝트를 진행한 적이 있었는데,
그때는 코드 포맷이 조금만 어긋나도 직접 줄 맞추고, 띄어쓰기 하나하나 신경 쓰느라 꽤 스트레스를 받았다.
그 경험 덕분에 자동 줄바꿈과 포맷팅의 소중함을 제대로 느꼈다.
그래서 이번 프로젝트에서는 필수는 아니지만, 미래의 내가 이 글을 보고 다시 프로젝트를 세팅할 수 있기를 바라며 린트 설정 과정을 정리해두려고 한다.
eslint ⊂ lintereslint-plugin-react@typescript-eslinteslint-config-airbnb npm i -D lint-staged
lint-staged는 커밋하려는 파일만 선택적으로 lint/format을 실행하는 라이브러리다.
커밋 전에 변경된 파일에 대해서만 린트를 실행하도록 설정한다!
#!/bin/sh
npx lint-staged
import typescriptEslint from '@typescript-eslint/eslint-plugin'
import typescriptParser from '@typescript-eslint/parser'
import prettier from 'eslint-config-prettier'
import globals from 'globals'
export default [
{
ignores: ['.next/', 'out/', 'build/', 'next-env.d.ts'],
},
{
files: ['**/*.{js,jsx,ts,tsx}'],
languageOptions: {
parser: typescriptParser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
},
plugins: {
'@typescript-eslint': typescriptEslint,
},
rules: {
...typescriptEslint.configs.recommended.rules,
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['error'],
'no-console': 'error',
},
},
// 브라우저
{
files: ['**/*.{jsx,tsx}'],
languageOptions: {
globals: globals.browser,
},
},
// Node / 서버
{
files: ['**/*.{js,ts}'],
languageOptions: {
globals: globals.node,
},
},
prettier,
]
한 줄씩 알아보기
프로젝트에서 타입스크립트를 사용할 예정이기 때문에 typescriptEslint, typescriptParser를 import해야한다.
typescriptEslint → TypeScript 전용 ESLint 플러그인으로 TS 문법에 대한 규칙을 제공한다
typescriptParser → Eslint가 TypeScript 코드를 파싱할 수 있게 도와주는 파서이다. 이 설정이 없으면 eslint는 ts문법을 이해하지 못한다.
prettier → ESLint와 Prettier 충돌 방지용 설정을 도와준다! 포맷팅 관련 eslint 규칙은 전부 꺼준다.
export default → 배열의 각 객체가 하나의 설정 블록이다.
export default 작성순서
1. eslint 검사에서 완전히 제외할 파일/폴더는 ignores배열에 넣어준다.
- 해당 파일들은 린트를 돌릴 필요 없는 자동 생성 파일들이다.
```jsx
{
ignores: ['.next/', 'out/', 'build/', 'next-env.d.ts'],
},
```
- `.next/` : Next.js 빌드 결과물
- `out/` : next export 결과
- `build/` : 빌드 산출물
- `next-env.d.ts` : Next가 자동 생성하는 타입 파일
2. ESLint 검사 대상 파일 지정한다
JS / TS 관련 파일에 대해서만 린트를 실행한다.
files: ['**/*.{js,jsx,ts,tsx}']
3. languageOptions 을 설정한다
languageOptions 는 ESLint가 코드를 어떤 언어 환경으로 해석할지 여부이다.
languageOptions: {
parser: typescriptParser,
parserOptions: {
ecmaVersion: 'latest', // 최신 JS 문법 허용
sourceType: 'module', // import / export 사용
},
},
4. ESLint 규칙을 설정한다
rules: {
...typescriptEslint.configs.recommended.rules,
'no-unused-vars': 'off', // JS 기본 no-unused-vars은 끔
'@typescript-eslint/no-unused-vars': 'error', // 사용하지 않는 변수 있으면 에러 처리
'no-console': 'error', // 콘솔로그 있으면 에러
},
no-unused-vars 를 끄는 이유no-unused-vars 는 순수 JavaScript 기준으로 만들어져, TypeScript 환경에서는 중복 오류를 발생하는 경우가 많다.no-console 에러로 처리한 이유5. 브라우저 설정한다
{
files: ['**/*.{jsx,tsx}'],
languageOptions: {
globals: globals.browser,
},
},
리액트 컴포넌트처럼 브라우저에서 실행되는 코드에 대한 설정이다!
languageOptions을 통해 window ,document ,fetch , location 등을 전역 객체로 허용한다.
```jsx
window.location.href // OK
process.env.NODE_ENV // 에러
```
6. Node / 서버 설정한다
{
files: ['**/*.{js,ts}'],
languageOptions: {
globals: globals.node,
},
},
API routes, 서버 컴포넌트, 설정 파일처럼 Node.js 환경에서 실행되는 코드들을 대상으로 한다.
process, __dirname, Buffer)를 허용한다.eslint.config.mjs 에서 브라우저와 서버 설정을 나눈 이유
실제 실행 환경이 다르기 때문에 섞이면 린트가 제대로 동작하지 않는다.
Next.js는 서버와 클라이언트 코드가 한 프로젝트 안에 공존한다.
환경을 나누지 않으면 클라이언트 컴포넌트에서 잡아야 할 에러를 린트가 놓칠 수 있다.
// 클라이언트 컴포넌트인데 이렇게 쓰면 에러나는데 린트는 통과된다.
console.log(process.env.SECRET_KEY)
lint-staged 설치만 하면 아무 일도 안 일어난다
⇒ 어떤 파일에 어떤 명령을 실행할지 스스로 작성해야된다!
그래서 package.json에 다음과 같이 설정을 추가했다.
{
"name": "hinkor",
"version": "0.1.0",
"private": true,
"scripts": {
/// 생략
},
"dependencies": {
/// 생략
},
"devDependencies": {
/// 생략
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"**/*.{json,css,md}": [
"prettier --write"
]
}
}
커밋하려는 파일 중 →js, ts, tsx , jsx 가 있으면 자동으로 eslint 수정 → prettier 포맷
json, css, md 은 prettier만 실행된다이렇게 설정한 이유
자바스크립트 / 타입스크립트 파일(js, ts, tsx 등)은 단순 포맷 문제뿐 아니라 문법 에러, 잠재적인 버그, 사용하지 않는 변수 같은 것들도 함께 잡아줘야 한다.
반면에 json, css, md 파일은로직을 포함하지 않는 설정 파일 또는 문서 성격의 파일이기 때문에ESLint를 적용해도 얻는 이점이 거의 없다고 판단했다.
따라서, 해당 파일들은 포맷팅만 책임지는 Prettier만 실행하도록 분리했다.
⇒ 로직이 있는 파일은 린트까지 통과해야 커밋하고, 그 외 파일은 포맷만 맞추고 빠르게 커밋하는 것을 목표로 했다
개인 프로젝트라도 이런 기본적인 규칙을 세워두는 게 생각보다 개발할 때 피로도를 많이 줄여준다는 걸 확실히 느꼈다!