← 목록으로

떠글보글 프로젝트 초기 설정

YEJI · 2026. 01. 20. 13:04 · 3분
목차

프로젝트를 시작할 때 제일 먼저 잡고 싶었던 건 **“사람이 실수해도 시스템이 보정해주는 기본 장치”**였습니다.

  • 커밋 메시지에 이슈 번호가 빠지지 않게 만들기
  • 프론트는 코드 스타일/임포트 정렬까지 자동으로 맞추기
  • 백엔드는 커밋 전에 포맷팅을 강제해서 리뷰 비용 줄이기
  • (TODO) 푸시 전에 빌드까지 확인하면 더 탄탄해짐

아래는 떠글보글에서 적용한 프론트엔드/백엔드 초기 설정 정리입니다.


프론트엔드 설정

1) Husky로 커밋 메시지에 이슈 번호 자동 부착

브랜치명에 이슈 번호를 포함하는 규칙을 전제로 했습니다.

예: feature/add-login-123

커밋할 때마다 메시지 끝에 (#123)이 자동으로 붙도록 commit-msg 훅을 설정했습니다.

  • 현재 브랜치명에서 숫자를 추출
  • 커밋 메시지에 이미 (#번호)가 있으면 중복 추가하지 않음
  • 없으면 메시지 끝에 (#번호)를 붙여 저장
sh
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
 
COMMIT_MSG_FILE=$1
BRANCH_NAME=$(git symbolic-ref --short HEAD)
ISSUE_NUMBER=$(echo "$BRANCH_NAME" | grep -oE '[0-9]+' | head -n 1)
 
if [ -n "$ISSUE_NUMBER" ]; then
ORIGINAL_MSG=$(cat "$COMMIT_MSG_FILE")
 
if ! echo "$ORIGINAL_MSG" | grep -q "(#$ISSUE_NUMBER)"; then
echo "$ORIGINAL_MSG (#$ISSUE_NUMBER)" > "$COMMIT_MSG_FILE"
echo "✅ Husky: 커밋 메시지 끝에 이슈 번호(#$ISSUE_NUMBER)를 추가했습니다."
fi
fi

이걸 해두면, “이 커밋이 어떤 작업(이슈)에서 나온 건지”를 커밋 단위로 추적하기가 쉬워져서 협업/회고/릴리즈 노트 작성이 훨씬 편해집니다.


2) ESLint(Flat Config) + Prettier + import 정렬(perfectionist)

프론트는 TypeScript + React 기반이라, lint를 “에러 잡기 + 스타일 통일”까지 같이 가져가도록 세팅했습니다.

포인트는 크게 3가지였습니다.

  1. TS 권장 규칙 기반 (typescript-eslint)
  2. React Hooks / React Refresh 규칙 포함
  3. import / named import 정렬을 강제해서 리뷰에서 불필요한 코멘트를 없애기
ts
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";
import perfectionist from "eslint-plugin-perfectionist";
import prettierConfig from "eslint-config-prettier";
 
export default [
{
ignores: ["dist", ".path", "node_modules", "public"],
},
 
js.configs.recommended,
 
...tseslint.configs.recommended,
 
prettierConfig,
 
{
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parser: tseslint.parser,
parserOptions: {
project: ["./tsconfig.app.json", "./tsconfig.node.json"],
tsconfigRootDir: import.meta.dirname,
},
},
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
perfectionist,
},
rules: {
...reactHooks.configs.recommended.rules,
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-explicit-any": "warn",
 
"perfectionist/sort-imports": [
"error",
{
type: "natural",
order: "asc",
groups: [
"builtin",
"external",
"internal",
["parent", "sibling", "index"],
],
internalPattern: ["^@/.*"],
},
],
 
"perfectionist/sort-named-imports": [
"error",
{
type: "natural",
order: "asc",
},
],
},
},
];

이 설정으로 얻는 효과

  • import 순서가 매번 동일해서 diff가 깔끔해짐
  • Hooks 룰이 강제되니까 사이드이펙트/의존성 누락 같은 실수를 초기에 차단
  • any, 사용하지 않는 변수 같은 “미래의 버그 씨앗”을 경고로 계속 노출

3) 빌드로 한 번 더 검증 (npm run build)

github workflow로 배포를 자동화하고는 build에서 특히 더, build에서 실패할 일을 막아야하기 때문에 푸시/병합 전에 아래 명령으로 한 번 더 확인하도록 했습니다.

bash
npm run build

백엔드 설정

1) commit-msg 훅: 브랜치명 이슈 번호 자동 부착

백엔드도 동일하게 “브랜치명에서 숫자를 뽑아서 커밋 메시지에 붙이기”를 적용했습니다.

  • 이미 (#숫자)가 있으면 그대로 둠
  • 없으면 (#이슈번호)를 붙임
sh
#!/bin/sh
 
COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
 
# 현재 브랜치명 가져오기
BRANCH_NAME=$(git symbolic-ref --short HEAD)
 
# 브랜치명에서 숫자 추출 (예: feature/123-add-login -> 123)
ISSUE_NUMBER=$(echo "$BRANCH_NAME" | grep -o '[0-9]\+' | head -1)
 
# 이미 (#숫자) 형식이 있는지 체크
if echo "$COMMIT_MSG" | grep -qE '\(#[0-9]+\)'; then
exit 0
fi
 
# 숫자가 있으면 커밋 메시지에 추가
if [ -n "$ISSUE_NUMBER" ]; then
echo "$COMMIT_MSG (#$ISSUE_NUMBER)" > "$COMMIT_MSG_FILE"
fi
 
exit 0

2) pre-commit 훅: Java 파일이 있으면 Spotless 적용 + 재스테이징

백엔드는 “포맷팅이 흔들리면 리뷰가 힘들어지는” 문제가 커서, 커밋 전에 Spotless를 자동으로 돌리도록 했습니다.

구성 포인트는 이거였습니다.

  • 스테이징된 파일 중 .java가 없으면 포맷팅 스킵
  • 있으면 spotlessApply 실행
  • 처음에 스테이징했던 Java 파일만 다시 git add 해서 “원치 않는 파일이 커밋되는 사고”를 줄임
sh
#!/bin/sh
 
echo "🔍 Pre-commit hook 실행 중..."
 
STAGED_JAVA_FILES=$(git diff --name-only --cached --diff-filter=ACMR | grep ".*\.java$")
 
if [ -z "$STAGED_JAVA_FILES" ]; then
echo "✨ 변경된 Java 파일이 없습니다. 포맷팅을 건너뜁니다."
exit 0
fi
 
echo "📝 스테이징된 파일 포맷팅 중..."
 
# 전체 프로젝트 포맷팅
./gradlew spotlessApply --daemon --quiet
 
# 원래 스테이징했던 파일들만 다시 스테이징
for file in $STAGED_JAVA_FILES; do
if [ -f "$file" ]; then
git add "$file"
fi
done
 
echo "✅ Pre-commit 체크 완료!"
exit 0

이렇게 해두면 “로컬 개발자마다 들쭉날쭉한 포맷” 때문에 PR에서 소모되는 시간을 크게 줄일 수 있습니다.


3) (TODO) 푸시 전에 빌드 검증까지 붙이면 더 완성형

백엔드는 아직 “푸시 전에 빌드 되는지 확인”을 훅으로 못 묶어둔 상태라, 다음 단계로는 아래 중 하나를 추천합니다.

  • ./gradlew test (가장 안전)
  • ./gradlew build (테스트 포함)
  • 빠르게만 보려면 ./gradlew compileJava (컴파일만)

예시로 pre-push 훅을 추가한다면 이런 형태가 됩니다.

sh
#!/bin/sh
echo "🚀 pre-push: 백엔드 빌드/테스트 확인 중..."
./gradlew test --daemon
RESULT=$?
 
if [ $RESULT -ne 0 ]; then
echo "❌ 테스트 실패로 푸시를 중단합니다."
exit 1
fi
 
echo "✅ 테스트 통과! 푸시 진행"
exit 0

마무리

초기 설정을 이렇게 잡아두니, 개발하면서 체감한 변화는 딱 두 가지였습니다.

  1. 작업 추적이 쉬워짐 (커밋 메시지에 이슈 번호가 자동으로 남음)
  2. 리뷰가 편해짐 (프론트는 import/스타일이 고정되고, 백엔드는 커밋 전에 포맷이 정리됨)