介紹下我們現(xiàn)在的前端部署方式,主要有以下功能要在CI實現(xiàn)
- 安裝依賴
- 編譯代碼
- 上傳資源文件到云存儲
- 部署服務器代碼
.gitlab-ci.yml文件
image: node:8.9.3
stages:
- build
- test
- deploy
masterbuild:
stage: build
script:
- npm install --no-optional
- npm run prod
- node ./tools/generate.config.js
- qshell='./tools/qshell-linux-x64'
- chmod a+x "${qshell}"
- ${qshell} account "${QINIU_AK}" "${QINIU_SK}"
- ${qshell} qupload 8 ./qiniuconfig
only:
- master
artifacts:
expire_in: 1 week
paths:
- dist
deploy_master:
image: sebble/deploy
stage: deploy
script:
- mkdir -p ~/.ssh
- echo "$PROD_DEPLOY_SSH" >> ~/.ssh/id_dsa
- chmod 600 ~/.ssh/id_dsa
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- rsync -rav dist/ "$PROD_DEPLOY_USER"@"$PROD_DEPLOY_HOST":/deploy_path
only:
- master
解釋下部署代碼,先看下build階段的
- npm install --no-optional
- npm run prod
這個是安裝依賴和編譯的
- node ./tools/generate.config.js
這個是生成七牛配置信息的,可根據(jù)實際情況修改,七牛qshell文檔
{
"src_dir": "",
"bucket": "",
"key_prefix": "",
"up_host": "http://up-z2.qiniup.com",
"overwrite": true,
"skip_fixed_strings": ".svn,.git",
"skip_suffixes": ".DS_Store,.exe",
"log_stdout": true
}
我這生成的配置是這樣,配置下要上傳的目錄和bucket,指定下前綴等
- qshell='./tools/qshell-linux-x64'
- chmod a+x "${qshell}"
- ${qshell} account "${QINIU_AK}" "${QINIU_SK}"
- ${qshell} qupload 8 ./qiniuconfig
用七牛的工具把資源文件(css,js,圖片,音頻)上傳到七牛,一些變量信息,為了共用,寫到項目組的CI / CD的Variables里面了
only:
- master
這個是指定只有master分支可以觸發(fā)這個job
artifacts:
expire_in: 1 week
paths:
- dist
artifacts主要是把編譯結果保存起來,供下一階段使用,還有就是有的時候要下載下來看下代碼有問題,expire_in指定緩存文件過期時間,paths指定要緩存的目錄和文件
build階段主要做這些事情
再來看下deploy階段
- mkdir -p ~/.ssh
- echo "$PROD_DEPLOY_SSH" >> ~/.ssh/id_dsa
- chmod 600 ~/.ssh/id_dsa
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- rsync -rav dist/ "$PROD_DEPLOY_USER"@"$PROD_DEPLOY_HOST":/deploy_path
首先創(chuàng)建一個.ssh目錄,把服務器的私鑰寫到id_dsa,然后用rsync把編譯結果上傳到我們的服務器,變量也是寫到Variables里面了
這樣我們就完成了一個前端項目的自動部署的配置,這樣就完了?
你剛才上傳那么資源到七牛有什么意義呢?如果你問這個問題,說明你跟著思路認真看下來了,沒錯,還沒完,我們還要把我們生成的html文件的資源鏈接改成七牛的地址
找到webpack配置文件的output配置項
output: {
publicPath: webebagconfig.getOutPutPath()
}
我們生產環(huán)境和測試的是分開的,我這一步是在npm run prod做的,根據(jù)命令getOutPutPath()函數(shù)返回不同的域名
現(xiàn)在我們就完成一個前端項目的自動部署,上傳資源到七牛(CDN)了,說到CDN,大家配置文件輸出的時候,文件名一定要加上hash,保證每次部署的時候,都能生效,如果可以的話,最好前綴也加上,我這是用日期,部署完成后,我看前端加載資源的前綴就知道有沒有部署成功,是不是用的緩存,webapck的輸出的filename我是這樣配置的assets/js/[name].[chunkhash:8].bundle.js
為什么要用兩個階段,一個不行嗎?
為什么有build和deploy階段,一個build就行了啊,一開始我也是只有一個build,后面因為遇到一件事,才把這個過程分成兩個階段來的,有一次部署的時候,新部署的程序有點問題,想回滾到上一個版本,然后npm抽風了,下載依賴非常慢,等了5分鐘才部署好,分成兩個階段的話,如果artifacts還沒有過期,就可以跳過build直接執(zhí)行deploy,直接部署文件就行了,不需要再下載依賴和編譯了,非???/p>
用CI部署的時候,如果中間某個步驟因為網絡問題,中斷了,可以在CI/CD -> Pipelines下面,點Run Pipeline,在Create for選你要觸發(fā)的分支,點Create Pipeline觸發(fā)一下就會自動執(zhí)行相應的CI,發(fā)版本的時候,最好每個版本都打上tag,這樣回滾版本非常方便,方法同上。
用CI還有個好處,我指服務端開發(fā),前端可以參考,因為也出現(xiàn)過類似問題,有些新同事開發(fā)的時候,代碼測試不嚴禁,上次調試代碼加了個打印進去,加了個log包,把bug修改好了,把打印去掉,直接就推代碼了,按以前那種方式,服務器拉下來編譯肯定不通過,因為引用了log包但沒有用到,用CI的話,如果編譯不通過,后面就不會執(zhí)行了,也就不會把有問題的程序部署到服務器,CI可以保證部署到服務器的是正常的程序。