[Frontend] Next.js 프로젝트 초기 세팅 & 협업 환경 구축

YuminPark·2026년 2월 15일

Frontend

목록 보기
10/17
post-thumbnail

새로 시작한 프로젝트에서 Next.js 초기 세팅을 맡게 되었다.
초기 세팅은 매번 비슷하면서도, 막상 시작하면 “이거 했었나?” 하고 다시 찾아보게 되는 작업들이 많은 편이다.
세팅을 하다 보니 다음에 또 프로젝트를 시작할 때 참고하면 좋을 것 같다는 생각이 들어, 기억이 남아 있을 때 기록으로 남겨두려고 한다.
이번 글에서는 Next.js 초기 세팅을 중심으로, 프로젝트 초기에 함께 해두면 좋았던 설정들도 번외로 정리해보려고 한다!


Next.js + Tailwind + Prettier + ESLint + husky 초기세팅

프로젝트 생성

먼저 터미널에서 아래 명령어를 입력해 Next.js 프로젝트를 생성한다.

pnpm create next-app@latest project_name

명령어를 실행하면 아래와 같이 초기 설정을 선택하는 프롬프트가 등장한다. 이 단계에서 프로젝트에 사용할 옵션들을 하나씩 선택해주면 된다.


Prettier & ESLint

코드 스타일을 통일하기 위해 Prettier + ESLint 관련 패키지를 추가로 설치했다.

pnpm add -D prettier eslint-config-prettier eslint-plugin-prettier
pnpm add -D prettier-plugin-tailwindcss
pnpm add -D eslint-plugin-simple-import-sort
  • eslint-config-prettier
    → ESLint와 Prettier가 충돌하지 않도록 ESLint 규칙을 비활성화해주는 설정

  • eslint-plugin-prettier
    → Prettier 규칙을 ESLint 규칙처럼 사용 가능하게 해줌

  • prettier-plugin-tailwindcss
    → Tailwind CSS 클래스 순서를 자동으로 정렬해주는 플러그인

  • eslint-plugin-simple-import-sort
    → import문을 정렬해주는 플러그인


.prettierrc 파일

아래는 실제로 사용한 .prettierrc 파일이다.
각 코드에 대한 설명은 주석으로 달아두었다.

{
  "arrowParens": "avoid", //  화살표 함수에서 매개변수가 하나일 경우 괄호를 생략
  "endOfLine": "auto", // 운영체제에 따른 줄바꿈 차이를 자동으로 맞춰줌
  "printWidth": 100, // 한 줄의 최대 길이를 100자로 제한
  "semi": true, // 문장 끝에 세미콜론(;)을 항상 붙임
  "singleQuote": false, // 문자열에 작은따옴표(') 대신 큰따옴표(")를 사용
  "tabWidth": 2, // 들여쓰기 시 스페이스 2칸을 사용
  "trailingComma": "all", // 객체, 배열, 함수 파라미터 등에서 마지막 요소 뒤에도 쉼표를 붙임
  "useTabs": false, // 탭(tab) 대신 스페이스(space)를 사용
  "plugins": ["prettier-plugin-tailwindcss"] // Tailwind CSS 클래스명을 권장 순서대로 자동 정렬해줌
}

.prettierignore 파일

Prettier가 포맷을 적용하지 않아도 되는 파일/폴더를 지정하기 위해 .prettierignore 파일도 함께 추가했다.

node_modules
dist
build
.env

ESLint에 Prettier 연동하기 (eslint.config.mjs 설정)

아래는 eslint.config.mjs에서 Prettier를 ESLint에 연동한 설정이다.
Next.js에서 제공하는 기본 ESLint 설정 위에 Prettier 관련 플러그인과 룰을 추가하여, 포맷 규칙 위반 또한 ESLint 에러로 감지되도록 구성했다.

import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
import prettierConfig from "eslint-config-prettier";
import prettierPlugin from "eslint-plugin-prettier";
import simpleImportSort from "eslint-plugin-simple-import-sort";

const eslintConfig = defineConfig([
  ...nextVitals,
  nextTs,
  {
    plugins: {
      prettier: prettierPlugin,
      "simple-import-sort": simpleImportSort,
    },
    rules: {
      "simple-import-sort/imports": "error",
      "simple-import-sort/exports": "error",
      "prettier/prettier": "error",
    },
  },
  prettierConfig,
  globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts"]),
]);

export default eslintConfig;

이 설정을 통해 포맷은 Prettier가 담당하고 코드 품질 검사는 ESLint가 담당하되, 포맷이 맞지 않은 코드도 에러로 관리할 수 있게 된다.


Webpack 설정 (@svgr/webpack)

SVG 아이콘을 이미지가 아닌 React 컴포넌트처럼 사용하기 위해 @svgr/webpack을 설치했다.

pnpm add -D @svgr/webpack

@svgr/webpack을 사용하면 SVG 파일을 import 해서 형태의 컴포넌트로 사용할 수 있다.

next.config.ts 설정

설치 후, next.config.ts를 아래와 같이 수정해준다.

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  turbopack: {
    rules: {
      "*.svg": {
        loaders: [{ loader: "@svgr/webpack", options: { dimensions: false } }],
        as: "*.js",
      },
    },
  },
};

export default nextConfig;

위 설정으로 Turbopack 환경에서 .svg 파일을 React 컴포넌트로 변환할 수 있다.
dimensions: false 옵션을 추가하면 SVG에 내장된 width, height 속성이 제거되어, 사용처에서 직접 크기를 지정할 수 있어 재사용성이 높아진다.


Husky로 pre-commit 훅 설정

Husky란?

Husky는 Git hook을 쉽게 관리할 수 있게 도와주는 도구다.
Git hook은 commit, push 같은 Git 이벤트가 발생하기 직전/직후에 특정 스크립트를 실행할 수 있게 해준다.

Husky를 사용하면

  • 커밋 전에 ESLint 실행
  • 포맷이 안 맞는 코드 커밋 방지
  • 테스트 실패 시 커밋 차단
    같은 작업을 자동화할 수 있다.

즉, 잘못된 코드가 커밋되는 걸 미리 막아주는 안전장치 역할을 한다.

아래 명령어로 Husky를 개발 의존성으로 설치한다.

pnpm add -D husky

다음 명령어를 실행해 Husky를 초기화한다.

pnpm dlx husky-init

이 명령어는 다음 작업을 자동으로 수행한다.

  • .husky/ 디렉토리 생성
  • 기본 pre-commit 훅 파일 생성
  • package.jsonprepare 스크립트 추가
pnpm install

husky-init 실행 후에는 prepare 스크립트가 정상적으로 동작하도록 의존성 재설치가 필요하다.
이 과정에서 Husky가 Git hook으로 제대로 연결된다.

생성된 파일 확인

명령어 실행 후, .husky 폴더와 pre-commit 훅이 자동으로 생성되고,

package.json에는 아래와 같이 prepare 스크립트가 생성된다.

package.json 스크립트 등록

아래는 실제로 사용한 package.json 스크립트 일부이다.

{
  "scripts": {
    "start": "next start",
    "lint": "eslint . --ext .js,.ts,.tsx --fix",
    "prepare": "husky install",
    "prettier": "prettier --write ."
  }
}
  • prepare
    의존성 설치 후 Husky를 자동으로 설치해주는 스크립트
    → 팀원이 새로 레포를 받아도 Husky가 자동으로 적용된다.

  • lint / prettier
    pre-commit 단계에서 실행할 명령어들을 분리해 관리하기 위함

pre-commit 훅 설정

아래 명령어로 lint-staged를 설치한다.

pnpm add -D lint-staged

생성된 .husky/pre-commit 파일을 열어 아래와 같이 수정한다.

#!/bin/sh
pnpm exec lint-staged

커밋을 실행하면 lint-staged가 자동으로 실행되며, staged된 파일에 한해 ESLint 검사와 Prettier 포맷팅을 거친 뒤 커밋이 진행된다.
package.jsonlint-staged 설정을 추가해 대상 파일과 실행할 명령어를 지정한다.

"lint-staged": {
  "*.{ts,tsx,js,json,css,md}": [
    "eslint --fix",
    "prettier --write"
  ]
}

기존 파일 포맷팅

이미 작성된 파일들에 대해 한 번에 포맷을 적용하고 싶다면 아래 명령어를 실행하면 된다.

pnpm run prettier

초기 세팅 단계에서 한 번 실행해두면 이후에는 pre-commit 훅을 통해 포맷이 자동으로 관리된다.


settings.json

.vscode 폴더에 settings.json 파일을 생성하고 아래와 같이 설정했다.

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

이 설정을 추가하면 파일을 저장하는 순간 자동으로 포맷과 린트 수정이 수행된다.

각 설정이 하는 일

  • editor.formatOnSave: true
    -> 파일을 저장할 때마다 자동으로 포맷팅을 실행한다.
    수동으로 Prettier를 돌릴 필요 없이, Ctrl + S만 눌러도 코드 스타일이 맞춰진다.

  • editor.defaultFormatter: "esbenp.prettier-vscode"
    -> 저장 시 실행될 기본 포맷터를 Prettier로 지정한다. 이 설정이 없으면 VSCode 기본 포맷터 또는 다른 확장 프로그램이 대신 실행될 수 있어, 팀원마다 포맷 결과가 달라질 수 있다.

  • editor.codeActionsOnSave.source.fixAll.eslint: "explicit"
    -> 저장 시 ESLint가 수정 가능한 규칙들을 자동으로 고쳐준다. "explicit"로 설정한 이유는 의도적으로 ESLint fix를 허용하겠다는 의미로, 예상치 못한 자동 수정으로 인한 혼란을 줄이기 위함이다.

    • 사용하지 않는 import 제거
    • ESLint --fix로 처리 가능한 규칙 자동 수정
    • 코드 스타일 및 간단한 에러 정리

추가적으로 함께 하면 좋은 작업들

초기 세팅을 하면서 필수는 아니지만, 함께 해두면 협업과 운영 측면에서 훨씬 편해지는 작업들도 정리해본다.

Discord WebHook 연동

PR 생성, merge등의 이벤트를 Discord로 바로 받아볼 수 있도록 WebHook을 연동했다.
이전에 정리한 글이 있어, 자세한 설정 과정은 해당 글을 참고하면 된다.


커스텀 라벨 생성

이슈, PR을 관리할 때 라벨이 잘 정리되어 있으면 작업 흐름을 한눈에 파악하기 좋다.
이 역시 이전에 정리해둔 글이 있어, 자세한 내용은 해당 글을 참고하면 된다.


PR 템플릿 생성

.github 폴더에 PULL_REQUEST_TEMPLATE.md 파일을 생성해 팀에서 사용할 PR 템플릿을 정의했다.

.github/
 └─ PULL_REQUEST_TEMPLATE.md

이렇게 설정해두면 실제로 PR을 생성할 때, 아래와 같이 미리 정의된 템플릿이 자동으로 노출된다. PR 내용 누락을 방지하고, 리뷰어가 변경 사항을 빠르게 파악하는 데 도움이 된다.


이슈 템플릿 생성

이슈 관리도 동일하게 템플릿을 적용했다.

.github/ISSUE_TEMPLATE 폴더에 issue-template.md 파일을 생성해 원하는 형식으로 작성한다.

.github/
 └─ ISSUE_TEMPLATE/
     └─ issue-template.md

이후 실제 이슈를 생성하면, 아래와 같이 설정한 이슈 템플릿이 자동으로 적용된다.


Branch 관련 설정

협업 중 실수로 잘못된 코드가 main 브랜치에 들어가는 것을 방지하기 위해, Branch 보호 규칙(Branch protection rule)도 함께 설정했다.

설정 경로는 아래와 같다.
Repository → Settings → Branches → Branch protection rules → Add rule

여기서 보호할 브랜치 이름(예: main)을 지정한 뒤, merge 조건을 하나씩 설정해주면 된다.
난 아래와 같은 조건을 활성화했다.

  • Require a pull request before merging
    → PR을 거치지 않으면 main 브랜치에 직접 merge할 수 없도록 설정

  • Require approvals
    → 최소 1명 이상의 리뷰 승인 후 merge 가능

또한 Repository → Settings → General 경로에서 Automatically delete head branches 옵션을 활성화해두면, PR이 merge되는 순간 해당 feature 브랜치가 원격에서 자동으로 삭제된다.


마무리

매번 프로젝트를 시작할 때마다 “이거 했었나…?” “초기 세팅할 게 또 뭐 있었지…?” 같은 고민을 반복했던 것 같다.
그래서 이번에는 초기 세팅 과정을 한 번 제대로 정리해서 글로 남겨두기로 했다.
앞으로는 새 프로젝트를 시작할 때 이 글을 보면서 차근차근 따라가면 될 것 같고, 적어도 뭔가 빼먹은 건 없는지 계속 고민하지 않아도 될 것 같다.
나처럼 매번 초기 세팅 단계에서 무엇을 했는지, 무엇을 더 해야 하는지 헷갈렸던 사람이 있다면 이 글이 작은 참고 자료나 체크리스트처럼 도움이 되었으면 좋겠다.

0개의 댓글