前端自動化部署的深度實踐


年前我也在自動化部署這方面下了點功夫,將自己的學習所得在自動化部署的一小步,前端搬磚的一大步這篇博客中做了分享。感謝兩位網友@_shanks@TomCzHen的意見,讓我有了繼續優化部署流程的動力。本文主要是在自動化部署流程中,對版本管理流程合理性等方面做了一些改進,配合規范的工作流,使用體驗更佳!

更新日志自動生成

之前我都是手動修改CHANGELOG.md,用來記錄更新日志,感覺操作起來有點心累,也不是很規范。好在已有前人種樹,於是我就考慮利用conventional-changelog-cli自動生成和更新CHANGELOG.md,真的好用!

真香警告

什么是conventional-changelog

Generate a changelog from git metadata

根據git元數據生成更新日志,而conventional-changelog-cli則是相關的命令行工具。

安裝conventional-changelog-cli

npm install -g conventional-changelog-cli

初始化生成CHANGELOG.md

cd my-project
conventional-changelog -p angular -i CHANGELOG.md -s

以上命令是基於最后一次的Feature, Fix, Performance Improvement or Breaking Changes等類型的commit記錄生成或更新CHANGELOG.md。如果你希望根據之前所有的commit記錄生成完整的CHANGELOG.md,那么可以試試下面這條命令:

conventional-changelog -p angular -i CHANGELOG.md -s -r 0

工作流

代碼添加到暫存區

這一步沒有什么特殊,日常擼代碼,然后將工作區的內容添加到暫存區。

git add .

規范commit message

一個規范的commit message一般分為三個部分Header,Body 和 Footer。Header包含type, scope, subject等部分,分別用於描述commit類型,影響范圍,commit簡述。Body則是詳細描述,可以分多行寫。Footer主要用於描述不兼容改動(Breaking Change)或者關閉issue(Closes #issue)。

格式如下:

<type>(<scope>): <subject>

<body>

<footer>

舉個栗子:

feat(支持自動部署): 結合conventional-changelog,配合部署腳本完成部署任務

conventional-changelog是一個很好的工具,用於自動生成changelog,再配上自定義的部署腳本,整個部署流程就顯得更規范了

Breaking Change: 比較大的更新
Closes #315

其中,Header是必需的,BodyFooter可以省略。

大致了解規范后,就可以上工具了,這里我們用到的是commitizen

npm install -g commitizen

接着在項目根目錄運行以下命令:

commitizen init cz-conventional-changelog --save --save-exact

運行成功后,package.json會新增如下內容:

"devDependencies": {
  "cz-conventional-changelog": "^3.1.0"
},
"config": {
  "commitizen": {
    "path": "./node_modules/cz-conventional-changelog"
  }
}

git commit這一步用git cz替代cz就是指commitizen,通過交互式命令行完成commit操作。

PS D:\robin\frontend\spa-blog-frontend> git cz
cz-cli@4.0.3, cz-conventional-changelog@3.1.0

? Select the type of change that you're committing: feat:     A new feature
? What is the scope of this change (e.g. component or file name): (press enter to skip) 支持自動部署
? Write a short, imperative tense description of the change (max 86 chars):
 (37) 結合conventional-changelog,配合部署腳本完成部署任務
? Provide a longer description of the change: (press enter to skip)

? Are there any breaking changes? No
? Does this change affect any open issues? No
[master ee41f35] feat(支持自動部署): 結合conventional-changelog,配合部署腳本完成部署任務
 3 files changed, 15 insertions(+), 3 deletions(-)

處理版本號,更新CHANGELOG

接着我們要更新npm包的版本號,結合npm versionconventional-changelog使用,可以同時更新CHANGELOG.md

好的,我們先准備好腳本:

"scripts": {
    "start": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "deploy": "node deploy",
    "version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
    "postversion": "npm run deploy"
}

根據實際版本情況選擇更新patch/minor/major版本。假設我們更新的是minor版本號,那么操作命令如下:

npm version minor -m '特性版本更新'

執行這條命令會更新package.json中的version字段,

同時會執行conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md,更新CHANGELOG.md

執行完這條命令后,可以看到CHANGELOG.md已經被修改了。

CHANGELOG自動更新

npm鈎子觸發部署腳本

通過postversion鈎子觸發部署腳本node deploy,開始進行部署工作。deploy.js文件內容如下:

const { execFile } = require('child_process');

const version = process.env.npm_package_version;

execFile('deploy.sh', [version], { shell: true }, (err, stdout, stderr) => {
    if (err) {
        throw err;
    }
    console.log(stdout);
});

這里利用了nodejschild_process模塊執行子進程,調用了execFile執行了 deploy.sh,並將npm包版本號作為參數傳遞給了deploy.sh

deploy.sh文件內容如下:

#!/bin/bash
npm run build
htmldir="/usr/share/nginx/html"
uploadbasedir="${htmldir}/upgrade_blog_vue_ts"
appenddir=$1
uploaddir="${uploadbasedir}/${appenddir}"
projectdir="/usr/share/nginx/html/blog_vue_ts"
scp -r ./dist/. txcloud:${uploaddir}
ssh txcloud > /dev/null 2>&1 << eeooff
ln -snf ${uploaddir} ${projectdir}
exit
eeooff
echo done

以上命令主要做的事情是:

  • npm run build執行構建任務
  • 將構建得到的dist文件夾中的內容通過scp傳輸到服務器,通過版本號區分各個版本。
  • nginx配置的是監聽80端口,指向/usr/share/nginx/html/blog_vue_ts,而我通過軟連接將blog_vue_ts再次指向到upgrade_blog_vue_ts下的版本目錄,如upgrade_blog_vue_ts/0.5.4。每次發布版本時,以上腳本會修改軟連接,指向目標版本,如upgrade_blog_vue_ts/0.6.0,完成版本過渡。

我這里使用了軟連接改進了之前的部署腳本,既可以在服務器保留各個歷史版本文件夾,也不用考慮處理index.html與靜態資源分離的問題。

強烈建議結合自動化部署的一小步,前端搬磚的一大步這篇文章一起看。

lrwxrwxrwx 1 root root   47 Feb  3 21:35 blog_vue_ts -> /usr/share/nginx/html/upgrade_blog_vue_ts/0.6.0

linux服務器項目版本文件夾

如果要回退版本,也可以通過修改軟連接的方式實現,還是比較方便的。

推送到remote

最后別忘了把代碼push到遠程倉庫。

git push

更新日志changelog查看也變得很方便了,修改了什么內容一目了然,並且可以直接跳轉到commit歷史,issue等。

github上的changelog

番外

可以看到,我是通過deploy.js調用了deploy.sh。之前本想直接在npm scripts中調用deploy.sh並傳入版本號參數的,但是試了幾種寫法都不行,這里也記錄一下。

"deploy": "deploy.sh npm_package_version"
"deploy": "deploy.sh $npm_package_version"

看起來在npm scripts中調用sh腳本時,只能寫字面量參數,傳變量作為參數好像行不通。

下面這種字面量參數寫法是可以的,但是就有點呆呆的感覺了,而且與自動化部署的主題不符。

"deploy": "deploy.sh 0.6.0"

所以我目前還是選擇通過deploy.js作為中間者來調用deploy.sh的。

結語

需要承認的是,我以上所述的部署流程是以我的個人項目為例說明,可能不是很規范,但是也算是通過自己的理解和摸索,完整地搞了一套部署流程,並沒有借用jenkins等工具。有了這段自動化部署的學習經歷后,相信學習和使用jenkins會變得更輕松。接下來我會繼續優化和規范自己的部署流程,jenkins理所當然會出現在我的計划表中。

我是Tusi,一個創業公司前端小leader,每天依然為寫不完的業務代碼煩惱,在打磨產品道路上沉淀技術,探索成長路線。如果你與我一樣,正在思考自己的技術成長與價值,歡迎加我微信交流探討,微信號ice_lloly。我會在公眾號猿出道和小程序Tusi博客同步博客內容,快來撩我!

歡迎關注


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM