Azure Static Web Apps에 하이브리드 Next.js 웹 사이트 배포(미리 보기)
이 자습서에서는 React Server 구성 요소, SSR(서버 쪽 렌더링) 및 API 경로와 같은 Next.js 기능에 대한 지원을 사용하여 Next.js 웹 사이트를 Azure Static Web Apps에 배포하는 방법을 알아봅니다.
참고 항목
Next.js 하이브리드 지원은 미리 보기 상태입니다.
필수 조건
리소스 | 설명 |
---|---|
Azure 계정 | 활성 구독이 있는 Azure 계정이 없는 경우 체험 계정을 만들 수 있습니다. |
GitHub 계정 | Github 계정이 없으면 체험 계정을 만들 수 있습니다. |
Node.JS | 최신 버전의 Node.js를 설치합니다. |
Next.js CLI | 최신 버전의 Next.js CLI를 설치합니다. 자세한 내용은 Next.js 시작 가이드를 참조하세요. |
미리 보기에서 지원되지 않는 기능
Static Web Apps의 다음 기능은 하이브리드 렌더링을 사용하는 Next.js에서 지원되지 않습니다.
- Azure 서비스 선택: Azure Functions, Azure App Service, Azure Container Apps 또는 Azure API Management를 사용하여 연결된 API입니다.
- SWA CLI 기능: SWA CLI 로컬 에뮬레이션 및 배포입니다.
- 부분 기능 지원:
staticwebapp.config.json
파일의 다음 속성은 지원되지 않습니다.- 탐색 대체는 지원되지 않습니다.
- Next.js 애플리케이션 내의 경로에 대한 경로 재작성은
next.config.js
내에서 구성되어야 합니다. staticwebapp.config.json
파일 내의 구성은next.config.js
내의 구성보다 우선합니다.- 전체 기능 호환성을 위해 Next.js 사이트 구성은
next.config.js
를 사용하여 처리되어야 합니다.
- 빌드 건너뛰기: Next.js 애플리케이션의 경우
skip_api_build=true
Static Web Apps는 개발 종속성을 제거하거나 기본적으로 날카로운 패키지를 추가하지 않습니다. 이러한 최적화를 원하는 경우 전달skip_app_build=true
하기 전에 사용자 지정 빌드 단계에 추가합니다. - ISR(증분 정적 다시 생성): 이미지 캐싱은 지원되지 않습니다.
참고 항목
하이브리드 Next.js 애플리케이션의 최대 앱 크기는 250MB입니다. 최적화된 앱 크기에 Next.js의 독립 실행형 기능을 사용합니다. 이것으로 충분하지 않으면 앱 크기 요구 사항이 250MB 이상인 경우 정적 HTML 내보내기 Next.js를 사용하는 것이 좋습니다.
리포지토리 만들기
이 문서에서는 GitHub 템플릿 리포지토리를 사용하여 쉽게 시작할 수 있습니다. 이 템플릿에는 Azure Static Web Apps에 배포할 스타터 앱이 있습니다.
다음 위치로 이동하여 새 리포지토리를 만듭니다.
https://github.com/staticwebdev/nextjs-hybrid-starter/generate
리포지토리 이름을 my-first-static-web-app으로 지정합니다.
템플릿에서 리포지토리 만들기를 선택합니다.
정적 웹앱 만들기
이제 리포지토리가 생성되었으므로 Azure Portal에서 정적 웹앱을 만들 수 있습니다.
- Azure Portal로 이동합니다.
- 리소스 만들기를 선택합니다.
- Static Web Apps를 검색합니다.
- Static Web Apps를 선택합니다.
- 만들기를 실행합니다.
기본 사항 섹션에서 새 앱을 구성하고 GitHub 리포지토리에 연결하여 시작합니다.
설정 | 값 |
---|---|
Subscription | Azure 구독을 선택합니다. |
리소스 그룹 | 새로 만들기 링크를 선택하고 텍스트 상자에 static-web-apps-test를 입력합니다. |
이름 | 텍스트 상자에 my-first-static-web-app을 입력합니다. |
플랜 유형 | 무료를 선택합니다. |
Source | 필요한 경우 GitHub를 선택하고 GitHub에 로그인합니다. |
GitHub로 로그인을 선택하고 GitHub로 인증합니다.
GitHub로 로그인한 후 리포지토리 정보를 입력합니다.
설정 | 값 |
---|---|
조직 | 조직을 선택합니다. |
리포지토리 | my-first-web-static-app을 선택합니다. |
Branch | 기본을 선택합니다. |
참고 항목
리포지토리가 표시되지 않는 경우:
- GitHub에서 Azure Static Web Apps에 권한을 부여해야 할 수 있습니다. GitHub 리포지토리로 이동하여 설정 > 애플리케이션 > 권한 부여된 OAuth 앱으로 이동하고 Azure Static Web Apps를 선택한 다음, 권한 부여를 선택합니다.
- Azure DevOps 조직에서 Azure Static Web Apps에 권한을 부여해야 할 수 있습니다. 사용 권한을 부여하려면 조직의 소유자여야 합니다. OAuth를 통해 타사 애플리케이션 액세스를 요청합니다. 자세한 내용은 OAuth 2.0을 사용하여 REST API에 대한 액세스 권한 부여를 참조하세요.
빌드 세부 정보 섹션에서 선호하는 프런트 엔드 프레임워크와 관련된 구성 세부 정보를 추가합니다.
빌드 사전 설정 드롭다운에서 Next.js를 선택합니다.
앱 위치 상자에서 기본값을 유지합니다.
Api 위치 상자를 비워 둡니다.
출력 위치 상자를 비워둡니다.
검토 + 만들기를 선택합니다.
웹 사이트 보기
정적 앱을 배포하는 데는 두 가지 측면이 있습니다. 먼저 앱을 구성하는 기본 Azure 리소스를 만듭니다. 두 번째는 애플리케이션을 빌드하고 게시하는 워크플로입니다.
새 정적 사이트로 이동하려면 먼저 배포 빌드가 실행을 완료해야 합니다.
Static Web Apps 개요 창에는 웹앱과 상호 작용하는 데 도움이 되는 일련의 링크가 표시됩니다.
GitHub Actions 실행 상태를 확인하려면 여기를 선택하세요.라는 배너를 선택하면 리포지토리에 대해 실행 중인 GitHub Actions로 이동됩니다. 배포 작업이 완료되었는지 확인되면 생성된 URL을 통해 웹 사이트로 이동할 수 있습니다.
GitHub Actions 워크플로가 완료되면 URL 링크를 선택하여 새 탭에서 웹 사이트를 열 수 있습니다.
변경하려면 Next.js 프로젝트를 로컬로 설정합니다.
새 리포지토리를 컴퓨터에 복제합니다. <GITHUB_ACCOUNT_NAME>을 계정 이름으로 바꾸어야 합니다.
git clone http://github.com/<GITHUB_ACCOUNT_NAME>/my-first-static-web-app
Visual Studio Code 또는 원하는 코드 편집기에서 프로젝트를 엽니다.
서버 쪽 렌더링 설정
관리되는 백 엔드는 모든 계획의 모든 하이브리드 Next.js 배포에 대해 자동으로 사용할 수 있습니다. 그러나 사용자 지정 백 엔드를 사이트에 할당하여 성능을 미세 조정하고 백 엔드를 보다 효율적으로 제어할 수 있습니다. 관리되는 백 엔드 간에 연결된 백 엔드로 전환하면 사이트에서 가동 중지 시간이 발생하지 않습니다.
사용자 고유의 백 엔드 가져오기
백엔드를 가져올 때 성능을 개선하고 Next.js 서버 측 렌더링을 더 잘 제어할 수 있습니다. 다음 단계를 사용하여 사이트에 대한 사용자 지정 백 엔드를 설정합니다.
다음 단계에서는 사용자 지정 백 엔드를 표준 플랜 및 정적 웹앱 위에 연결하는 방법을 보여 줍니다.
참고 항목
연결된 백 엔드는 표준 플랜 이상을 사용하는 사이트에서만 사용할 수 있습니다.
Azure Portal에서 정적 웹앱으로 이동합니다.
설정을 선택한 다음, 측면 메뉴에서 API를 선택합니다.
연결된 백 엔드 구성을 선택합니다.
새 App Service 요금제를 만들거나 기존 App Service 요금제를 선택합니다.
선택한 App Service 요금제는 S1 SKU 이상을 사용해야 합니다.
링크를 클릭합니다.
서버 구성 요소를 사용하여 서버 렌더링 데이터 추가
앱 라우터를 사용하여 Next.js 프로젝트에 서버 렌더링 데이터를 추가하려면 Next.js 구성 요소를 편집하여 구성 요소에서 데이터를 렌더링하는 서버 쪽 작업을 추가합니다. 기본적으로 Next.js 구성 요소는 서버 렌더링이 가능한 서버 구성 요소입니다.
app/page.tsx
파일을 열고 서버 쪽 계산 변수의 값을 설정하는 작업을 추가합니다. 예를 들어, 데이터 페치 또는 기타 서버 작업이 포함됩니다.export default function Home() { const timeOnServer = new Date().toLocaleTimeString('en-US'); return( ... ); }
next/cache
에서unstable_noStore
를 가져오고Home
구성 요소 내에서 호출하여 경로가 동적으로 렌더링되는지 확인합니다.import { unstable_noStore as noStore } from 'next/cache'; export default function Home() { noStore(); const timeOnServer = new Date().toLocaleTimeString('en-US'); return( ... ); }
참고 항목
이 예에서는 이 구성 요소의 동적 렌더링을 강제하여 서버의 현재 시간에 대한 서버 렌더링을 보여 줍니다. Next.js의 앱 라우터 모델은 개별 데이터 요청을 캐싱하여 Next.js 앱의 성능을 최적화하는 것이 좋습니다. Next.js의 데이터 페치 및 캐싱에 대해 자세히 알아봅니다.
서버 쪽 데이터를 렌더링하려면 app/pages.tsx에서
Home
구성 요소를 업데이트합니다.import { unstable_noStore as noStore } from 'next/cache'; export default function Home() { noStore(); const timeOnServer = new Date().toLocaleTimeString('en-US'); return( <main className="flex min-h-screen flex-col items-center justify-between p-24"> <div> This is a Next.js application hosted on Azure Static Web Apps with hybrid rendering. The time on the server is <strong>{timeOnServer}</strong>. </div> </main> ); }
API 경로 추가
서버 구성 요소 외에도 Next.js는 Next.js 애플리케이션에 대한 API 경로를 만드는 데 사용할 수 있는 경로 처리기를 제공합니다. 클라이언트 구성 요소에서 이러한 API를 가져올 수 있습니다.
먼저 API 경로를 추가합니다.
app/api/currentTime/route.tsx
에 새 파일을 만듭니다. 이 파일에는 새 API 엔드포인트에 대한 경로 처리기가 포함되어 있습니다.API에서 데이터를 반환하는 처리기 함수를 추가합니다.
import { NextResponse } from 'next/server'; export const dynamic = 'force-dynamic'; export async function GET() { const currentTime = new Date().toLocaleTimeString('en-US'); return NextResponse.json({ message: `Hello from the API! The current time is ${currentTime}.` }); }
app/components/CurrentTimeFromAPI.tsx
에 새 파일을 만듭니다. 이 구성 요소는 브라우저에서 API를 가져오는 클라이언트 구성 요소에 대한 컨테이너를 만듭니다.이 파일에서 API를 가져오는 클라이언트 구성 요소를 추가합니다.
'use client'; import { useEffect, useState } from 'react'; export function CurrentTimeFromAPI(){ const [apiResponse, setApiResponse] = useState(''); const [loading, setLoading] = useState(true); useEffect(() => { fetch('/api/currentTime') .then((res) => res.json()) .then((data) => { setApiResponse(data.message); setLoading(false); }); }, []); return ( <div className='pt-4'> The message from the API is: <strong>{apiResponse}</strong> </div> ) }
이 클라이언트 구성 요소는 로드가 완료된 후 구성 요소를 렌더링하기 위해 useEffect
React 후크를 사용하여 API를 가져옵니다. 'use client'
지시문은 이 요소를 클라이언트 구성 요소로 식별합니다. 자세한 내용은 클라이언트 구성 요소를 참조하세요.
app/page.tsx를 편집하여
CurrentTimeFromAPI
클라이언트 구성 요소를 가져오고 렌더링합니다.import { unstable_noStore as noStore } from 'next/cache'; import { CurrentTimeFromAPI } from './components/CurrentTimeFromAPI'; export default function Home() { noStore(); const timeOnServer = new Date().toLocaleTimeString('en-US'); return( <main className="flex min-h-screen flex-col items-center justify-between p-24"> <div> This is a Next.js application hosted on Azure Static Web Apps with hybrid rendering. The time on the server is <strong>{timeOnServer}</strong>. </div> <CurrentTimeFromAPI /> </main> ); }
API 경로의 결과가 페이지에 표시됩니다.
Next.js의 런타임 버전 구성
특정 Next.js 버전에는 특정 Node.js 버전이 필요합니다. 특정 Node 버전을 구성하려면 package.json
파일의 engines
속성을 설정하여 버전을 지정할 수 있습니다.
{
...
"engines": {
"node": "18.17.1"
}
}
Next.js에 대한 환경 변수 설정
Next.js는 빌드 시와 요청 시 환경 변수를 사용하여 서버 쪽 렌더링을 통해 정적 페이지 생성과 동적 페이지 생성을 모두 지원합니다. 따라서 빌드 및 배포 작업 내와 Azure Static Web Apps 리소스의 환경 변수 모두에서 환경 변수를 설정합니다.
...
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for GitHub integrations (i.e. PR comments)
action: "upload"
app_location: "/"
api_location: ""
output_location: ""
env:
DB_HOST: ${{ secrets.DB_HOST }}
DB_USER: ${{ secrets.DB_USER }}
DB_DATABASE: ${{ secrets.DB_DATABASE }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DB_PORT: ${{ secrets.DB_PORT }}
...
독립 실행형 기능 사용
애플리케이션 크기가 250MB를 초과하면 Next.js 출력 파일 추적 기능이 앱 크기를 최적화하고 성능을 개선하는 데 도움이 됩니다.
출력 파일 추적은 필요한 패키지 종속성이 있는 전체 애플리케이션의 압축된 버전을 만듭니다. 이 패키지는 .next/standalone이라는 폴더에 기본 제공됩니다. 이 패키지를 사용하면 node_modules 종속성 없이 앱이 자체적으로 배포할 수 있습니다.
standalone
기능을 사용하도록 설정하려면 next.config.js
에 다음 속성을 추가합니다.
module.exports ={
output:"standalone",
}
다음으로, package.json
파일에서 build
명령을 구성하여 정적 파일을 독립 실행형 출력에 복사합니다.
{
...
"scripts": {
...
"build": "next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/"
...
}
...
}
배포를 위한 라우팅 및 미들웨어 구성
사용자 지정 리디렉션, 다시 쓰기 및 미들웨어를 사용하여 경로의 Next.js 프로젝트 핸들을 구성할 수 있습니다. 이러한 처리기는 일반적으로 인증, 개인 설정, 라우팅 및 국제화에 사용됩니다. 사용자 지정 처리는 Next.js 사이트의 기본 라우팅에 영향을 미치며 구성은 Static Web Apps의 호스팅과 호환되어야 합니다.
Static Web Apps는 빌드 시 사이트에 페이지를 추가하여 Next.js 사이트가 성공적으로 배포되었는지 유효성을 검사합니다. 페이지 이름은 public/.swa/health.html
이며 Static Web Apps는 /.swa/health.html
로 이동하고 성공적인 응답을 확인하여 사이트의 성공적인 시작 및 배포를 확인합니다. 리디렉션 및 재작성을 포함하는 미들웨어 및 사용자 지정 라우팅은 /.swa/health.html
경로 액세스에 영향을 미쳐 Static Web Apps의 배포 유효성 검사를 방해할 수 있습니다. Static Web Apps에 성공적으로 배포하기 위해 미들웨어 및 라우팅을 구성하려면 다음 단계를 따릅니다.
미들웨어 구성의
middleware.ts
(또는.js
) 파일에서.swa
로 시작하는 경로를 제외합니다.export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - .swa (Azure Static Web Apps) */ '/((?!.swa).*)', ], }
next.config.js
에서 리디렉션을 구성하여.swa
(으)로 시작하는 경로 제외module.exports = { async redirects() { return [ { source: '/((?!.swa).*)<YOUR MATCHING RULE>', destination: '<YOUR REDIRECT RULE>', permanent: false, }, ] }, };
next.config.js
에서 재작성 규칙을 구성하여.swa
로 시작하는 경로 제외module.exports = { async rewrites() { return { beforeFiles: [ { source: '/((?!.swa).*)<YOUR MATCHING RULE>', destination: '<YOUR REWRITE RULE>', } ] } }, };
이러한 코드 조각은 사용자 지정 라우팅 또는 미들웨어가 이러한 요청을 처리하지 못하도록 .swa
(으)로 시작하는 경로를 제외합니다. 이러한 규칙은 배포 유효성 검사 중에 경로가 예상대로 해결되도록 합니다.
Next.js 로깅 사용
Next.js 서버 API 문제 해결 모범 사례에 따라 API에 로깅을 추가하여 이러한 오류를 catch합니다. Azure에서 로깅은 Application Insights를 사용합니다. 이 SDK를 미리 로드하려면 사용자 지정 시작 스크립트를 만들어야 합니다. 자세히 알아보려면 다음을 수행합니다.
리소스 정리
이 애플리케이션을 계속 사용하지 않을 경우 다음 단계를 통해 Azure Static Web App 인스턴스를 삭제할 수 있습니다.
- Azure Portal을 엽니다.
- 위쪽 검색 창에서 my-first-web-static-app을 검색합니다.
- 앱 이름을 선택합니다.
- 삭제를 선택합니다.
- 예를 선택하여 삭제 작업을 확인합니다(이 작업은 완료하는 데 몇 분 정도 걸릴 수 있음).