Vue 2.x & Vue CLI 3 保留自動化上版紀錄

Kion
9 min readJan 15, 2020

--

目次

1. Docusaurus 與 Vue CLI 部署差異
2. Vue CLI 官方 Shell Script 範例講解
3. 程式碼分享

當版本有 Bug 時,第一時間的搶救方式便是先退版

跟很多新手一樣,起初我是按照 Vue CLI 官方範例寫 Shell Script
體驗體驗自動化的力量

但殊不知, Vue.CLI 官方 Shell Script 範例會直接洗掉上版紀錄
除了無法保留紀錄以外,最重要的事

一旦上版就無法退版!

這是很嚴重的問題!
這樣的上版方式,讓我們失去第一時間止血的能力
想當初我就有不小心上了一個有問題的版,但因為無法退版而不能馬上補救的經驗

於是前輩幫我寫了一個參考 Docusaurus 寫法的版本(原來不是自己研究的
特別跟大家分享一下

Docusaurus 與 Vue CLI 官方範例部署差異

在開始 Vue 專案之前,我就有用過 Docusaurus 這套工具試水溫
Docusaurus 為 Facebook 開發,以 React.js 為核心
是一款標榜快速創建、易於維護的靜態網站工具

在部署方面不同的是:

  1. Vue CLI 的 Shell Script 是開發者自己寫的, Vue CLI 官方文件有 各式範例 可以參考,還是很佛的!
    但美中不足的是,官方範例的寫法會直接洗掉上版紀錄
此為 Atlanssian 的服務介面

2. Docusaurus 的 Shell Script 則是官方寫好已被包成 npm Script 可立即使用
且他會保留上版紀錄,是我們想達到的目標

此為 GitHub 的服務介面

那就來先了解官方是怎麼寫的吧!

Vue CLI 官方 Shell Script 範例講解

以 GitHub Page 作為範例
一般在 GitHub 使用 GitHub Page 部署,只需把 code 推至遠端 merge 進 master 便可完成,詳細可以點這

但使用 Vue 開發和傳統方式不同
index.html 是沒有涵蓋所有程式碼的,但瀏覽器卻只能看懂 HTML
所以才需透過 npm run build 的指令打包,轉換成瀏覽器看得懂的 HTML、CSS 放在 dist/ 這個資料夾內

因此我們的目標是:將 GitHub Page 設定是指向 gh-pages 分支,並單獨將打包後的檔案推上 gh-pages

了解上述條件後我們來看官方範例

#!/usr/bin/env sh# 當發生錯誤時中止腳本
set -e
# 打包
npm run build
# cd 到打包輸出的目錄下
cd dist
# (可省略)部署到自定義域網域名稱
# echo 'www.example.com' > CNAME
git init
git add -A
git commit -m 'deploy'
# 第一種做法,部署到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
# 第二種做法,部署到 https://<USERNAME>.github.io/<REPO>
# git push -f git@github.com:<USERNAME>/<REPO>.git master:gh-pages
cd -

內容大致上是打包後, cd 至 dist 目錄
將此目錄初始化,形成新的 Git Repository
根據剛剛的前提,採取第二種寫法
強制推上遠端倉庫並將分支改名為 gh-pages

將 commit 推向遠端倉庫

一般在下 push 指令時,我們常常是這樣寫:

git push  origin <BRANCHNAME>

origin 其實就是代稱該 Git Repository 指向的遠端倉庫
原本應該是這樣:

git push  <REMOTENAME> <BRANCHNAME>

因為我們在 dist 創建了新的環境,沒有設定指向哪個遠端倉庫,因此我們要這樣寫:

git push -f git@github.com:<USERNAME>/<REPO>.git master

將該環境的 master 推向遠端
但這樣就會遇到一個問題,如果我們直接推上 master git 記錄會整個亂掉
為了保留完整的開發紀錄,我們必須推上去時將他改名成 gh-pages
這樣在 master 上就可以保留開發紀錄

那第一個方法是什麼時機使用呢?

當你將 Repo 名字取名為 <USERNAME>.github.io 時,也能開啟 GitHub Pages 的服務
甚至不需設定直接抓取 master 的檔案,詳細可以看 這篇
網址預設為:
https://<username>.github.io/

Atlassian 也是使用這樣的方式,詳細可以看 這篇

他就不是靠分支去區隔上版和開發紀錄了
而是分為上版的 Repo 和開發版控的 Repo
因此直接推到上版的 Repo 的 master 即可

Docusaurus

但官方佛心、看似美好的腳本
卻因為他的簡易性而缺少了 commit 紀錄,造成問題發生時無法退版補救
我們便翻了一下 Docusaurus 的原始碼

檔案路徑在:

docusaurus/packages/docusaurus/src/commands/deploy.ts

但 Docusaurus 是用 TypeScript 寫的,並不是 Shell Script
搭配註解來看,可以發現 Facebook 錯誤處理和檢查寫的非常完善啊!
長長的一大串,看得很頭疼

總之,他邏輯大概是:
將遠端的檔案抓下來, clone 進特定資料夾後切換到特定分支
藉由清空資料夾,把 dist 的內容複製過來,commit 後推上去
便能記錄到檔案間的更動情形

當然要考慮的點還有很多,只是簡單講解有個概念
可以看 Docusaurus 的原始碼了解邏輯
也可以直接看下面的實作

程式碼分享

以下範例已部署在 Github 作為舉例:

#!/usr/bin/env sh# 抓取目前最新的 commit hash,取前 7 個字current_commit=$(git rev-parse HEAD | cut -c1-7)# 將設計好的 commit 訊息存入變數commit_message="Deploy website version based on ${current_commit}"# 開始打包npm run build# 將遠端倉庫的內容抓下來,放入 deploy-temp 目錄
# 目的是在 deploy-temp 目錄建立一個自己的環境
# 但跟之前的方法不一樣的是:我們是抓專案的遠端倉庫
git clone git@github.com:<USERNAME>/<USERNAME>.github.io.git deploy-temp# 切進 deploy-temp 目錄cd deploy-temp# 檢查看看遠端是否已有 gh-pages 分支git checkout origin/gh-pages# 條件式,若沒有成功切換的話,執行
# $? 為變數,用於檢查上一個指令退出的狀態(0 為命令成功完成)
# -ne 0 -> 不等於0
if [ $? -ne 0 ]; then # 因為遠端沒有分支,開一個空的分支
# 一般開分支都會繼承主支的內容,只要下 --orphan 就可以不繼承主分支
git checkout --orphan gh-pages # 條件式,若沒有成功創建的話,執行 if [ $? -ne 0 ]; then # 噴錯 echo "Error: Git checkout failed" # 非正常運行導致退出,$? 為 1 exit 1 # 結束判斷 fi# 遠端有 gh-pages 分支的話else # 在地端拉下遠端分支 git checkout -b gh-pages # 將此分支指向遠端的 gh-pages git branch --set-upstream-to=origin/gh-pagesfi# 刪除目錄內的所有檔案和資料夾
# -f 即使原檔案屬性設為唯讀,亦直接刪除,無需逐一確認
# -r 將目錄及以下之檔案亦逐一刪除
git rm -rf .# 切出空目錄cd ../# 複製 dist 內所有檔案至 deploy-temp 目錄cp -R dist/* deploy-temp# 切至 deploy-tempcd deploy-tempgit add --all# commit message 便是上面宣告的變數git commit -m "${commit_message}"# 將此環境的 commit 推送至遠端的 gh-pagesgit push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git gh-pages# 切至上層目錄cd -# 刪除 deploy-temp 目錄rm -rf deploy-temp

如此一來,遠端的 gh-pages 分支就有從 deploy-temp 推上去的 dist 檔案
而每次都會把 git 環境抓下來放進新建的 deploy-temp 目錄
切換至 gh-pages 時,刪掉所有檔案、複製 dist 檔案進去,再 commit 推向遠端倉庫
透過這樣的方式紀錄檔案更動
也就可以在 gh-pages 切回上一個 commit 達到退版的動作了!

拍個手讓我知道,這個文章對你們有幫助 ♥(´∀` )人

參考資料

  1. Vue CLI 官方文件 — 部署
  2. Docusaurus 開源程式碼 — deploy.ts

--

--

Kion
Kion

Written by Kion

程式就是利用自動化與排程的特性解決問題 文章分類總覽: https://hackmd.io/@Kion/SyvyEks0L

No responses yet