在 Azure Static Web Apps 上部署混合式Next.js網站 (預覽)

在本教學課程中,您將瞭解如何使用 React Server 元件、伺服器端轉譯 (SSR) 和 API 路由等Next.js功能的支援,將Next.js網站部署Azure Static Web Apps

注意

Next.js混合式支持處於預覽狀態。

必要條件

預覽中不支援的功能

使用混合式轉譯Next.js不支持靜態 Web Apps 的下列功能:

  • 使用 Azure Functions、Azure App 服務、Azure Container Apps 或 Azure API 管理 的連結 API。
  • SWA CLI 本機模擬和部署。
  • 檔案的部分 staticwebapp.config.json 支援。
    • 不支持導覽後援。
    • 必須在內設定路由重寫至Next.js應用程式內的 next.config.js路由。
    • 檔案內的 staticwebapp.config.json 組態優先於內的 next.config.js組態。
    • 應使用 來處理 next.config.js Next.js月台的設定,以取得完整的功能相容性。
  • skip_app_buildskip_api_build 無法在部署映像內 Azure/static-web-apps-deploy@v1 使用。
  • 累加式靜態重新產生 (ISR) 不支援快取映像。

注意

混合式Next.js應用程式的應用程式大小上限為 250 MB。 針對 優化的應用程式大小使用獨立 功能,Next.js。 如果這還不夠,請考慮使用 導出的靜態 HTML Next.js 如果您的應用程式大小需求超過 250 MB。

建立存放庫

本文使用 GitHub 範本存放庫,讓您輕鬆開始使用。 此範本包含要部署至 Azure Static Web Apps 的入門應用程式。

  1. 流覽至下列位置以建立新的存放庫。

    https://github.com/staticwebdev/nextjs-hybrid-starter/generate

  2. 將您的存放庫 命名為 my-first-static-web-app

  3. 選取 [從範本建立存放庫]

    從範本按鈕建立存放庫的螢幕快照。

建立靜態 Web 應用程式

現在已建立存放庫,您可以從 Azure 入口網站 建立靜態 Web 應用程式。

  1. 前往 Azure 入口網站
  2. 選取 [建立資源]
  3. 搜尋 靜態 Web Apps
  4. 選取 [Static Web Apps]
  5. 選取 建立

在 [ 基本] 區 段中,從設定新的應用程式並將其連結至 GitHub 存放庫開始。

Azure 入口網站 中 [基本] 區段的螢幕快照。

設定
訂用帳戶 選取 Azure 訂閱。
資源群組 選取 [ 建立新 連結],然後在文本框中輸入 static-web-apps-test
名稱 在文本框中輸入 my-first-static-web-app
方案類型 選取 [免費]
Azure Functions 和暫存詳細資料 選取最接近您的區域。
來源 選取 [GitHub]。

選取 [使用 GitHub 登入],並使用 GitHub 進行驗證。

使用 GitHub 登入之後,請輸入存放庫資訊。

設定
組織 選取您的組織。
存放庫 選取 my-first-web-static-app
分支 選取 main

Azure 入口網站 中存放庫詳細數據的螢幕快照。

注意

如果您沒有看到任何存放庫:

  • 您可能需要在 GitHub 中授權 Azure Static Web Apps。 流覽至您的 GitHub 存放庫,並移至 [設定 > 應用程式>授權的 OAuth Apps],選取 [Azure 靜態 Web 應用程式],然後選取 [授與]。
  • 您可能需要在 Azure DevOps 組織中授權 Azure Static Web Apps。 您必須是組織的擁有者,才能授與許可權。 透過 OAuth 要求第三方應用程式存取權。 如需詳細資訊,請參閱 使用 OAuth 2.0 授權 REST API 的存取權。

在 [建置詳細數據]段中,新增您慣用前端架構特有的組態詳細數據。

  1. 從 [建置預設] 下拉式清單中選取 [Next.js]。

  2. 將預設值保留在 [應用程式位置] 方塊中

  3. 將 Api 位置方塊保留空白。

  4. 將 [ 應用程式成品位置] 方塊保留空白。

選取 [檢閱 + 建立]。

[建立] 按鈕的螢幕快照。

檢視網站

部署靜態應用程式有兩個層面。 第一個會建立構成您應用程式的基礎 Azure 資源。 第二個是建置和發佈應用程式的工作流程。

您必須先完成執行部署組建,才能移至新的靜態月臺。

[靜態 Web 應用程式概觀] 視窗會顯示一系列連結,可協助您與 Web 應用程式互動。

Azure Static Web Apps 概觀視窗的螢幕快照。

在橫幅上選取,選取這裡以檢查 GitHub Actions 執行的狀態,會帶您前往針對存放庫執行的 GitHub Actions。 確認部署作業已完成之後,您就可以透過產生的URL前往您的網站。

GitHub Actions 工作流程完成後,您可以選取 URL 連結,以在新索引標籤中開啟網站。

在本機設定您的Next.js項目進行變更

  1. 將新的存放庫複製到您的電腦。 請務必以您的帳戶名稱取代 <YOUR_GITHUB_ACCOUNT_NAME> 。

    git clone http://github.com/<YOUR_GITHUB_ACCOUNT_NAME>/my-first-static-web-app
    
  2. 在 Visual Studio Code 或您慣用的程式代碼編輯器中開啟專案。

使用伺服器元件新增伺服器轉譯的數據

若要使用應用程式路由器在Next.js專案中新增伺服器轉譯的數據,請編輯Next.js元件,以新增伺服器端作業以轉譯元件中的數據。 根據預設,Next.js元件是 可以轉譯伺服器的伺服器元件

  1. 開啟檔案並 app/page.tsx 新增作業,以設定計算伺服器端的變數值。 範例包括擷取數據或其他伺服器作業。

    export default function Home() {
        const timeOnServer = new Date().toLocaleTimeString('en-US');
        return(
            ...
        );
    }
    
  2. next/cacheunstable_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中的數據擷取和快取。

  3. Home更新 app/pages.tsx 中的元件,以轉譯伺服器端數據。

    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 路由開始。

  1. 在建立新的檔案 app/api/currentTime/route.tsx。 此檔案會保存新 API 端點的路由處理程式。

  2. 新增處理程式函式以從 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}.`
        });
    }
    
  3. 在建立新的檔案 app/components/CurrentTimeFromAPI.tsx。 此元件會為從瀏覽器擷取 API 的用戶端元件建立容器。

  4. 新增可擷取此檔案中 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' 這個項目識別為用戶端元件。 如需詳細資訊,請參閱 用戶端元件

  1. 編輯 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>
        );
    }
    
  2. API 路由的結果會顯示在頁面上。

顯示 API 路由輸出的螢幕快照。

設定Next.js的運行時間版本

某些Next.js版本需要特定的Node.js版本。 若要設定特定的 Node 版本,您可以設定檔案 package.json 的 'engine' 屬性來指定版本。

{
  ...
  "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路由和中間件以部署至 Azure Static Web Apps

您可以將Next.js項目設定為具有重新導向、重寫和中間件的自定義路由處理。 這些處理程式通常用於驗證、個人化、路由和國際化。 自定義處理會影響Next.js月臺的預設路由,且設定必須與靜態 Web Apps 上的裝載相容。

靜態 Web Apps 會藉由在建置階段將頁面新增至您的網站,來驗證您的Next.js網站已成功部署。 頁面名為 public/.swa/health.html,靜態 Web Apps 會流覽至並驗證成功的回應, /.swa/health.html 以驗證網站的成功啟動和部署。 中間件和自定義路由,包括重新導向和重寫,可能會影響路徑的 /.swa/health.html 存取,這可以防止靜態 Web Apps 的部署驗證。 若要設定成功部署至 Static Web Apps 的中間件和路由,請遵循下列步驟:

  1. 排除中間件組態中middleware.ts開頭為 .swa (或.js) 檔案的路由。

    export const config = {
      matcher: [
        /*
         * Match all request paths except for the ones starting with:
         * - .swa (Azure Static Web Apps)
         */
        '/((?!.swa).*)',
      ],
    }
    
  2. 將您的重新導向設定為 next.config.js 從 開始排除路由 .swa

    module.exports = {
        async redirects() {
            return [
              {
                source: '/((?!.swa).*)<YOUR MATCHING RULE>',
                destination: '<YOUR REDIRECT RULE>', 
                permanent: false,
              },
            ]
        },
    };
    
  3. 將您的重寫設定為 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 以攔截這些錯誤。 Azure 上的記錄會使用 Application Insights。 若要預先載入此 SDK,您必須建立自訂啟動文稿。 若要深入了解:

清除資源

如果您不打算繼續使用此應用程式,您可以透過下列步驟刪除 Azure Static Web Apps 實例:

  1. 開啟 Azure 入口網站
  2. 從頂端搜尋列搜尋 my-first-web-static-app
  3. 選取應用程式名稱。
  4. 選取 [刪除]
  5. 選取 [ ] 以確認刪除動作(此動作可能需要幾分鐘的時間才能完成)。

下一步