我們這邊好多小組覺得每次測試人員叫我們開發打包部署到某某個測試環境人工操作比較麻煩,因為他們想做到只專注於開發,不管這些瑣碎的事。於是有個組長問我前端能不能用Jenkins去執行這一個固定的流程,因為他們後端都是用Jenkins去實現自動化打包部署。我之前沒用過Jenkins,於是我去Jenkins官網看了下,發現確實是可以使用Jenkins實現前端自動化打包部署的,因為Jenkins可以執行遠端shell指令碼,我們開發是在Windows下,只是相當於在Linux下打包而已,而前端專案完全是可以在Linux環境下打包的。(順便提一句,我們的Jenkins部署在CentOS下,所以以下示例程式碼均以CentOS環境為例,示例中的Jenkins語言文字漢化不完整,不過大家按圖索驥應該也能找到相應的位置)
1.安裝nodejs,publish over ssh外掛
開啟Jenkins首頁->Manage Jenkins->Manage Plugins
這裡有兩種安裝方式,一種是聯網直接在“可安裝”這個tab頁中搜尋安裝;還有一種是離線安裝。由於我們處於內網,所以我用了第二種方式離線安裝,此處以離線安裝nodejs外掛為例。Jenkins外掛地址:https://plugins.jenkins.io
然後你就會獲得一個名為nodejs.hpi的離線外掛。然後通過“高階”這個tab頁裡的上傳外掛功能匯入這個外掛即可。
安裝好外掛之後需要重啟Jenkins,只要在Jenkins的url後新增/restart回車稍等幾分鐘即可。
2.在jenkins所在的Linux主機上安裝node.js並配置環境變數。
下載node.js的release包,推薦清華大學開源軟體映象網:https://mirrors.tuna.tsinghua.edu.cn/nodejs-release/,要不牆的你懷疑人生。找到你想要的node版本,檢視Linux架構可用arch命令,如下圖所示,x64就是x86_64的簡稱,此處以下載最新版node為例,一般不推薦最新版,容易出各種莫名其妙的bug,最好和開發node版本一樣,然後點選下載。
這裡建議再安裝一個node-sass的release包,因為每次前端npm install出問題有一半原因都是因為node-sass安裝出問題,而且內網也沒聯網,這裡我也就一起離線安裝了。這個node-sass版本需要與node版本相匹配,否則會報錯,具體可以參考我這篇文章https://www.cnblogs.com/jdWu-d/p/13594721.html。如果覺得自己npm install沒啥問題就可以跳過不用看了。
然後將這兩個release包上傳到伺服器的某個目錄下,我以某個使用者下新建的node檔案目錄存放release包,以某使用者下.bash_profile配置區域性環境變數為例,如需全域性環境變數,可到etc/profile配置。
在.bash_profile檔案下新增
export PATH=/nodejs的release包所在路徑/bin:$PATH
export SASS_BINARY_PATH=/node-sass的release包所在路徑 //如無離線安裝node-sass,則可不配置
新增完畢後儲存退出編輯,然後用source .bash_profile命令重新整理區域性變數。然後node -v測試是否安裝成功
3.jenkins系統配置和全域性工具配置
(1)開啟Jenkins首頁->Manage Jenkins->Configure System->全域性屬性->Environment variables->新增鍵值佇列表,如果不設定此項,會導致Jenkins內部無法識別node及npm等命令,最後在執行npm run build的時候會報錯:npm:未找到命令。
Linux檢視PATH命令為echo $PATH
為了方便,我直接把所有PATH直接新增進去,大家自己可以按需新增,SASS_BINARY_PATH如無離線安裝node-sass則無必要新增
(2)開啟Jenkins首頁->Manage Jenkins->Global Tool Configure->nodejs安裝,別名隨便取,安裝目錄填nodejs的release包所在路徑,然後儲存
4.寫測試指令碼
此步驟只是為了驗證上述的配置是否生效,自信的可以直接跳過此步驟檢視步驟5
開啟Jenkins首頁->new item->Freestyle Project
在構建環境中勾選“Provide Node&npm bin/folder to PATH”選擇步驟3中nodejs安裝填寫的那個別名,測試語句node -v & npm -v。然後儲存。
在專案列表,右鍵Build Now。
在構建歷史中檢視,看到藍色即成功,紅色即失敗,點選進入詳情頁面,檢視控制檯輸出,看見有輸出node和npm的版本,則證明上述配置生效。
5.新增憑據
開啟Jenkins首頁->憑據->系統->全域性憑據->新增憑據,分別新增github及目標主機的賬戶密碼,注意,其中ID是唯一且不可修改的。這些ID將會與步驟6指令碼中的credentialsId(“examples”,“172.XXX.XXX.XXX”)相對應,否則會報錯。
6.寫流水線指令碼
建立一個流水線專案,開啟Jenkins首頁->new item->流水線,在指令碼中填寫程式碼下載->打包->部署流程的指令碼程式碼。
流水線語法有兩種,一種是宣告式語法,一種是指令碼式語法,官方文件手冊傳送門:https://www.jenkins.io/zh/doc/book/pipeline/syntax/。這裡以指令碼式語法為例,具體程式碼如下:
node("master"){ //清理工作區 step([$class:'WsCleanup']) //工程部署目標伺服器ip def deploy_ip='172.XXX.XXX.XXX' //目標伺服器dist包所在目標目錄 def path='/home/XXXX/nginx/html' //當前日期 def cur_date="`date + %Y%m%d`" stage('程式碼下載'){ checkout([$class:'GitSCM',branches: [[name:'*/test']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],userRemoteConfigs: [[credentialsId: 'examples', url: 'http://172.XXX.XXX.XXX/XXX/XXX.git']]]) } stage('打包程式碼'){ sh ''' cd /home/XXX/.jenkins/workspace/fronted_build_test npm install #此處也可用unzip node_modules.zip,詳見下方解釋 chmod -R 755 ./* npm run build & sleep 1m mv dist distJenkinsTest #也可以在vue.config.js裡的outputDir裡自己設定包名 ''' } withCredentials([usernamePassword(credentialsId: '172.XXX.XXX.XXX', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]){ stage('部署dist包'){ //建立必要的資料夾 sh "sshpass -p '$PASSWORD' ssh -o StrictHostKeyChecking=no $USERNAME@$deploy_ip \" if [ ! -d $path/backup ]; then mkdir $path/backup; fi\" " //備份舊dist檔案 sh "sshpass -p '$PASSWORD' ssh -o StrictHostKeyChecking=no $USERNAME@$deploy_ip \" if [ -d $path/distJenkinsTest ]; then mv $path/distJenkinsTest/ $path/backup/distJenkinsTest-$cur_date; fi\" " //將新dist包上傳到目標伺服器目標目錄 sh "sshpass -p '$PASSWORD' scp -r distJenkinsTest $USERNAME@$deploy_ip:$path " } }
打包程式碼中,我還是建議可以第一次構建可以npm install,然後在workspace裡把npm install後生成的node_modules檔案壓縮成node_modules.zip,之後可以使用unzip node_modules.zip,因為只要專案中不引入新的模組和外掛node_modules資料夾內的內容是不會變的,沒必要每次都npm install,經常npm install不僅考驗網速,而且還容易報錯。Linux下壓縮node_modules資料夾請用命令zip -r -y node_modules.zip node_modules/,因為node_modules資料夾裡有很多符號連結,沒有使用”-y“引數會導致npm run build打包的時候這檔案找不到那檔案找不到,這模組丟失那模組丟失。
至此,就可以一勞永逸的使用Jenkins實現前端的自動化打包部署了,你也不會在群裡看見測試@你的名字喊你部署包到哪個環境了