본문 바로가기

Frontend

[vscode] ESLint, Prettier 적용하기

예전 팀 프로젝트인 Web IDE 만들기 프로젝트에서 prettier를 개인적으로 적용한 상태라

저장 한 번에 전체 파일 포맷이 바뀌는 상황이 많았고,

내가 작업하지 않는 파일도 git diff에 떠서 많은 스트레스를 받았다.

설명은 들었지만 적용하지 않은 나의 죄가 크지

 

 

그래서 이번에는 Prettier + Lint를 명확하게 설정하여 vscode에서도 자동 적용 되도록 환경을 만들어

해당 이슈가 재발하지 않도록 해야겠다는 결심을 했다.

 

다른 팀원분께는 위 작업을 위해 내가 이번에 구조 작업을 맡겠다고 제안드렸고 흔쾌히 ok하심

 

 

Prettier 설정하기(.prettierrc)

{
  "singleQuote": false,
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80,
  "bracketSpacing": true,
  "arrowParens": "always",
  "endOfLine": "auto"
}

기존 팀원들이 선호하던 스타일을 반영해 통일시켰다.

특히 useTab: false, tabWidth를 2로 고정해 가장 많이 발생하던 diff 이슈를 해결했다.

tab 공백 적용하고 난 후 변경점 확인할 때 좀 뿌듯했음

 

Lint 설정하기(eslint.config.mjs)

처음에는 .eslintrc.js를 통해 작업 중이였는데

Next.js 13부터는 FlatConfig 기반 eslint.config.mjs 방식이 권장된다는걸 보게되었다.

처음엔 설정 방식이 달라서 약간 헤맸지만 FlatCompat로 기존에 만들었던 것을 마이그레이션했다.

 

작업완료 후 스크립트를 돌렸을 때 몇가지 오류가 발생했다.

eslint-plugin 충돌 이슈였다.

나는 역할을 분리하기위해 포맷은 Prettier가 전담하고, Lint는 코드 검사만 하도록 했기 때문에

eslint-plugin-prettier를 제거하고 prettier만 넣었다.

또 JSX: React must be in scope 오류가 발생했다.

React 17 이후 JSX에 import React가 필요없기때문에 "react/react-in-jsx-scope": "off"로 설정했다.

최종 버전

import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: {
    rules: {},
  },
});

const config = [
  {
    ignores: [
      "**/node_modules/**",
      "**/.next/**",
      "**/dist/**",
      "**/build/**",
      "**/out/**",
      "**/public/**",
    ],
  },
  ...compat.config({
    root: true,
    parser: "@typescript-eslint/parser",
    parserOptions: {
      ecmaVersion: 2020,
      sourceType: "module",
      ecmaFeatures: {
        jsx: true,
      },
    },
    env: {
      browser: true,
      node: true,
      es6: true,
    },
    plugins: ["react", "react-hooks", "@typescript-eslint"],
    extends: [
      "eslint:recommended",
      "plugin:react/recommended",
      "plugin:react-hooks/recommended",
      "plugin:@typescript-eslint/recommended",
      "prettier",
    ],
    rules: {
      "@typescript-eslint/explicit-module-boundary-types": "off",
      "react/react-in-jsx-scope": "off",
    },
    settings: {
      react: {
        version: "detect",
      },
    },
  }),
];

export default config;

 

 

VSCode 설정 (.vscode/settings.json)

생성한 prettier, lint파일을 적용하기 위해 settings.json파일도 생성했다.

{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true
}

저장 시 자동으로 ESLint와 Prettier 둘 다 적용되도록 구성했다.

기본 포맷터를 Prettier로 지정해 ESLint나 다른 확장과 충돌하지 않도록 설정했다.

 

Package.json에서의 작업

script추가

check를 통해 한번에 실행할 수 있게하고

lint, format을 추가해 필요 시 따로 실행할 수 있도록 했다.

...
"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start",
  "lint": "eslint .",
  "format": "prettier --write \"**/*.{js,ts,jsx,tsx,json,css,md}\"",
  "check": "npm run lint && npm run format"
},
...

 

버전 고정

각자의 개발 환경 차이로 발생하는 문제를 막기위해 주요 라이브러리의 버전을 고정했다.

안정적인 버전은 GPT에게 물어보면 정리했다.

...
"dependencies": {
  "next": "15.3.1",
  "react": "18.3.1",
  "react-dom": "18.3.1",
  "zustand": "4.4.7"
},
...

 

 

 

 

다음에 꼭 설정해야지~ 생각만 했던 부분인데

이번 프로젝트가 마지막이라는 생각에 미뤄왔던 설정들을 정리하고 적용할 수 있어서 시작부터 만족스러웠다.

 

PR에서 불필요한 diff가 줄어들길 기대하며,, 마지막 프로젝트도 화이팅!