TanStack Router를 프로덕션에 배포하는 방법
이 가이드에서는 널리 사용되는 호스팅 플랫폼에 TanStack Router 애플리케이션을 배포하는 방법을 설명합니다.
빠른 시작
단일 페이지 애플리케이션(SPA)은 클라이언트 측 라우팅을 처리하기 위해 특별한 서버 구성이 필요합니다. 모든 라우트에 index.html을 제공하도록 호스팅 플랫폼을 구성하면 TanStack Router가 내비게이션을 처리할 수 있습니다.
Netlify 배포
1. _redirects 파일 만들기
public/_redirects 파일(또는 빌드 출력 디렉터리의 _redirects 파일)을 만듭니다.
/* /index.html 200
2. 대안: netlify.toml
프로젝트 루트에 netlify.toml 파일을 만듭니다.
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[build]
publish = "dist"
command = "npm run build"
3. TanStack Start(SSR)의 경우
[build]
publish = ".output/public"
command = "npm run build"
[functions]
directory = ".output/server"
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/server"
status = 200
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
Cloudflare Pages
1. _redirects 파일 만들기
public/_redirects 파일을 만듭니다.
/* /index.html 200
2. 대안: _routes.json
더 세밀하게 제어하려면 public/_routes.json 파일을 만듭니다.
{
"version": 1,
"include": ["/*"],
"exclude": ["/api/*"]
}
3. TanStack Start(SSR)의 경우
SSR을 지원하도록 functions/_middleware.ts를 만듭니다.
export const onRequest: PagesFunction = async (context) => {
// Handle SSR requests
return await handleSSR(context)
}
4. Git으로 배포
- GitHub 저장소를 Cloudflare Pages에 연결합니다.
- 빌드 설정을 지정합니다.
- 빌드 명령:
npm run build - 빌드 출력 디렉터리:
dist - 루트 디렉터리: (비워 둡니다)
- 빌드 명령:
5. Wrangler CLI로 배포
# Install Wrangler
npm install -g wrangler
# Deploy
wrangler pages publish dist --project-name=my-app
Vercel 배포
1. vercel.json 만들기
프로젝트 루트에 vercel.json 파일을 만듭니다.
{
"rewrites": [
{
"source": "/(.*)",
"destination": "/index.html"
}
]
}
2. TanStack Start(SSR) 애플리케이션의 경우
SSR과 함께 TanStack Start를 사용한다면 다음 구성을 대신 사용합니다.
{
"functions": {
"app/server.ts": {
"runtime": "nodejs18.x"
}
},
"routes": [
{
"src": "/(.*)",
"dest": "/api/server"
}
]
}
3. 빌드 구성
package.json에 올바른 빌드 스크립트가 있는지 확인합니다.
{
"scripts": {
"build": "vite build",
"preview": "vite preview"
}
}
4. 배포
# Install Vercel CLI
npm i -g vercel
# Deploy
vercel
GitHub Pages
1. 404.html 만들기
GitHub Pages에는 index.html을 복제한 404.html 파일이 필요합니다.
# After building
cp dist/index.html dist/404.html
2. vite.config.js 업데이트
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'
export default defineConfig({
base: '/your-repo-name/', // Replace with your repository name
plugins: [
tanstackRouter({
target: 'react',
autoCodeSplitting: true,
}),
react(),
],
build: {
outDir: 'dist',
},
})
3. GitHub Actions 워크플로
.github/workflows/deploy.yml을 만듭니다.
name: Deploy to GitHub Pages
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Create 404.html
run: cp dist/index.html dist/404.html
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
Firebase Hosting
1. firebase.json 만들기
{
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
2. 배포
# Install Firebase CLI
npm install -g firebase-tools
# Login and initialize
firebase login
firebase init hosting
# Build and deploy
npm run build
firebase deploy
Apache 서버
빌드 출력 디렉터리에 .htaccess 파일을 만듭니다.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
Nginx
Nginx 서버 블록에 다음 구성을 추가합니다.
server {
listen 80;
server_name your-domain.com;
root /path/to/your/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# Optional: Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Docker 배포
1. Dockerfile 만들기
# Build stage
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
2. nginx.conf 만들기
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
3. 빌드 및 실행
docker build -t my-tanstack-app .
docker run -p 80:80 my-tanstack-app
프로덕션 체크리스트
배포하기 전에 다음 항목을 확인합니다.
- 호스팅 플랫폼 구성 파일을 만들었는지 확인합니다.
- 하위 디렉터리에 배포한다면 올바른 base path를 설정했는지 확인합니다.
-
VITE_접두사를 사용해 환경 변수를 구성했는지 확인합니다. - 직접 URL에 접근해 모든 라우트를 테스트했는지 확인합니다.
- 정적 애셋이 올바르게 로드되는지 확인합니다.
일반적인 문제
페이지 새로 고침 시 404 오류
문제: 앱 내부에서 이동할 때는 라우트가 작동하지만 페이지를 새로 고치면 404가 표시됩니다.
원인: 서버가 SPA에 존재하지 않는 /about/index.html과 같은 파일을 찾습니다.
해결 방법: 호스팅 플랫폼에 맞게 위에 설명한 구성 파일을 추가합니다.
로컬에서는 작동하지만 배포하면 앱이 중단됨
문제: 개발 환경에서는 앱이 작동하지만 프로덕션에서 오류가 표시됩니다.
해결 방법:
- 하위 디렉터리 배포:
vite.config.js에서 base path를 구성합니다.export default defineConfig({
base: '/my-app/', // Match your deployment path
}) - 빌드 출력 불일치: 빌드 디렉터리가 호스팅 구성과 일치하는지 확인합니다.
export default defineConfig({
build: {
outDir: 'dist', // Must match hosting platform setting
},
}) - 환경 변수:
VITE_를 접두사로 추가하고 다시 빌드합니다.# .env
VITE_API_URL=https://api.example.com
애셋이 로드되지 않음(CSS/JS 404)
문제: 앱은 로드되지만 스타일이 깨지거나 JavaScript를 로드하지 못합니다.
해결 방법:
- 호스팅 구성에서 빌드 출력 디렉터리를 확인합니다.
- Vite의 public path 구성을 확인합니다.
- 정적 파일 제공이 올바르게 구성되었는지 확인합니다.
일반적인 다음 단계
배포 후 다음 작업을 수행할 수 있습니다.
- 기본 인증 설정 방법 - 인증으로 애플리케이션을 보호합니다.
- React Router v7에서 마이그레이션 - React Router에서 마이그레이션하는 경우의 전체 마이그레이션 가이드입니다.
- 서버 측 렌더링(SSR) 설정 방법
관련 리소스
- 배포 예시 - 공식 예시