나는 회사에서 안드로이드 개발을 주로 하는데, 어느 순간부터 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에 올리면 안 되는 것들:
- node_modules/ → 용량 어마어마함. npm install로 언제든 복구 가능
- .env.local → Firebase API 키 등 민감 정보
- serviceAccountKey.json → Firebase Admin SDK 키. 이거 올리면 프로젝트 털림
- .firebase/ → 배포 캐시. 올릴 필요 없음
반대로 반드시 Git에 올려야 하는 것:
- package-lock.json → 이거 안 올리면 배포 때 npm ci 실패함
- firebase.json → Firebase 설정
- .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편] 환경변수 관리와 멀티 프로젝트 운영 팁
'web' 카테고리의 다른 글
| [3편] 환경변수 관리와 Firebase 멀티 프로젝트 운영 팁 (0) | 2026.03.18 |
|---|---|
| [2편] Firebase Hosting 배포하기 + Cloud Build 오류 트러블슈팅 (Windows 11) (0) | 2026.03.18 |
| 해외에서 진짜 많이 쓰는 웹 UI 레퍼런스 5가지 (0) | 2026.03.18 |
댓글