Try   HackMD

2023/10/03

Vite 部署靜態網頁 Github Pages 含 Vue Router 設置

使用工具和前置作業

  • Vite
  • pnpm
  • 已經建立好的 GitHub Repository 遠端庫

修改vite.config.ts

根據官方文件說明,若預期部署在https://<USERNAME>.github.io/<REPONAME>/ 網址上,首先需要在本地專案中的vite.config.ts新增或修改base屬性。
例如我的遠端庫名稱<REPONAME>vue-weather-app,那麼就設定base'/vue-weather-app/':

export default defineConfig({
  plugins: [vue()],
  base: '/vue-weather-app/',
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
});

*需要合乎命名規則,並注意名稱務必一致。

專案項目打包,生成dist目錄

根據package.json的腳本內容用vite打包專案,以命令列執行pnpm build

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

執行後會在專案根目錄生成dist目錄內含打包後的index.html等文件,也就是接下來實際部署的程式碼來源。
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

之後若想先預覽本地環境靜態網頁的建構,我們可以在命令列執行pnpm preview

修改.gitignore文件,準備將dist目錄推送至遠端庫

畢竟網頁是部署在遠端,勢必得推送上傳dist目錄。
在推送之前記得將.gitignore文件內設定的dist參數刪除或註解才能上傳。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

將dist目錄推送到遠端庫的gh-pages分支

為了將主要開發文件和部署靜態網頁文件區隔開來,並且方便之後管理,我們在本地命命列執行以下程式碼,將dist內含的文件推送到新建的gh-pages分支

git subtree push prefix dist origin gh-pages

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

在 GitHub 遠端庫的設定中,啟用 GitHub Pages

順利上傳靜態網頁文件後,前往 GitHub Repository>Settings>Pages

  1. Source 來源選擇 Deploy from a branch
  2. Branch 選擇 gh-pages分支的根目錄/(root)

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

選好之後按Save儲存,回到專案主頁,看到顯示綠色圓點的github-pages代表成功完成布署:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

可以回到之前的Settings>Pages瀏覽部署好的網址:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

小結

目前為止我們所做的就是指定gh-pages分支作為部署網頁的來源以正式啟用GitHub Pages。

關於GitHub Pages建構及部署來源(發布來源)的設置,有兩個模式可以選擇:

  • 在將程式碼推送到特定分支時部署網頁(這次部署採用方式)。
  • 編寫 GitHub Actions 工作流程(Workflow)來部署網頁,

我會在下一篇文章示範 Workflow 腳本以使用 GitHub Actions 實施自動化部署。

遇到的問題

如何取消部署GitHub Pages?

一開始我用main主分支測試部署功能,但是我想改用gh-pages做為新的部署分支,當作唯一github pages部署來源,要如何移除原先main分支來源部署的github pages呢?或者我想改用Netlify或Vercel來部署我的網頁,而不想使用GitHub Pages,該如何取消/移除既有GitHub Pages部署網頁?

GitHub遠端庫主頁和設定都找不到明確取消GitHub Pages部署的選項,官方文件的介紹已過時,後來找到這個討論串:
https://github.com/orgs/community/discussions/22018

最簡單移除GitHub Pages的方法是:
刪除專案遠端庫Setting的Environments設定。刪除後便會取消GitHub Pages的線上部署網頁,之後便可以依照需求重新部署。

Vue Router 設定 Hash / HTML5 History 模式

vue-router 讓我們可以根據偏好或網頁需求使用createWebHashHistory或是createWebHistory
兩者在網址外觀上的差異:

https://example.com/#/           //Hash 
https://example.com/#/about   //Hash
https://example.com/             //HTML5
https://example.com/about     //HTML5

Hash mode

  • 使用createWebHashHistory
  • 是vue-router預設的模式,如果沒有設定就會是hash mode,會在網址後加上一個#
  • 簡單來說很像瀏覽器的錨點功能,#號後的URL變化不會向伺服器發送請求,不需要後端相對應的配置。
import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    //...
  ],
})

HTML5 mode

  • 使用createWebhHistory
  • 官方推薦模式,因為網址省略#,會使網址看起來很"正常"。
  • URL的變化都會向伺服器發送一個請求。
  • 如果有設置除首頁外多個路由網址,後端需要相應的配置,否則若使用者端直接訪問其他路由網址,會導至404 error頁面。
  • 例如使用者在瀏覽器直接訪問https://example.com/about,在前端只有設置根目錄一份index.html的前提下,伺服器要依據請求找尋根目錄下的about目錄下的index.html文件,但根本就沒有這個about目錄,因此返回404 error頁面了。
  • 一個簡單的後端配置是在根目錄創建一個404.html文件,內容和index.html文件相同。
import { createRouter, createWebhHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    //...
  ],
})

參考