用最簡單的方式來部署自己的 gh-pages 網頁

gh-pages

前言

gh-pages 是 GitHub 所提供的一個服務,簡單來講就是可以讓你不用花錢也可以部署一個靜態網頁作為展示用,因此對於前端工程師來講就非常方便而且很實用,但是部署方式百百種,所以這一篇就會來介紹用最簡單方式來部署自己的 gh-pages 網頁。

gh-pages 介紹

首先這邊我們先來認識一下什麼是 gh-pages。

其實 gh-pages 完整名稱是 GitHub Pages,基本上這是一個由 GitHub(程式碼托管平台)所提供的服務,可以讓你不用花錢也可以部署一個靜態網頁,你可以拿來放自己的部落格、作品集或是一些臨時展示用的網頁。

除此之外它也是 GitHub 的特殊分支(如果你瞭解 Git 的話),如果你的 GitHub 儲存庫有這個分支,那麼你就可以透過 https://<username>.github.io/<repository> 來存取你的網頁,其中 <username> 是你的 GitHub 帳號名稱,<repository> 是你的專案名稱。

以我的 GitHub 帳號來講是 hsiangfeng,而假設儲存庫是 israynotarray,那麼完整 Url 就會長這樣

1
https://hsiangfeng.github.io/israynotarray

Note
這邊也額外提一件事情,你可能會看到有人的網址只需要輸入這樣 https://<username>.github.io 就可以觀看網站,這是因為它的儲存庫名稱跟帳號名稱一樣,所以就可以省略掉儲存庫名稱,例如我的是 hsiangfeng,那麼理論上來講要長這樣 https://hsiangfeng.github.io/hsiangfeng.github.io,但是因為儲存庫名稱跟帳號名稱一樣,所以就可以省略掉儲存庫名稱,變成 https://hsiangfeng.github.io

最後也提一件事情,雖然 gh-pages 是屬於免費的服務,基本上只要你持有 GitHub 帳號就可以使用,但是它基本上有幾個重點可以稍微注意一下

  • 只能放置純靜態網頁,也就是說沒有後端的網頁,例如 PHP、Node.js、Python 等等,只能是純 HTML、CSS、JavaScript 等等,因為它並沒有運算能力。
  • gh-pages 是以儲存庫為單位,也就是說每個儲存庫都可以有一個 gh-pages 分支,但是每個儲存庫只能有一個 gh-pages 分支,因此如果你想要部署多個網頁,那麼你就需要建立多個儲存庫。
  • gh-pages 的容量是有限制的,每個儲存庫的容量是 1GB,如果你的網頁超過這個容量,那麼就無法部署。
  • gh-pages 的流量為每月 100GB
  • gh-pages 每小時只能部署 10 次,如果是使用自己寫的 GitHub Actions 就沒有這個限制(畢竟要花錢)。
  • 免費的 ssh 憑證
  • 預設的網域是 https://<username>.github.io/<repository>,如果你想要使用自己的網域,那麼你就需要花錢購買網域,並且設定 DNS,關於這一點你可以參考我先前的「從零開始教你買網址(Google Domain)到設定成自己部落格網址」文章。

最後要稍微注意一下 gh-pages 雖然是免費提供的靜態網頁託管服務,但是它並不能拿來作為商業用途或是違法用途,否則你的帳號可能會被封鎖,這一條其實在 GitHub 文件中都可以找到,所以就不額外提了。

那麼接下來將會來介紹如何部署 gh-pages 網頁囉~

部署 gh-pages

首先前面有提到 gh-pages 要使用的話非常簡單,你只需要具備一個 GitHub 帳號就可以免費使用,但是實際上來講我們該如何操作呢?沒有很懂程式的人也可以部署一個簡單的網頁嗎?

答案是可以的,而且非常簡單,你只需要懂一點基本前端知識與 Git 知識就可以,所以接下來就會來介紹如何部署 gh-pages 網頁。

那麼這邊有兩個步驟我會直接省略,如:

  • 安裝 VSCode(你可以選擇其他編輯器)
  • 建立 GitHub 帳號
  • 建立 GitHub 儲存庫

我相信你應該是可以做到的,所以就不額外去介紹這一塊,如果你真的不知道該如何建立儲存庫的話也不用擔心,你可以看一下我先前寫的文章「(11) 試著學 Hexo - 部署你的第一個部落格」的「建立 GitHub Pages 儲存庫」這一節,裡面有詳細的步驟可以參考。

建立初始環境

假設現在你已經準備好一個 GitHub 帳號與儲存庫,那麼接下來我會請你回到你的電腦上,然後建立一個資料夾叫做 example,並且在裡面建立一個 index.html 檔案,內容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IsRayNotArray gh-pages</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<h1>這是一個單純的示範網頁</h1>
</body>
</html>

而 style.css 也很單純

1
2
3
4
body {
background-color: black;
color: white;
}

初始化 git

接下來這邊我會建立一個空的儲存庫叫做 example-gh-pages

example-gh-pages

然後我會在 example 資料夾下面初始化 git 並將它推送到 GitHub

1
2
3
4
5
6
git init # 初始化 git
git add . # 將所有檔案加入 git 索引
git commit -m "first commit" # 加上 commit 訊息
git branch -M main # 將分支名稱改成 main
git remote add origin [email protected]:hsiangfeng/example-gh-pages.git # 新增遠端儲存庫路徑
git push -u origin main # 將本地端的 main 分支推送到遠端儲存庫,並且設定為預設分支,下次就可以直接使用 git push

Note
請注意 git remote add origin [email protected]:hsiangfeng/example-gh-pages.git 會隨著你的帳號與儲存庫名稱而有所不同,請自行替換。

目前來講,只要你有做到 git push -u origin main 這一步之後,你的 GitHub 儲存庫就會長這樣

GitHub

使用 gh-pages 套件

接下來呢?接下來我該怎麼做呢?如果你是單純的靜態網頁而非需要編譯的網頁,那麼你只需要在你的儲存庫下面建立一個 gh-pages 分支,然後將你的網頁推送到這個分支 GitHub 就會自動幫你部署了,但是這種做法我認為有一個問題點,變成你除了要將原始碼推到 main 分支之外,還要將編譯後的檔案推到 gh-pages 分支,身為一個人類來講,基本上是會有很高機會失誤的,那麼為了減少失誤的機會,我們可以使用 gh-pages 套件來幫助我們部署 gh-pages 網頁。

首先請你回到你桌面上的專案資料夾,然後輸入以下指令

1
2
npm init -y # 初始化 npm
npm install gh-pages # 安裝 gh-pages 套件

接著請你優先建立 .gitignore 檔案,並且加入以下內容

1
node_modules

.gitignore 主要是用來忽略不需要加入 git 索引的檔案,例如 node_modules 資料夾,因為這個資料夾通常都會很大,而且裡面的檔案都是可以透過 npm install 來安裝,因此我們可以透過 .gitignore 來忽略它。

接下來我們要修改 package.json 檔案,將它修改成以下內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"name": "example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"deploy": "gh-pages -d src" // 增加這一行
},
"repository": {
"type": "git",
"url": "git+https://github.com/hsiangfeng/example-gh-pages.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/hsiangfeng/example-gh-pages/issues"
},
"homepage": "https://github.com/hsiangfeng/example-gh-pages#readme",
"dependencies": {
"gh-pages": "^5.0.0"
}
}

接著把 index.html 與 style.css 檔案移動到 src 資料夾下面

src

接著請你回到終端機,然後輸入以下指令

1
npm run deploy

接下來你只要看到終端機畫面出現 Published 就代表部署成功了

Published

接著你就可以到你的 GitHub 儲存庫看一下,你會發現多了一個 gh-pages 分支

gh-pages

而且你也可以透過 https://<username>.github.io/<repository> 來觀看你的網頁,以這個範例來講就是 https://hsiangfeng.github.io/example-gh-pages

Note
GitHub 會自動偵測 gh-pages 分支,只要你有這個分支,那麼它就會自動部署,而部署過程你可以在儲存庫的 Actions 中看到,通常名稱叫做「pages build and deployment」,等到它變成綠色的勾勾就代表部署成功了。

接下來我們回頭聊一下 gh-pages 套件是怎麼做到的,首先我們剛剛在 package.json 中新增了一行指令 gh-pages -d src,這行指令的意思呼叫 gh-pages 套件,並且將 src 資料夾下面的檔案推送到 gh-pages 分支,-d 呢?-d 的意思是 directory(目錄),也就是說我們可以透過 -d 來指定要推送的目錄,如果沒有指定的話,預設會是根目錄,但我們並不希望把所有檔案都推送到 gh-pages 分支,因此我們就指定 src 資料夾。

接著它是如何辨別要推到哪一個儲存庫呢?預設的狀況下,它會去讀取你的專案資料夾下面的 .git 資料夾,然後去讀取裡面的 remote 設定,也就是說它會去讀取你的遠端儲存庫路徑,然後推送到 gh-pages 分支,這也是為什麼我們在 package.json 中沒有指定遠端儲存庫路徑,但是它還是可以正確推送的原因。

Note
如果你是使用 CRA、Vite 等開發工具的話,你必須閱讀一下 gh-pages 文件,因為它有相對應的設定,否則你的網頁可能會無法正常運作,這一點要稍微注意一下,這個就建議你直接閱讀官方文件比較好。

額外補充

如果你是使用 Vite 這類編譯工具,你可以將 "deploy": "gh-pages -d dist" 改成 "deploy": "vite build && gh-pages -d dist",這樣子就可以在部署之前先編譯後部署囉~