이 주제로 글을 작성하게 된 계기

이전에 'Prettier 설정하기'라는 이름의 게시글을 작성했습니다. 이 글을 쓸 당시에는 혼자서만 코드를 작성하고 배포해보았고 그 이후에서도 혼자서만 코드를 작성하여 큰 문제 없이 스스로 쓴 글을 보며 사용하고 있었습니다. 하지만 곧 있을 협동 프로젝트로 인해 개인 설정이 아닌 협동을 위한 설정이 필요하게 되었습니다.
특히 Prettier를 단독으로 사용하는 것이 아닌 ESLint설정을 함께 해주고 두 도구의 충돌도 신경을 써주어야 합니다. 그래서 이번 글은 협동 프로젝트를 준비하면서 내가 사용하기 위해 정리한 결과물을 공유하고자 합니다! 😎

본격적으로 들어가기전에

이 게시글에서는 ESLint에 대한 개념은 정리되어 있으나 Prettier의 개념에 대해서는 생략이 있으니 'Prettier 설정하기'를 먼저 보고 오는 것을 추천드립니다!



Prettier 사용을 위한 3가지 준비

1. VS Code의 Extension에서 Prettier 확장 프로그램 설치

2. VS Code 설정에서 Prettier 사용 설정 하기

맥의 경우 Command + , / 윈도우의 경우 Ctrl + , 를 동시에 눌러 VS Code 설정창을 띄웁니다.
화면에 윗부분에 있는 검색창에 Editor: Default Formatter를 입력한 후 None을 Prettier - Code formatter로 바꾸어 줍니다.
다음으로 다시 검색창에 Editor: Format on Save를 입력한 후 빈 박스를 클릭하여 체크합니다.

3. Prettier 패키치 설치

.prettierrc라는 설정 파일을 생성하여 그 안에 원하는 포맷팅 형식을 저장해야하는데 이 파일을 생성하려면 패키지를 설치해야 합니다.
터미널을 열어 아래 명령어를 입력하여 설치합니다.

패키지 매니저가 npm 일 때

npm install -D prettier

테일윈드를 함께 사용할 예정이라면
npm install -D prettier prettier-plugin-tailwindcss

패키지 매니저가 yarn 일 때

yarn install -D prettier

테일윈드를 함께 사용할 예정이라면
yarn install -D prettier prettier-plugin-tailwindcss



Prettier 사용

1. .prettierrc

사용 준비를 마쳤으니 이제 사용해보아야겠죠? 가장 상위 폴더(package.json과 같은 선상)에 .prettierrc 파일을 생성합니다. 그리고 원하는 설정 코드를 { }안에 키와 값의 형태로 작성합니다.
Prettier 공식 문서를 확인해보면 더 많은 설정들이 있지만 현재 경험 해본적 없는 파일에 대한 설정은 가져오지 않았습니다.

아래 Prettier 적용에 주석 없이 바로 복사 가능한 코드가 있습니다.

{
  ------------------------
  기본 포맷팅 설정
  ------------------------
  // 한 줄의 최대 길이를 설정 (기본값: 80)
  // 이 길이를 초과하면 자동으로 줄바꿈이 발생
  "printWidth": 80,
  
  // 들여쓰기 시 사용할 공백 문자 수 (기본값: 2)
  // useTabs가 false일 때만 적용됨
  "tabWidth": 2,
  
  // 들여쓰기에 탭 문자 사용 여부 (기본값: false)
  // true: 탭 문자 사용, false: 공백 문자 사용
  "useTabs": false,
  
  // 문장 끝 세미콜론 사용 여부 (기본값: true)
  // true: 모든 문장 끝에 세미콜론 추가
  // false: 필요한 경우에만 세미콜론 추가
  "semi": true,
  
  ------------------------
  따옴표 관련 설정
  ------------------------
  // 문자열에 작은따옴표 사용 여부 (기본값: false)
  // true: 'string', false: "string"
  "singleQuote": true,
  
  // 객체 속성에 따옴표 추가 방식 (기본값: "as-needed")
  "quoteProps": "as-needed",
  // - "as-needed": 필요한 경우에만 따옴표 추가
  // - "consistent": 하나라도 따옴표가 필요하면 모든 속성에 따옴표 추가
  // - "preserve": 입력된 따옴표 스타일 유지
  
  // JSX에서 작은따옴표 사용 여부 (기본값: false)
  // singleQuote 설정과 독립적으로 동작
  "jsxSingleQuote": true,
  
  ------------------------
  쉼표 및 괄호 설정
  ------------------------
  // 객체, 배열 등의 후행 쉼표 설정 (기본값: "es5")
  "trailingComma": "es5",
  // - "all": 모든 구문에서 후행 쉼표 사용 (함수 인자 포함)
  // - "es5": ES5에서 유효한 위치에만 후행 쉼표 추가
  // - "none": 후행 쉼표 사용 안 함
  
  // 객체 리터럴의 중괄호 주위 공백 추가 (기본값: true)
  // true: { foo: bar }, false: {foo: bar}
  "bracketSpacing": true,
  
  // JSX 요소의 > 위치 설정 (기본값: false)
  // true: 마지막 줄에 > 위치, false: 다음 줄에 > 위치
  "bracketSameLine": false,
  
  // 화살표 함수 매개변수 괄호 사용 방식 (기본값: "always")
  "arrowParens": "always",
  // - "always": (x) => x
  // - "avoid": x => x (매개변수가 하나일 때)
  
  ------------------------
  특수 포맷팅 설정
  ------------------------
  // 줄 끝 문자 설정 (기본값: "lf")
  "endOfLine": "lf",
  // - "lf": \n (Unix)
  // - "crlf": \r\n (Windows)
  // - "cr": \r (Mac OS)
  // - "auto": 첫 줄 끝 문자 유지
  
  // 마크다운 텍스트의 줄바꿈 방식 (기본값: "preserve")
  "proseWrap": "always",
  // - "always": 항상 printWidth에 따라 줄바꿈
  // - "never": 줄바꿈 하지 않음
  // - "preserve": 원본 텍스트 줄바꿈 유지
  
  // HTML 공백 처리 방식 (기본값: "css")
  "htmlWhitespaceSensitivity": "strict",
  // - "css": CSS display 속성 기준으로 처리
  // - "strict": 모든 공백을 유지
  // - "ignore": 모든 공백을 무시
  
  ------------------------
  플러그인 설정
  ------------------------
  // Tailwind CSS 클래스 자동 정렬을 위한 플러그인
  "plugins": ["prettier-plugin-tailwindcss"]
}

2. .prettierignore

.gitignore 파일 처럼 Prettier를 적용하지 않을 파일을 작성하면 됩니다.

# 빌드 결과물
dist/
build/

# Node.js 모듈
node_modules/

# 환경 설정 파일
.prettierrc
** eslint.config.js -> 자신이 사용하는 확장자명으로 바꿔주기 **

# 로그 파일
npm-debug.log
yarn-debug.log
yarn-error.log

# 프로젝트 루트에서 제외된 다른 파일들
public/
coverage/

# 기타
.vscode/
.idea/
.DS_Store
*.config.js


# 패키지 관리
package-lock.json



Prettier 적용

제가 설정한 설정과 동일하게 사용하거나 일부만 수정하실 경우 아래 코드를 사용하시면 됩니다!

1. .prettierrc

{
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "quoteProps": "as-needed",
  "jsxSingleQuote": true,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "bracketSameLine": false,
  "arrowParens": "always",
  "endOfLine": "lf",
  "proseWrap": "always",
  "htmlWhitespaceSensitivity": "strict",
  "plugins": ["prettier-plugin-tailwindcss"] // 테일윈드 사용 시
}

2. .prettierignore

dist/
build/
node_modules/
.prettierrc
.eslintrc.cjs
npm-debug.log
yarn-debug.log
yarn-error.log
public/
coverage/
.vscode/
.idea/
.DS_Store
*.config.js
package-lock.json




잠깐! ESLint를 사용하기 전에 ESLint가 무엇인지 알아봅시다.


ESLint란?

쉽게 말해 사용하는 언어의 문법에 문제가 없는지 코드 실행 전 검사해주는 도구입니다.

ESLint는 JavaScript 및 TypeScript 코드의 정적 분석 도구로, 코드에서 문제를 식별하고 코드 품질을 유지하는 데 도움을 줍니다. 정적 분석 도구는 코드 실행 없이 소스 코드를 분석하여 잠재적인 오류나 일관성 없는 스타일을 찾아냅니다. 이를 통해 코드의 가독성을 향상시키고, 협업 시 개발자들 사이의 코드 품질을 일치시킬 수 있습니다.

1. ESLint의 특징

  • 코드 품질 검사
    ESLint는 코드 품질을 유지하기 위해 다양한 규칙을 적용하여 코드 내의 잠재적인 문제를 식별합니다. 이는 버그를 예방하고 코드의 안정성을 높이는 데 도움을 줍니다.

  • 구성 가능성
    ESLint는 사용자 정의 규칙을 생성하거나 기본 제공 규칙을 사용자 필요에 맞게 조정할 수 있습니다. 또한, 다양한 규칙 세트를 확장하여 사용할 수 있습니다.

  • 플러그인 지원
    ESLint는 플러그인 아키텍처를 가지고 있어, 추가적인 플러그인을 통해 더 많은 언어 기능 및 스타일 검사 기능을 추가할 수 있습니다. React, Vue.js, TypeScript 등과 같은 다양한 라이브러리 및 프레임워크와 통합할 수 있습니다.

  • 자동 수정 기능
    ESLint는 코드 문제를 식별할 뿐만 아니라, --fix 옵션을 통해 일부 문제를 자동으로 수정할 수 있습니다. 이를 통해 코드 스타일을 일관되게 유지하는 것이 더 쉬워집니다.

  • 통합 가능성
    ESLint는 대부분의 코드 편집기와 통합되어 실시간으로 코드 검사를 수행할 수 있습니다. 또한, 빌드 도구나 CI/CD 파이프라인에 통합하여 코드 품질을 지속적으로 관리할 수 있습니다.

2. ESLint의 설정파일 종류

eslint.config.* 형식의 설정 파일을 사용하며, 확장자에 따라 다음과 같은 특징을 가집니다.

1. eslint.config.js

  • 가장 범용적 - 널리 사용되어 문서화가 잘 되어있고 호환성이 좋음
  • “type”: “module” 주의 - package.json 설정에 따라 문법이 달라질 수 있음
  • 유연성 - 동적 설정이 가능하며 대부분의 상황에 적합
export default [
  {
    files: ['**/*.{js,jsx}'],
    rules: {
      semi: 'error',
      'prefer-const': 'error'
    }
  }
]

2. eslint.config.mjs

  • ESM 전용 - 최신 JavaScript 모듈 시스템을 명시적으로 사용
  • 호환성 제한 - 일부 도구나 이전 Node.js 버전과 호환성 문제 가능
  • 명확한 구문 - import/export가 명확하여 코드 이해가 쉬움
import js from '@eslint/js'

export default [
  {
    files: ['**/*.{js,jsx}'],
    rules: js.configs.recommended.rules
  }
]

3. eslint.config.cjs

  • 안정성 - Node.js 모든 버전에서 안정적으로 동작
  • 제한된 기능 - 최신 ESM 기능 사용이 제한됨
  • 단순함 - 설정이 단순하고 직관적이나 현대적 기능 부족
module.exports = [
  {
    files: ['**/*.{js,jsx}'],
    rules: {
      semi: 'error'
    }
  }
]

4. eslint.config.ts

  • 타입 안정성 - TypeScript의 타입 체크와 자동완성 지원
  • 추가 설정 필요 - 빌드 설정과 의존성 추가가 필요함
  • 개발 생산성 - 복잡한 설정도 타입 안전하게 작성 가능
import type { Linter } from 'eslint'

const config: Linter.Config[] = [
  {
    files: ['**/*.{ts,tsx}'],
    rules: {
      '@typescript-eslint/explicit-function-return-type': 'error'
    }
  }
]

export default config

5. eslint.config.mts/cts

  • 명확한 구조 - TypeScript와 모듈 시스템을 명시적으로 구분
  • 높은 진입장벽 - 설정이 복잡하고 도구 지원이 제한적
  • 타입 안정성 - 타입스크립트의 장점을 최대한 활용 가능
import type { Linter } from 'eslint'

const config: Linter.Config[] = [
  {
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parser: '@typescript-eslint/parser'
    }
  }
]

export default config

3. ESLint의 설정파일 우선순위

ESLint는 설정 파일을 찾을 때 특정 우선순위를 따릅니다. 프로젝트 루트 디렉토리에서 설정 파일을 찾으며, 다음 순서로 파일을 검색합니다:

  1. eslint.config.js
  2. eslint.config.mjs
  3. eslint.config.cjs
  4. eslint.config.ts (추가 설정 필요)
  5. eslint.config.mts (추가 설정 필요)
  6. eslint.config.cts (추가 설정 필요)


ESLint 사용을 위한 2가지 준비

1. VS Code의 Extension에서 ESLint 확장 프로그램 설치

2. ESLint 패키지 설치

.eslintrc.cjs이라는 설정 파일을 생성하여 그 안에 원하는 포맷팅 형식을 저장해야하는데 이 파일을 생성하려면 패키지를 설치해야 합니다.

저는 타입스크립트를 기반으로 리액트와 테일윈드를 사용하여서 이에 기반한 패키지들을 설치하였습니다. 외에도 ESLint 공식 문서에 다른 패키지도 있으니 필요하신 분들은 추가로 설치하시면 됩니다!

패키지 매니저가 npm 일 때

npm install -D eslint @eslint/js eslint-config-prettier eslint-import-resolver-node eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-react-refresh eslint-plugin-tailwindcss prettier prettier-plugin-tailwindcss typescript-eslint

패키지 매니저가 yarn 일 때

yarn add -D eslint @eslint/js eslint-config-prettier eslint-import-resolver-node eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-react-refresh eslint-plugin-tailwindcss prettier prettier-plugin-tailwindcss typescript-eslint

어떤 패키지를 설치하는 건가요?

각 패키지들의 핵심 기능을 설명하면 다음과 같습니다.

핵심 린팅 도구
eslint: JavaScript/TypeScript 코드의 문제점을 검사하는 린터
@eslint/js: ESLint의 JavaScript 관련 기본 설정

코드 스타일링
prettier: 코드 포맷터
eslint-config-prettier: ESLint와 Prettier 충돌 방지
eslint-plugin-prettier: Prettier를 ESLint 규칙으로 실행
prettier-plugin-tailwindcss: Tailwind CSS 클래스 자동 정렬

React 관련
eslint-plugin-react: React 관련 린트 규칙
eslint-plugin-react-hooks: React Hooks 규칙 검사
eslint-plugin-react-refresh: Fast Refresh 관련 규칙

모듈 및 경로
eslint-plugin-import: import/export 구문 검사
eslint-import-resolver-node: import 경로 해석

UI 및 접근성
eslint-plugin-jsx-a11y: JSX 접근성 규칙 검사
eslint-plugin-tailwindcss: Tailwind CSS 관련 린트 규칙

TypeScript 지원
typescript-eslint: TypeScript 코드를 위한 ESLint 플러그인



ESLint 사용

1. eslint.config.js

사용 준비를 마쳤으니 이제 사용해보아야겠죠? 이 설정 파일에는 설치한 패키지들에 대한 정보를 작성합니다. 만약 타입스크립트에 관한 패키지를 추가로 설치하셨다면 ESLint 설정파일에도 그 정보를 추가로 작성해주어야 합니다.
Vite를 사용하여 프로젝트를 만들었다면 자동으로 생성되는eslint.config.js 파일이 있습니다. 이 설정 파일은 React 프로젝트에서 사용할 ESLint 설정을 일부 정의하고 있습니다. 그래서 이 설정에 우리가 추가로 사용하는 패키지만 추가해 주도록 하겠습니다. 사용을 원하는 설정 코드를 ' ' : ' ' 형태로 작성합니다.


아래 ESLint 적용에 주석 없이 바로 복사 가능한 코드가 있습니다.

// TypeScript, React, Tailwind CSS 프로젝트를 위한 통합 린팅 규칙 설정

------------------------
필요한 플러그인 및 설정 import
------------------------
import js from '@eslint/js'                        // 기본 JavaScript 규칙
import reactHooks from 'eslint-plugin-react-hooks' // React Hooks 규칙
import reactRefresh from 'eslint-plugin-react-refresh' // React Refresh 기능 지원
import globals from 'globals'                      // 전역 변수 설정
import tseslint from 'typescript-eslint'           // TypeScript 지원
import prettier from 'eslint-plugin-prettier'      // Prettier 통합
import react from 'eslint-plugin-react'           // React 규칙
import jsxA11y from 'eslint-plugin-jsx-a11y'      // 접근성 규칙
import importPlugin from 'eslint-plugin-import'    // import/export 규칙
import tailwindcss from 'eslint-plugin-tailwindcss' // Tailwind CSS 규칙

export default tseslint.config(
  // 빌드 결과물 폴더 무시
  { ignores: ['dist'] },
  {
    // TypeScript와 TSX 파일만 린팅 대상으로 지정
    files: ['**/*.{ts,tsx}'],

    ------------------------
    언어 및 파서 설정
    ------------------------
    languageOptions: {
      // TypeScript 파서 사용
      parser: tseslint.parser,
      // 최신 ECMAScript 문법 지원
      ecmaVersion: 'latest',
      // ES 모듈 시스템 사용
      sourceType: 'module',
      globals: {
        // 브라우저 전역 변수 허용
        ...globals.browser,
        // React를 전역 변수로 설정 (읽기 전용)
        React: 'readonly',
      },
      parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module',
        ecmaFeatures: {
          // JSX 문법 활성화
          jsx: true
        }
      }
    },

    ------------------------
    프로젝트 설정
    ------------------------
    settings: {
      // React 설정
      react: {
        // React 버전 자동 감지
        version: '18.2',
        // 새로운 JSX 변환 사용
        runtime: 'automatic'
      },
      // import 경로 해석 설정
      'import/resolver': {
        node: {
          // 자동 확장자 처리
          extensions: ['.js', '.jsx', '.ts', '.tsx', '.css']
        }
      }
    },

    ------------------------
    사용할 플러그인 설정
    ------------------------
    plugins: {
      'react-hooks': reactHooks,     // React Hooks 규칙
      'react-refresh': reactRefresh,  // Fast Refresh 지원
      'prettier': prettier,           // 코드 포맷팅
      'react': react,                // React 규칙
      'jsx-a11y': jsxA11y,           // 접근성 검사
      'import': importPlugin,         // import 순서 및 규칙
      'tailwindcss': tailwindcss     // Tailwind CSS 규칙
    },

    ------------------------
    상세 린팅 규칙
    ------------------------
    rules: {
      // JavaScript 추천 규칙 적용
      ...js.configs.recommended.rules,
      // React Hooks 추천 규칙 적용
      ...reactHooks.configs.recommended.rules,

      // React 17+ 이상에서는 React import 불필요
      'react/react-in-jsx-scope': 'off',
      
      // Prettier 규칙 위반시 에러 표시
      'prettier/prettier': 'error',
      
      // 화살표 함수 스타일 제한 해제
      'arrow-body-style': 'off',
      'prefer-arrow-callback': 'off',
      
      // target="_blank" 사용시 보안 경고 비활성화
      'react/jsx-no-target-blank': 'off',
      
      // Fast Refresh 관련 설정
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true }
      ],

      // TypeScript 사용하므로 기본 미사용 변수 규칙 비활성화
      'no-unused-vars': 'off',
      
      // TypeScript 미사용 변수 규칙 설정
      '@typescript-eslint/no-unused-vars': ['warn', {
        'varsIgnorePattern': '^_',      // '_'로 시작하는 변수 무시
        'argsIgnorePattern': '^_',      // '_'로 시작하는 매개변수 무시
        'ignoreRestSiblings': true      // 구조분해할당의 나머지 변수 무시
      }],

      // 일치 연산자 강제 (==, != 대신 ===, !== 사용)
      'eqeqeq': ['error', 'always'],
      
      // Tailwind CSS 관련 규칙
      'tailwindcss/classnames-order': 'warn',    // 클래스명 순서 경고
      'tailwindcss/no-custom-classname': 'off'   // 커스텀 클래스명 허용
    }
  }
)

2. .eslintignore

.gitignore 파일 처럼 ESLint를 적용하지 않을 파일을 작성하면 됩니다.

# 빌드 결과물
dist/
build/

# Node.js 모듈
node_modules/

# 환경 설정 파일
.eslintrc.cjs

# 로그 파일
npm-debug.log
yarn-debug.log
yarn-error.log

# 프로젝트 루트에서 제외된 다른 파일들
public/
coverage/

# 기타
.vscode/
.idea/
.DS_Store
*.config.js

# 패키지 관리
package-lock.json



ESLint 적용

제가 설정한 설정과 동일하게 사용하거나 일부만 수정하실 경우 아래 코드를 사용하시면 됩니다!

1. eslint.config.js

import js from '@eslint/js'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import globals from 'globals'
import tseslint from 'typescript-eslint'
import prettier from 'eslint-plugin-prettier'
import react from 'eslint-plugin-react'
import jsxA11y from 'eslint-plugin-jsx-a11y'
import importPlugin from 'eslint-plugin-import'
import tailwindcss from 'eslint-plugin-tailwindcss'

export default tseslint.config(
  { ignores: ['dist'] },
  {
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parser: tseslint.parser,
      ecmaVersion: 'latest',
      sourceType: 'module',
      globals: {
        ...globals.browser,
        React: 'readonly',
      },
      parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module',
        ecmaFeatures: {
          jsx: true
        }
      }
    },
    settings: {
      react: {
        version: '18.2',
        runtime: 'automatic'
      },
      'import/resolver': {
        node: {
          extensions: ['.js', '.jsx', '.ts', '.tsx', '.css']
        }
      }
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
      'prettier': prettier,
      'react': react,
      'jsx-a11y': jsxA11y,
      'import': importPlugin,
      'tailwindcss': tailwindcss
    },
    rules: {
      ...js.configs.recommended.rules,
      ...reactHooks.configs.recommended.rules,
      'react/react-in-jsx-scope': 'off',
      'prettier/prettier': 'error',
      'arrow-body-style': 'off',
      'prefer-arrow-callback': 'off',
      'react/jsx-no-target-blank': 'off',
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true }
      ],
      'no-unused-vars': 'off',
      '@typescript-eslint/no-unused-vars': ['warn', {
      'varsIgnorePattern': '^_',
      'argsIgnorePattern': '^_',
      'ignoreRestSiblings': true
      }],
      'eqeqeq': ['error', 'always'],
      'tailwindcss/classnames-order': 'warn',
      'tailwindcss/no-custom-classname': 'off'
    }
  }
)

2. .eslintignore

dist/
build/
node_modules/
.eslintrc.cjs
npm-debug.log
yarn-debug.log
yarn-error.log
public/
coverage/
.vscode/
.idea/
.DS_Store
*.config.js
package-lock.json




마무리하며

구글링했을 때 나오는 정보들이 많지만 아직 코딩 초보에게는 어려운 정보들이 너무 많았습니다. 그래서 학습 정도에 맞게 필요한 정보만을 정리하여 코딩 초보도 보고 이해할 수 있는 글을 쓰고싶었습니다.
다른 코딩 초보분들에게 이 글이 도움이 되었으면 좋겠습니다 🤘

profile
프론드엔드 개발자 입니다!

6개의 댓글

comment-user-thumbnail
2024년 7월 5일

미쳤다.. 프로젝트 시작 하기 전에 eslint랑 prettier설정을 어떻게 해야 할지 너무 막막했는데 ㅜㅜ 정리가 너무 깔끔하게 되어있어서 공부 잘 하고 갑니다!! 감사합니당!@

1개의 답글
comment-user-thumbnail
2024년 7월 7일

아 익숙치 않아서 대충 안해도 되겠지라는 생각으로 있었는데, 이렇게 정리 해주니 새내기 개발자들에게 많은 도움이 되는거 같습니다 ㅎㅎ 감사합니다 !

1개의 답글
comment-user-thumbnail
2025년 5월 11일

정리가 너무 잘되어 있어서 첫 협업에서 보고 세팅했습니다! 감사합니다.. 초보 탈출만을 바라며!!

1개의 답글