[Azure][VSTS]透過自建 Build Agent 解決 Angular 4 佈署逾時問題

因為採用 Angular 4 開發前端,但隨著專案越來越大,已經無法放在 VSTS 去做佈署了,透過 VSTS Agent 的設定,以及搭配 Release 的處理,讓 Angular 4 的程式可以順利完成建置和佈署

這一陣子把前端程式從原本的 Angular JS 1 升級到 Angular 4 之後,原本在前端因為是採用 VS 的專案,因此很容易透過 VSTS 來進行發佈,但升級到 Angular 4 之後,因為前端都改用 VS Code 來進行開發,因此就想說要怎麼來調整 VSTS ,來讓他可以幫我佈署程式。

原本擔心會非常難佈署,但所幸在 VSTS 上面,有支援 NPM 的功能,因此把之前透過

都 Build 完成之後,在 Azure App Service Deploy 的 Task 也要稍微注意一下,要記得將佈署來源給改成 「$(System.DefaultWorkingDirectory)/dist」,看來就可以順利的佈署。


但事情通常都不會那麼簡單,當我們使用這樣去發佈程式,會變成使用者第一次連上去的時候,載入時間可能會超過 10s,甚至有些時候還會延長到 30s ,這實在不是我們所樂意看見的,因此我們決定再找看看是否有辦法來縮短這個時間。因為在 VSTS 上面,要是我們 Build 超過 30mins 的話,那麼這個 job 會被強迫中斷,所以為了能順利完成發佈,勢必要調整一下作法。

透過一些測試和查看資料,也請了一些專家幫忙來調教,原本我們期待透過 CDN 來提升效能,也將程式中的圖片、CSS 和 Font 都移到 CDN 上,但實際測試下來這個部分提升的較為有限,主要還是要透過 Build 的時候加入 --prod 的參數,不只將產出的JavaScript做最小化壓縮的動作,並且也提供 Ahead-of-time 的處理,讓以往要超過 10s 的載入時間,都可以縮短到 3s 以內了。因此我們嘗試在原本VSTS 的 Build 中加入參數,但這樣的執行在地端的電腦,就需要花費 5~10 mins。然而在 VSTS 上面,程式碼和使用的套件少一點的時候還可以執行,但如果我們將整個程式都放置上去的時候,不只會逾時無法執行,還會會當出一些錯誤訊息,因此這個狀況讓我們卡關好久。

後來再跟 MVP 的朋友討論的時候,他們給我一個方向,參考「打通自動化雲端部署到地端-安裝VSTS Agent」 文章中所介紹的方式,透過地端的 VSTS Agent 來做 Build。為了方便使用,我就直接在 Azure 的雲端上開了一個 D2 等級的 VM,透過文章中所介紹的方式,將 Agnet 佈署在 Azure 的 VM 上面。當安裝好之後,因為我們要使用 NPM 來做 Build,因此這裡也需要自己手動將 nodejs 給安裝上去囉。

當我們設定完成之後,回到 VSTS 內就可以從 Agent queues 內看到我們所建立的 VSTS Agent,而且狀態是 Online ,這樣看起來 VSTS 已經跟我們的 Agent 連接起來。

接下來我們就可以把 VSTS 重新用新的 Build ,但很不幸的在這裡我又被卡關了,第一個問題是 npm 的版本太舊了,因此造成我在跑 aot 的時候會有些異常。

另外一個問題是 VSTS Agent 那一台上面的 MSDeploy 版本太舊,因此沒有辦法直接將 Build 的程式發佈


為了解決這兩個問題,我把整個步驟再調整一下。首先在 VSTS 的 Build 設定,我放置四個 npm。前面兩個是之前所沒有的,這兩個主要是用來安裝 npm 和 angular cli,而他們只需要在第一次執行的時候去啟用,後續除非有特別要改版,否則前面那兩個 npm 的處理就可以把它給關閉了,這樣 Build 可以稍微節省一點時間。 

而第一個 npm 的設定如下:

第二個 npm 的設定如下

透過這兩個步驟的處理,我們就將 Agnet 所在的環境上,將 npm 與 angular cli 給升級,這樣就可以使用 npm 5.3 和 angular cli 較新的版本了。

而在上面的步驟中,當 angular 程式被 build 出來之後,我就沒有直接佈署到 Azure Web App 上面去使用,在這裡我透過 Publish Artifact,將前面步驟透過 npm,在 Angent 上面 Build 好的程式上傳到 VSTS 上面去。然後再建立一個 VSTS 的 Release 處理,在 Release 裡面,我們就放置一個 Depoly Azure App Service 的 Task

並且在 Release 的 Triggers 裡面設定好 CD ,指定對應的 Build 。這樣當 Build 完成後,就會自動觸發 Release 的相關程序

原本以為這樣就大功告成了,但因為整體的程式再做 aot 的時候耗用記憶體較多,因此在這裡我們將 source 內的 package.json 的設定檔案,再使用 nodejs 的時候,特別加上 「node --max_old_space_size=2048 」的設定,讓 nodejs 可以使用較多的記憶體之後,整個 VSTS 的 Build + Release 總算可以完成了。


整個步驟目前看起來都還算蠻順利的,雖然在 Build 的時候花費比較多的時間,但因為現在我們是使用自己的 Build Agent ,因此 VSTS 每個月可以免費使用的 240 分鐘額度,就還足夠使用。如果有朋友每個月的額度會使用不足的話,那麼也可以透過上述的方式,將發佈程式分為 Build 和 Release ,這樣就可以少算一點費用;或者是像我目前的作法,建立多個 EMail 帳號去申請 VSTS 的額度,然後使用 External Git 連回到自己的 VSTS 存放 Source 的地方,這樣就可以不用因為每個月只有 240 分鐘的德度受限了。

感謝 :

1. 整個過程感謝 Kevin 哥的指導,讓我們在 Angular 4 的部分做些調整,讓目前程式可以有不錯的效果。

2. 感謝 MVP 郭董,透過他指導 VSTS Agent 的設定,讓我們可以節省不少測試的時間。