- 前端高階進階:javascript 程式碼是如何被壓縮
- 前端高階進階:如何更好地優化打包資源
- 前端高階進階:網站的快取控制策略最佳實踐及注意事項
- 前端高階進階:在生產環境中使你的 npm i 速度提升 50%
- 前端高階進階:使用 docker 高效部署你的前端應用
- 前端高階進階:CICD 下的前端多特性分支環境的部署
- 前端高階進階:前端部署的發展歷程
更多文章: 前端工程化系列
我在 github 上新建了一個倉庫 每日一題,每天一道面試題,歡迎交流。
無論大中小企業,多特性分支的前端環境基本上已成為了標配,即每一個功能分支都配有相應的測試環境。今天山月就循序漸進來講解下多分支環境的實現方式,經濟基礎決定上層建築,企業的基礎服務建設決定實現方式,這裡是基於 Docker 與 CICD 的實現。
至於伺服器端的多分支環境部署,由於都是基於容器的思想,思路與前端一致,如果直接想看結論,請翻到最後看小結。
從前後端的開發到上線,不同的企業對不同的環境有不同的命名,甚至有更精細的劃分。但是一般可以可以劃分為三個環境,我把這三個環境命名如下,並會在下述
local
:本地環境,把專案 git clone 到自己的工作筆記本或者開發機中,在localhost:8080
類似的地址進行除錯與開發。此時環境的物件導向主要是開發者。dev
:測試環境,本地業務迭代開發結束並交付給測試進行功能測試的環境,在dev.shanyue.tech
類似的二級域名進行測試。此時環境的物件導向主要是測試人員。prod
:生產環境,線上供使用者使用的環境,在shanyue.tech
類似的地址。此時環境的物件導向主要是使用者。
那什麼是多分支環境部署呢?這要從 Git 的工作流說起
本篇文章要求你有一定的 Docker,DevOps 以及前端工程化的知識儲備。如果沒有的話,本系列文章以及 個人伺服器運維指南 中的 Docker 部分會對你有所幫助。
Git 工作流
隨著不同的環境的區分,基於版本管理工具演化出了各種各樣的工作流,比如 Git Flow
,Github Flow
與 Gitlab Flow
。這裡簡單介紹一種最常見的 Git Flow
git flow
流程如圖上所示,關於細節這裡不作過多的討論。一般來說
feature
分支對應本地環境develop
分支對應測試環境master
分支對應生產環境
由於每次 feature
開發結束後都要合併到 develop
分支進行測試。此時會有幾個問題
- 當
develop
分支測試出現 bug 後,每次修復後都需要合併到develop
分支。 - 當多功能同時開發時會造成
develop
分支的擁擠導致,各個功能最後只能統一上線,因為它無法時刻保持一個乾淨的develop
分支,這與我們現在所提倡的敏捷開發,小步迭代格格不入。
此時,基於 feature
分支急需一套可單獨測試的環境
多分支環境部署
CI,Continous Integration
持續整合使專案變得更加自動化,充分減少程式設計師的手動操作,並且在產品快速迭代的同時提高程式碼質量。基於 CICD 的工作流也大大改善了 Git 的工作流。其中就增加了一個基於分支的前端環境:
- 特性環境 (也不知道叫啥名字,就這麼起吧),對應於
feature
分支。每個feature
分支都會有一個環境,可以視為本地環境與測試環境的結合體。如對功能feature-A
的開發在feature-A.dev.shanyue.tech
類似的三級域名進行測試。
此時對於開發,測試,產品交付來講,整個流程的體驗就順滑了很多。於是終於到了今天的正題:
如何實現多分支環境部署?
基於 docker 進行部署
由於 docker 的輕便易用,隔離性好並且可移植性高的特點,這裡選擇基於 docker 的部署,映象配置檔案如下所示。
FROM node:10-alpine as builder
ENV PROJECT_ENV development
ENV NODE_ENV production
# http-server 不變動也可以利用快取
WORKDIR /code
ADD package.json package-lock.json /code
RUN npm install --production
ADD . /code
RUN npm run build
# 選擇更小體積的基礎映象
FROM nginx:10-alpine
COPY --from=builder /code/public /usr/share/nginx/html
複製程式碼
另外由於此時不在生產環境,完全沒有必要把所有靜態資源扔到 CDN 去處理,甚至為了方便除錯,在打包時也可以避免做過多的混淆及壓縮。如果你對 docker 不熟悉,可以檢視本系列暨前端工程暨高階前端進階的系列文章第 N 篇:使用 Docker 部署前端專案
基於容器的前端部署與反向代理
現在流行的 kubernetes
,docker-compose
應用編排都是基於容器的,所以我們只需要著力於容器,思考如何利用它做多分支部署。
首先解決的問題是多分支部署環境的多域名問題,因此首先要了解如何利用容器來對映域名,以下是兩種常見的方案,但是利用容器的 label 的方式還是多一些
- 基於 container label,如
traefik
以及kubernetes ingress
。 - 基於 environment,如
docker-nginx
。
但是無論基於那種方式的部署,我們總是可以在給它封裝一層來簡化操作,一來方便運維管理,一來方便開發者直接接入。如把部署抽象為一個命令,我們這裡暫時把這個命令命名為 deploy
,deploy
這個命令可能基於 kubectl
也有可能基於 docker-conpose
。
該命令最核心 API 如下:
$ deploy service-name --host :host
複製程式碼
假設要部署一個應用 shanyue-feature-A
,設定它的域名為 feature-A.dev.shanyue.tech
,則這個部署前端的命令為:
$ deploy shanyue-feature-A --host feature-A.dev.shanyue.tech
複製程式碼
現在只剩下了一個問題:找到當前分支。
基於 CICD 的多分支部署
在 CICD 中很容易獲取當前分支的資訊,在 CI 環境中可以通過環境變數獲取到。
如在 gitlab CI 中可以通過環境變數 CI_COMMIT_REF_SLUG
獲取,該環境變數還會做相應的分支名替換,如 feature/A
到 feature-a
的轉化。
CI_COMMIT_REF_SLUG
: $CI_COMMIT_REF_NAME lowercased, shortened to 63 bytes, and with everything except 0-9 and a-z replaced with -. No leading / trailing -. Use in URLs, host names and domain names.
以下是一個基於 gitlab CI
的一個多分支部署的簡單示例
deploy-for-feature:
stage: deploy
only:
refs:
- /^feature\/.*$/
script:
- deploy shanyue-$CI_COMMIT_REF_SLUG --host https://$CI_COMMIT_REF_SLUG.sp.dev.smartstudy.com
environment:
name: review/$CI_COMMIT_REF_NAME
url: http://$CI_COMMIT_REF_SLUG.dev.shanyue.tech
複製程式碼
小結
隨著 CICD 的發展,對快速迭代以及程式碼質量提出了更高的要求,而基於分支的多測試環境則成為了剛需。對於該環境的搭建,思路也很清晰
- 借用現有的 CICD 服務,如
jenkins
,gitlab CI
或者drone CI
,獲取當前分支資訊 - 借用 Docker 快速部署前端或者後端,根據分支資訊啟動不同的容器,並配置標籤
- 根據容器的標籤與當前 Git 分支對前端後端設定不同的域名
另外,這個基於容器的思路不僅僅使用於前端,同樣也適用於後端。而現實的業務中複雜多樣,如又分為已下幾種,這需要在專案的使用場景中靈活處理。
feature-A
的前端分支對應feature-A
的後端分支環境feature-A
的前端分支對應develop
的後端分支環境feature-A
的前端分支對應master
的後端分支環境