본문 바로가기
web

[1편] Next.js + Firebase 프로젝트 생성부터 초기 설정까지 (Windows 11)

by kkong93 2026. 3. 18.

나는 회사에서 안드로이드 개발을 주로 하는데, 어느 순간부터 Firebase Cloud Functions이랑 웹 대시보드까지 같이 맡게 됐다. 그러다 보니 자연스럽게 Next.js + TypeScript + Firebase 조합으로 프로젝트를 하나 세팅하게 됐는데, 이 과정을 처음부터 끝까지 정리해보려고 한다.

안드로이드 개발자 입장에서 웹 프로젝트 세팅은 진짜 낯설었다. build.gradle 대신 package.json, Gradle 대신 npm, Android Studio 대신 VS Code... 근데 한 번 해보면 구조 자체는 비슷하다. 이 글은 나처럼 안드로이드 하다가 갑자기 웹+서버도 해야 되는 사람한테 도움이 될 것 같다.


개발 환경

  • OS: Windows 11 (클린 설치 직후)
  • 에디터: Visual Studio Code
  • Node.js: v18 이상
  • Firebase CLI
  • 터미널: PowerShell

1. Node.js 설치

먼저 Node.js가 있어야 한다. https://nodejs.org 에서 LTS 버전을 받아서 설치하면 된다.

설치 후 터미널에서 확인:

node --version
# v18.x.x 또는 v20.x.x

npm --version
# 9.x.x 또는 10.x.x

여기서 주의할 게, Firebase Cloud Functions는 Node.js 버전에 민감하다. 나중에 배포할 때 Cloud Build 환경이랑 로컬 Node 버전이 다르면 오류 날 수 있으니까, 가능하면 18 버전을 쓰는 걸 추천한다.

Android 개발자를 위한 비유: Node.js는 JDK 같은 거고, npm은 Gradle 같은 역할이다. package.json이 build.gradle이라고 생각하면 편하다.


2. Firebase CLI 설치

npm으로 글로벌 설치한다:

npm install -g firebase-tools

설치 확인:

firebase --version
# 13.x.x

그리고 Firebase에 로그인:

firebase login

브라우저가 열리면서 Google 계정 로그인하라고 나온다. 로그인하면 터미널에 "Success! Logged in as xxxx@gmail.com" 이렇게 뜬다.


3. Next.js 프로젝트 생성

이제 프로젝트를 만든다:

npx create-next-app@latest my-project

물어보는 것들:

✔ Would you like to use TypeScript? → Yes
✔ Would you like to use ESLint? → Yes
✔ Would you like to use Tailwind CSS? → Yes
✔ Would you like to use `src/` directory? → Yes
✔ Would you like to use App Router? → Yes
✔ Would you like to customize the default import alias? → No

나는 TypeScript, ESLint, Tailwind CSS, App Router 전부 Yes로 했다. src/ 디렉토리도 쓰는 게 구조가 깔끔하다.

생성된 프로젝트 폴더로 이동:

cd my-project

Android 개발자를 위한 비유: npx create-next-app은 Android Studio에서 "New Project" 하는 것과 같다. 템플릿 선택하면 기본 구조가 자동으로 잡히는 것까지 똑같다.


4. npm install

프로젝트 폴더에 들어가면 package.json은 있지만 node_modules는 아직 없을 수 있다. (create-next-app이 자동으로 해주긴 하는데, 혹시 안 됐으면):

npm install

이게 끝나면 node_modules 폴더가 생기고, package-lock.json도 생성된다.

여기서 중요한 개념 하나:

  • package.json → 내가 설치하고 싶은 패키지 목록 (Gradle의 dependencies 블록)
  • package-lock.json → 실제로 설치된 패키지의 정확한 버전 잠금 파일 (Gradle의 gradle.lockfile)
  • node_modules/ → 실제 패키지 파일들이 들어있는 폴더 (Gradle cache 같은 것)

package-lock.json은 반드시 Git에 올려야 한다. 이걸 안 올리면 나중에 배포할 때 Cloud Build에서 npm ci 명령어가 실패한다. (이거 때문에 나중에 한참 삽질했는데, 트러블슈팅 편에서 자세히 다룬다.)


5. Firebase 초기화

프로젝트 루트에서:

firebase init

스페이스바로 선택하고 엔터로 넘어가는 방식이다:

◯ Firestore
◯ Functions
◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
◯ Storage

일단 이 글에서는 Hosting을 기준으로 설명한다. Functions도 같이 쓸 거면 같이 선택해도 된다.

Hosting 설정

? What do you want to use as your public directory? → out
? Configure as a single-page app (rewrite all urls to /index.html)? → No
? Set up automatic builds and deploys with GitHub? → No

여기서 public directory를 out으로 설정한 이유는, Next.js의 next export(또는 output: 'export')로 정적 빌드하면 out/ 폴더에 결과물이 나오기 때문이다.

근데 만약 SSR(서버사이드 렌더링)을 쓸 거면 이게 좀 달라진다. Firebase에서 Next.js SSR을 지원하는 firebase-frameworks 기능을 쓸 수도 있는데, 이건 배포 편에서 다룬다.

firebase.json 확인

초기화가 끝나면 firebase.json 파일이 생긴다:

{
  "hosting": {
    "public": "out",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}

.firebaserc 확인

{
  "projects": {
    "default": "my-firebase-project-id"
  }
}

여기서 Firebase 프로젝트가 2개 이상이면 이렇게 된다:

{
  "projects": {
    "default": "project-a",
    "production": "project-b"
  }
}

프로젝트 전환은 이렇게:

firebase use default      # project-a로 전환
firebase use production   # project-b로 전환
firebase use              # 현재 어떤 프로젝트인지 확인

나는 프로젝트가 2개 등록되어 있었는데, 이게 나중에 배포할 때 꼬이면 좀 골치아프다. 어떤 프로젝트에 배포하는 건지 꼭 확인하고 deploy 해야 한다.


6. 환경변수 설정

Firebase 관련 환경변수는 .env.local 파일에 넣는다:

# .env.local
NEXT_PUBLIC_FIREBASE_API_KEY=AIzaSyXXXXXXXXXX
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=my-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=my-project
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=my-project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=123456789
NEXT_PUBLIC_FIREBASE_APP_ID=1:123456789:web:abcdef

NEXT_PUBLIC_ 접두사가 붙어야 브라우저에서 접근 가능하다. 이거 안 붙이면 서버에서만 쓸 수 있는 환경변수가 된다.

중요: .env.local 파일은 절대 Git에 올리면 안 된다. API 키가 노출되니까.


7. .gitignore 설정

이게 진짜 중요하다. Node.js 프로젝트에서 .gitignore 잘못 설정하면 node_modules 같은 거대한 폴더가 올라가거나, 반대로 필요한 파일이 빠질 수 있다.

내가 쓰는 .gitignore:

# 의존성
node_modules/

# 빌드 결과물
.next/
out/
dist/

# 환경변수 (절대 올리지 마)
.env
.env.local
.env.production.local

# Firebase
.firebase/

# Firebase 서비스 계정 키 (이거 올리면 큰일남)
serviceAccountKey.json
*-firebase-adminsdk-*.json

# OS
.DS_Store
Thumbs.db

# IDE
.vscode/
*.swp
*.swo

# 디버그
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# TypeScript
*.tsbuildinfo

여기서 핵심적으로 절대 Git에 올리면 안 되는 것들:

  1. node_modules/ → 용량 어마어마함. npm install로 언제든 복구 가능
  2. .env.local → Firebase API 키 등 민감 정보
  3. serviceAccountKey.json → Firebase Admin SDK 키. 이거 올리면 프로젝트 털림
  4. .firebase/ → 배포 캐시. 올릴 필요 없음

반대로 반드시 Git에 올려야 하는 것:

  1. package-lock.json → 이거 안 올리면 배포 때 npm ci 실패함
  2. firebase.json → Firebase 설정
  3. .firebaserc → 프로젝트 매핑 (단, 민감 정보 없으면)

Android 개발자를 위한 비유: node_modules는 .gradle 캐시 폴더 같은 거고, package-lock.json은 gradle.lockfile이다. .gradle은 gitignore하지만 lockfile은 올리는 것처럼, 여기서도 똑같다.


8. 프로젝트 구조 정리

최종적으로 이런 구조가 된다:

my-project/
├── .firebaserc              ← Firebase 프로젝트 매핑
├── .gitignore               ← Git 제외 목록
├── firebase.json            ← Firebase 설정
├── next.config.ts           ← Next.js 설정
├── package.json             ← 패키지 목록
├── package-lock.json        ← 패키지 버전 잠금 (Git에 올려야 함!)
├── tailwind.config.ts       ← Tailwind CSS 설정
├── tsconfig.json            ← TypeScript 설정
├── .env.local               ← 환경변수 (Git 제외!)
├── src/
│   └── app/
│       ├── layout.tsx
│       ├── page.tsx
│       └── globals.css
├── public/
│   └── (정적 파일들)
└── node_modules/            ← (Git 제외!)

다음 편 예고

여기까지가 프로젝트 생성이랑 초기 설정이다. 다음 편에서는 실제로 firebase deploy로 배포하는 과정이랑, 내가 겪었던 opentelemetry 오류 + Cloud Build 실패 트러블슈팅을 자세히 다룬다.

솔직히 배포하면서 제일 많이 삽질한 부분이 2편 내용인데... 그냥 미리 말하면 package-lock.json이랑 node_modules 싱크 문제였다. 클로드 CLI한테 물어봐도 계속 해결 못해서 결국 직접 삽질해서 찾았다.

→ [2편] Firebase Hosting + Functions 배포하기 (+ Cloud Build 오류 트러블슈팅) → [3편] 환경변수 관리와 멀티 프로젝트 운영 팁

반응형

댓글