iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0
Modern Web

Angular:踏上現代英雄之旅系列 第 27

Day 27|部署上線:ng build 與 GitHub Pages

  • 分享至 

  • xImage
  •  

哈囉,各位邦友們!
歷經從 Standalone 專案起手,走過服務、HTTP、Signals 與 @defer
今天的目標,就是讓 Day01~Day26 打造的專案透過 ng build 打包,並部署到 GitHub Pages,正式對外公開。

今日任務

  1. 回顧前三週的成果,確認專案已具備上線條件。
  2. 使用 ng build 產出可部署的靜態資源,理解基礎設定與常見參數。
  3. 完成 GitHub Pages 部署,並擴充部署清單,評估更真實的雲端託管管道。

一、Day01~Day26 的鋪陳如何支援部署?

  • 第 1 週(Day01~Day07):我們建立 Standalone 專案、拆分元件、掌握控制流與 ngModel。這些讓專案結構清晰、依賴明確,是部署前檢視可維護性的第一步。
  • 第 2 週(Day08~Day18):服務化資料、串接 HTTP、完成 CRUD、導入 NgOptimizedImage。這些功能證明應用能處理真實資料流,並已加入錯誤處理與 UI 回饋,避免上線後才驚覺缺少保護措施。
  • 第 3 週(Day19~Day26):我們將 Reactive Forms、Signals、resource()@defer 應用到位,並在 Day26 總結時完成整體驗收。這意味著狀態管理與效能策略都已就緒,可以放心對外展示。

二、以 ng build 打包生產版

1. 確認環境與設定

  • Node.js 版本需達 v20 以上 。
  • 進入專案根目錄(本系列為 hero-journey),執行 npm installnpm ci,確保依賴完整。
  • 開啟 angular.json 可以看到以下片段:
"build": {
    "builder": "@angular/build:application",
    "options": {
    "browser": "src/main.ts",
    "tsConfig": "tsconfig.app.json",
    "inlineStyleLanguage": "scss",
    "assets": [
        {
        "glob": "**/*",
        "input": "public"
        }
    ],
    "styles": [
        "src/styles.scss"
    ],
    "server": "src/main.server.ts",
    "outputMode": "server",
    "ssr": {
        "entry": "src/server.ts"
    }
    },
    "configurations": {
    "production": {
        "budgets": [
        {
            "type": "initial",
            "maximumWarning": "500kB",
            "maximumError": "1MB"
        },
        {
            "type": "anyComponentStyle",
            "maximumWarning": "4kB",
            "maximumError": "8kB"
        }
        ],
        "outputHashing": "all"
    },
    "development": {
        "optimization": false,
        "extractLicenses": false,
        "sourceMap": true
    }
    },
    "defaultConfiguration": "production"
}

預設為 SSR 專案(outputMode: "server"),代表 ng build 會輸出 dist/hero-journey/browserdist/hero-journey/server。GitHub Pages 僅能托管靜態檔案,因此稍後要取用 browser 目錄內容。

2. 加入專案路徑的 baseHref

GitHub Pages 會把網站掛在 https://<使用者>.github.io/<repo>/,因此需要設定 baseHref 讓路由與資源路徑正確。

有兩種做法:

  • 一次性參數
    npx ng build --configuration production --output-mode=static --base-href "/hero-journey/"
    
  • 長期設定:在 angular.jsonbuild.options 增加 "baseHref": "/hero-journey/",或建立 project.json 環境設定檔。

小提示:如果你使用自己的 GitHub 仓庫,將 /hero-journey/ 替換成實際 repo 名稱即可。

3. 預渲染英雄詳細頁面

靜態部署時,Angular 會依據 app.routes.server.ts 的設定產生預渲染路徑。為了避免 /detail/:id 在 GitHub Pages 重新整理時出現 404,我們新增以下設定,讓 CLI 在建置時替每位英雄產生對應的靜態頁面:

import { DEFAULT_HEROES } from './in-memory-data';

export const serverRoutes: ServerRoute[] = [
  {
    path: 'detail/:id',
    renderMode: RenderMode.Prerender,
    getPrerenderParams: async () =>
      DEFAULT_HEROES.map((h) => ({ id: String(h.id) })),
  },
  {
    path: '**',
    renderMode: RenderMode.Prerender,
  },
];

這段程式碼會迭代 DEFAULT_HEROES,並把每個 id 轉成字串傳給 getPrerenderParams。也因此我們將 DEFAULT_HEROESsrc/app/in-memory-data.ts 匯出,讓同一份資料可供 SSR 與 API 模擬共用;未來若改成呼叫後端,只需在此改成抓取真實資料清單即可銜接。

4. 執行建置

npm run build -- --configuration production --output-mode browser --base-href "/hero-journey/"
  • npm run build 透過 CLI 執行 ng build
  • --configuration production 套用壓縮、tree-shaking 等最佳化。
  • --output-mode=static 強制產出純前端資源,避免把 dist/.../server 誤傳到靜態主機。
  • --base-href 確保靜態資源尋址正確。

5. 檢查輸出結構

建置完成後會看到類似結果:

dist/hero-journey/
├── browser/
│   ├── index.html
│   ├── main-HASH.js
│   ├── styles-HASH.css
└── 3rdpartylicenses.txt
└── prerendered-routes.json

部署到 GitHub Pages 時,只需要 browser/ 目錄即可。若想預覽生產版,直接在本機啟動簡易伺服器:

npx http-server dist/hero-journey/browser -p 4200

三、部署到 GitHub Pages

1. 準備 GitHub 儲存庫

  1. hero-journey 推送至 GitHub。
  2. 確認主分支 (mainmaster) 已開啟 GitHub Actions。

2. 方法一:使用 angular-cli-ghpages

最簡單、快速的方式,適合個人專案。

npm install angular-cli-ghpages --save-dev
npm run build -- --configuration production --output-mode=static --base-href "/hero-journey/"
npx angular-cli-ghpages --dir=dist/hero-journey/browser
  • 第三行會自動建立 gh-pages 分支並推送至遠端。
  • 完成後,到 GitHub 專案的 Settings → Pages,將來源選為 Deploy from a branch 並指向 gh-pages
  • 約莫數分鐘後即可透過 https://<使用者>.github.io/hero-journey/ 造訪。

3. 方法二:建立 GitHub Actions 自動化

適合團隊合作或常態發佈。

在專案根目錄新增 .github/workflows/deploy.yml

name: Deploy Angular to GitHub Pages

on:
  push:
    branches:
      - main
  workflow_dispatch: {}

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pages: write
      id-token: write
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install dependencies
        run: npm ci
        working-directory: projects/hero-journey

      - name: Build browser bundle
        run: npm run build -- --configuration production --output-mode=static --base-href "/hero-journey/"
        working-directory: projects/hero-journey

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: projects/hero-journey/dist/hero-journey/browser

      - name: Deploy to GitHub Pages
        uses: actions/deploy-pages@v4

首次執行後,GitHub 會自動建立 github-pages 環境並指向最新部署結果。你只需要把程式碼推到 main,部署就交給 CI。

4. 部署後驗收清單

  • 網站可於 GitHub Pages URL 正常載入。
  • 所有路由(Heroes、Dashboard、Detail...)重新整理後仍可顯示;若看到 404,確認 baseHrefredirect 設定是否正確。
  • 圖片、CSS、JS 皆為生產版 Hash 檔名,確保瀏覽器快取運作。
  • 若有使用 @defer 或懶載入,於 GitHub Pages 上再檢查一次觸發條件是否正常。

四、從 GitHub Pages 延伸到真實雲端

部署到 GitHub Pages 是最容易入門的方式,但在實務專案中,我們常需要 SSL、後端 API、版本管理或自動回滾。以下提供三條進階道路:

  • Firebase Hosting
    • 優勢:全球 CDN、免費 SSL、整合 Authentication/Firestore。
    • 流程:npm install -g firebase-toolsfirebase loginfirebase init hosting → 指定 dist/hero-journey/browserfirebase deploy
    • 適合:需要快速串接 Google 生態系或單頁應用的團隊。
  • Vercel
    • 優勢:自動拉取 Git repo、支援 Preview Deployment、內建 Edge Functions。
    • 流程:在 Vercel 新增專案 → 指向 GitHub Repo → 指定 Build Command npm run build -- --output-mode=static 與 Output dist/hero-journey/browser → 一鍵部署。
    • 適合:需要 CI/CD 與多環境預覽的前端團隊。
  • Netlify
    • 優勢:支援表單、身份認證、Serverless Functions;部署流程與 Vercel 類似。
    • 流程:連接 GitHub → 設定 Build Command npm run build -- --output-mode=static、Publish Directory dist/hero-journey/browser → 啟用自動部署。
    • 適合:需要快速推出 MVP 並整合 Serverless 功能的團隊。

建議依專案需求挑選平台,並持續將部署腳本自動化,避免手動操作造成遺漏。


五、常見問題與排查

  • 畫面空白或樣式錯亂:通常是 baseHrefdeploy-url 設定錯誤。記得清理瀏覽器快取或使用 DevTools 檢查資源載入路徑。
  • 路由重新整理 404:GitHub Pages 沒有自訂伺服器規則。可在 dist/hero-journey/browser 內複製一份 index.html404.html,或善用 angular-cli-ghpages 自動處理。
  • Node 版本過舊導致 build 失敗:升級到 Node 20 LTS,再執行 npm ci,確保 Angular CLI 能正確運作。
  • SSR 相關檔案不需要:若無打算使用 SSR,記得在部署 artifact 時僅選擇 browser 目錄,避免多餘檔案增加下載量。

*今日小結:
今天我們正式開啟把專案部署上線。透過 ng build 掌握打包流程、搞定 baseHref 與靜態資源路徑,再善用 GitHub Pages 或雲端平台,就能讓 Day01~Day26 的成果與更多人分享。


上一篇
Day 26|主題總結:重點速覽
下一篇
Day 28|變更檢測:Zoneless
系列文
Angular:踏上現代英雄之旅28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言