회사에 코딩 컨벤션을 도입한 후기

Boseong Choi·2025년 12월 12일
post-thumbnail

🎯 회사에 코딩 컨벤션 도입기

💡 TL;DR: AI 시대에도 코딩 컨벤션은 필수입니다. Prettier + ESLint + AI 프롬프트 조합으로 팀 전체가 일관된 코드를 작성하게 된 경험을 공유합니다.


1. 왜 코딩 컨벤션인가?

코딩 컨벤션(Code Convention): 팀이 일관된 코드 스타일과 규칙을 사용하기 위해 정한 약속.

도입을 고민하게 된 계기

I. 개발자마다 다른 코딩 스타일

가장 큰 이유였습니다. 협업 프로젝트가 있을 때마다 개발팀의 스타일이 제각각이라 가독성이 좋지 않았습니다.

항목개발자 A개발자 B
세미콜론필수 사용생략
따옴표쌍따옴표 "작은따옴표 '
들여쓰기Tab 4칸Space 2칸
import 정렬무작위알파벳순

결과적으로 발생한 문제들

🔴 코드 리뷰 시 스타일 논쟁에 시간 낭비
🔴 신규 팀원 온보딩 시 "이 프로젝트는 이렇게 해요"라는 불필요한 설명 증가
🔴 Git diff가 실제 로직 변경이 아닌 포맷팅 변경으로 오염

II. 프롬프트 엔지니어링과 AI 코딩

회사에 Cursor IDE를 적극 도입하면서 생산성은 이전과 비교할 수 없을 정도로 향상되었습니다. 하지만 한 가지 문제가 있었습니다.

AI는 기본적으로 우리 팀의 코딩 컨벤션을 모릅니다.

AI가 생성한 코드가 다음과 같은 문제를 일 수 있습니다.

// AI가 생성한 코드 (우리 컨벤션과 다름)
import {Controller} from "@nestjs/common"
import {UserService} from "./user.service"

export class UserController {
    constructor(private userService: UserService) {}
}
// 우리 팀 컨벤션
import { Controller } from '@nestjs/common';

import { UserService } from './user.service';

export class UserController {
  constructor(private readonly userService: UserService) {}
}

따라서 바이브 코딩(Vibe Coding) 을 하더라도 코딩 컨벤션을 지켜야 한다는 건 변함이 없었습니다.


2. 코딩 컨벤션 도입이 실패하는 이유

많은 팀이 코딩 컨벤션 도입을 시도하지만 실패하는 경우가 많습니다. 왜 그럴까요?

원인설명
📌 각자 다른 IDE 환경VS Code, WebStorm, Cursor 등 각자 다른 IDE를 사용하면 설정 공유가 어려움
📌 세팅의 복잡성ESLint, Prettier, EditorConfig 등 도구가 많고 설정 파일이 복잡함
📌 규칙을 지키기 어려움"저장할 때 자동 포맷팅" 설정을 안 하면 매번 수동으로 해야 함
📌 강제성 부재CI/CD 파이프라인에서 검사하지 않으면 결국 개인 재량에 맡겨짐
📌 너무 많은 규칙처음부터 모든 규칙을 error로 설정하면 개발자 피로도 급증
📌 문서화 부재"왜 이 규칙인지" 설명 없이 규칙만 강요하면 저항이 생김

우리 팀의 해결 원칙

1. Prettier가 포맷 최종 결정권자 → 포매팅 논쟁 종결
2. 가독성 > 개인 취향 → 정답이 없는 부분은 Prettier 기본값 + 팀 최소 합의
3. 경고 중심 도입 → 대부분 warn으로 시작, 익숙해지면 error로 승격
4. 자동화 우선 → 저장 시 포맷/자동수정, 커밋 전 자동 검사
5. 규칙은 짧게 → 꼭 필요한 소수 규칙만, 나머지는 리뷰로 보완

3. 코딩 컨벤션 도입 방법

3-1. 공통 설정 파일 구성

모든 IDE에서 공통으로 읽을 수 있는 4가지 핵심 설정 파일을 프로젝트 루트에 배치합니다.

.editorconfig - IDE 공통 설정

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true

.prettierrc.json - 코드 포맷팅

{
  "printWidth": 100,
  "tabWidth": 2,
  "singleQuote": true,
  "semi": true,
  "trailingComma": "none",
  "bracketSpacing": true,
  "arrowParens": "always",
  "endOfLine": "lf"
}

.eslintrc.cjs - 코드 품질 검사

module.exports = {
  root: true,
  plugins: ['@typescript-eslint', 'import', 'unused-imports'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:import/recommended',
    'plugin:prettier/recommended'  // Prettier와 충돌 방지
  ],
  rules: {
    'prettier/prettier': ['warn'],
    'prefer-const': 'error',
    '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
    'import/order': ['warn', {
      groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
      'newlines-between': 'always',
      alphabetize: { order: 'asc', caseInsensitive: true }
    }],
    'unused-imports/no-unused-imports': 'warn'
  }
};

3-2. AI IDE용 프롬프트 설정

Cursor (VS Code 계열)

Settings > Cursor Settings > Rules for AI에 팀 컨벤션 프롬프트 입력

# 코딩 컨벤션 규칙
- Prettier 규칙 준수: singleQuote, semi, trailingComma: none
- import 정렬: builtin → external → internal → parent/sibling
- 변수/함수: camelCase, 컴포넌트/클래스: PascalCase
- const 우선, async/await 사용
- 메서드는 동사로 시작 (예: checkSomething, getUserById)

JetBrains (WebStorm, IntelliJ 등)

프로젝트 루트에 .aiassistant/rules/ 폴더를 생성하고 마크다운 파일로 프롬프트 작성

📁 프로젝트 루트
└── 📁 .aiassistant
    └── 📁 rules
        └── 📄 coding-convention-prompt.md

3-3. package.json 스크립트 추가

{
  "scripts": {
    "lint": "eslint . --ext .ts,.tsx,.js --max-warnings=0",
    "lint:fix": "eslint . --ext .ts,.tsx,.js --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  }
}

4. 트러블 슈팅

🔧 CRLF vs LF 문제

증상

Windows 개발자와 Mac/Linux 개발자가 협업할 때 줄바꿈 문자 충돌

해결 방법

  1. .gitattributes 파일 추가

    * text=auto eol=lf
    *.{cmd,[cC][mM][dD]} text eol=crlf
    *.{bat,[bB][aA][tT]} text eol=crlf
  2. .prettierrc.json"endOfLine": "lf" 설정

  3. Git 전역 설정

    git config --global core.autocrlf input  # Mac/Linux
    git config --global core.autocrlf true   # Windows

🔧 ESLint + Prettier 충돌

증상

ESLint와 Prettier가 서로 다른 포맷을 요구

해결 방법

npm install -D eslint-config-prettier eslint-plugin-prettier

.eslintrc.cjsextends 마지막에 추가

extends: [
  // ... 다른 설정들
  'plugin:prettier/recommended'  // 반드시 마지막에!
]

🔧 import 순서 자동 정렬 안 됨

증상

import/order 규칙이 경고만 주고 자동 수정 안 됨

해결 방법

  1. eslint-import-resolver-typescript 설치

    npm install -D eslint-import-resolver-typescript
  2. 설정 추가

    settings: {
      'import/resolver': {
        typescript: { project: '.' }
      }
    }

🔧 미사용 import 자동 삭제

증상

사용하지 않는 import가 남아있음

해결 방법

npm install -D eslint-plugin-unused-imports
plugins: ['unused-imports'],
rules: {
  'unused-imports/no-unused-imports': 'warn'
}

5. 결과 및 기대효과

📊 정량적 효과

지표BeforeAfter
코드 리뷰 시 스타일 코멘트~30%< 5%
신규 팀원 온보딩 시간1주일2-3일
Git diff 노이즈잦음거의 없음
AI 코드 수정 필요 빈도매번자동 적용

✅ 정성적 효과

  • 코드 리뷰 품질 향상: 스타일 논쟁 대신 로직과 설계에 집중
  • 인지 부하 감소: 어떤 파일을 열어도 익숙한 구조
  • AI 협업 효율화: 프롬프트에 컨벤션을 넣어 처음부터 올바른 코드 생성
  • 팀 문화 개선: "내 스타일" 대신 "팀 표준"이라는 인식 정착

📚 참고 자료


profile
Software Engineer

0개의 댓글