編寫代碼只是軟件開發(fā)的一小部分碉碉,更多的時(shí)間往往花在構(gòu)建(build)和測(cè)試(test)。之前介紹了前端的單元測(cè)試,這篇再介紹和實(shí)踐一下前端的持續(xù)集成(Continuous integration),簡(jiǎn)寫為CI媒怯。
什么是持續(xù)集成
持續(xù)集成是一種軟件開發(fā)實(shí)踐,即團(tuán)隊(duì)開發(fā)成員經(jīng)常集成他們的工作髓窜,通過(guò)每個(gè)成員每天至少集成一次扇苞,也就意味著每天可能會(huì)發(fā)生多次集成欺殿。每次集成都通過(guò)自動(dòng)化的構(gòu)建(包括編譯,發(fā)布鳖敷,自動(dòng)化測(cè)試)來(lái)驗(yàn)證脖苏,從而盡早地發(fā)現(xiàn)集成錯(cuò)誤。
持續(xù)集成的益處:
- 減少風(fēng)險(xiǎn)
- 減少重復(fù)過(guò)程
- 任何時(shí)間定踱、任何地點(diǎn)生成可部署的軟件
- 增強(qiáng)項(xiàng)目的可見性
- 建立團(tuán)隊(duì)對(duì)開發(fā)產(chǎn)品的信心
集成工具
GitHub 上比較主流的持續(xù)集成工具有 Travis CI 和 Circle CI棍潘;分別占市場(chǎng)占有率前兩位,兩者的功能和使用都比較相似崖媚,其中Travis CI用的最多亦歉,就選擇Travis CI進(jìn)行介紹。
Travis CI 只支持 Github畅哑,不支持其他代碼托管服務(wù)肴楷。這意味著,你必須滿足以下條件荠呐,才能使用 Travis CI赛蔫。
- 擁有 GitHub 帳號(hào)
- 該帳號(hào)下面有一個(gè)項(xiàng)目
- 該項(xiàng)目里面有可運(yùn)行的代碼
- 該項(xiàng)目還包含構(gòu)建或測(cè)試腳本
Travis有兩個(gè)網(wǎng)址,org的那個(gè)是非盈利的泥张,為GitHub上public的repository提供免費(fèi)服務(wù)呵恢;com的那個(gè)是盈利的,可以對(duì)private的提供付費(fèi)服務(wù)媚创。com前100次build是免費(fèi)的瑰剃,此后按月收費(fèi)。
使用很簡(jiǎn)單筝野,用GitHub 賬號(hào)登錄后,Travis 會(huì)列出 Github 上面你的所有倉(cāng)庫(kù),以及你所屬于的組織粤剧。此時(shí)歇竟,選擇你需要 Travis 幫你構(gòu)建的倉(cāng)庫(kù),打開倉(cāng)庫(kù)旁邊的開關(guān)抵恋。一旦激活了一個(gè)倉(cāng)庫(kù)焕议,Travis 會(huì)監(jiān)聽這個(gè)倉(cāng)庫(kù)的所有變化。
流程很簡(jiǎn)明弧关,但絕大多數(shù)復(fù)雜度都集中在這個(gè).travis.yml
文件盅安。這是一個(gè)YAML文件,主要用來(lái)做CI的配置世囊。Travis會(huì)按照這個(gè)文件配置的方式來(lái)運(yùn)行别瞭。
以下是項(xiàng)目中使用travis的簡(jiǎn)單例子:
language: node_js
node_js:
- "8"
install:
- npm install -g codecov
- npm install
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 3 # give xvfb some time to start
script:
- cross-env TRAVIS=true karma start --single-run
- codecov
Travis 的運(yùn)行流程很簡(jiǎn)單,任何項(xiàng)目都會(huì)經(jīng)過(guò)兩個(gè)階段株憾。
- install 階段:安裝依賴
- script 階段:運(yùn)行腳本
Node 項(xiàng)目的install和script階段都有默認(rèn)腳本蝙寨,可以省略晒衩。
- install 默認(rèn)值:npm install
- script 默認(rèn)值:npm test
完整的生命周期,從開始到結(jié)束是下面的流程:
1. before_install
2. install
3. before_script
4. script
5. aftersuccess or afterfailure
6. [OPTIONAL] before_deploy
7. [OPTIONAL] deploy
8. [OPTIONAL] after_deploy
9. after_script
更多用法可查閱官方文檔墙歪,官方文檔比較詳細(xì)听系。
在上面的例子中,每次代碼 push 以后虹菲,Travis 會(huì)自動(dòng)開始構(gòu)建靠胜,并運(yùn)行單測(cè),最后得到構(gòu)建
狀態(tài)如下
點(diǎn)擊狀態(tài)圖標(biāo)毕源,可以在彈出界面中得到該項(xiàng)目的狀態(tài)圖標(biāo)鏈接浪漠。放到repository的README.md中,就可以在GitHub頁(yè)面得到編譯狀態(tài)的展示了脑豹。
另外郑藏,如果多次提交同時(shí)push,默認(rèn)只在最新提交執(zhí)行一次build瘩欺;在git commit中如果包含[skip ci]
或[ci skip]
必盖,該提交就不會(huì)觸發(fā)一次build。
集成測(cè)試覆蓋率工具
代碼覆蓋率報(bào)告可以為編寫測(cè)試程序提供參考俱饿,通過(guò)一些工具歌粥,還可以及時(shí)的把你的代碼的測(cè)試情況及時(shí)的反饋給用戶,讓用戶感知你的測(cè)試是否完備拍埠。
GitHub 上比較主流的代碼覆蓋率集成工具有 codecov 和 coveralls失驶;兩者也差不多,在之前travis的例子中選擇使用了codecov枣购。
同樣使用GitHub 賬號(hào)登錄嬉探,第一次使用時(shí),默認(rèn)是沒(méi)有 repository 的棉圈,需要通過(guò)點(diǎn)擊 + Add my first repository
來(lái)添加需要 codecov 管理的 repository涩堤。無(wú)論 codecov 還是 coveralls,它自身都不會(huì)去運(yùn)行測(cè)試用例來(lái)獲得項(xiàng)目代碼的覆蓋率分瘾,而是通過(guò)收集覆蓋率報(bào)告及其他關(guān)鍵信息來(lái)靜態(tài)分析胎围。codecov 可以接收 lcov, gcov 以及正確的 json 數(shù)據(jù)格式作為輸入信息。
該例子就是在travis CI 平臺(tái)中跑完測(cè)試用例后德召,將測(cè)試報(bào)告中的 lcov 和 json 文件提交至codecov 平臺(tái)進(jìn)行覆蓋率分析白魂,同樣分析的覆蓋率結(jié)果的徽章圖標(biāo)也能從平臺(tái)中獲取,可以加入到GitHub repository 的README.md中上岗。
language: node_js
node_js:
- "8"
install:
- npm install -g codecov
- npm install
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 3 # give xvfb some time to start
script:
- cross-env TRAVIS=true karma start --single-run
- codecov
跨瀏覽器集成測(cè)試
瀏覽器端使用的庫(kù)福荸,在各個(gè)瀏覽器端的兼容性也是非常重要的‰戎溃跨瀏覽器測(cè)試同樣有 2 個(gè)選擇逞姿,SAUCELABS 和 BrowserStack辞嗡,可以進(jìn)行瀏覽器兼容性測(cè)試。這里沒(méi)有詳細(xì)實(shí)踐過(guò)滞造,怎么操作可以去參考文章看续室。
至此,CI 除了能跑跑測(cè)試谒养、顯示覆蓋率之外挺狰,還能自動(dòng)部署發(fā)布,怎樣部署也在 yaml文件中進(jìn)行腳本編寫买窟,這里就不舉例子了丰泊。以上說(shuō)的都是源代碼放在 Github 上的開源代碼,但相信大家接觸得更多的應(yīng)該是公司的私有代碼始绍,私有代碼的項(xiàng)目也有 CI 解決方案瞳购,就是Jenkins,其前身是 Hudson (相信大家都見過(guò)亏推,我們用的所謂的編譯平臺(tái)就是這個(gè)東東学赛,但估計(jì)主動(dòng)去用的不多)。
Jenkins
這里 搭建了一個(gè) Jenkins吞杭, http://10.134.72.178:8080/jenkins/盏浇,搭建過(guò)程不細(xì)說(shuō),說(shuō)下能解決什么問(wèn)題芽狗。比如有這樣的場(chǎng)景:
- 前后端分離后希望將前端主干代碼部署至服務(wù)器绢掰;
- 新項(xiàng)目尚未接入考拉平臺(tái),希望可以部署至服務(wù)器供聯(lián)調(diào)童擎;
- 能每次代碼提交后都能自動(dòng)構(gòu)建自動(dòng)部署滴劲,無(wú)須任何操作;
- 項(xiàng)目緊張時(shí)顾复,領(lǐng)導(dǎo)希望能看到每天程序員提交代碼后班挖,項(xiàng)目的進(jìn)展情況等。
這些場(chǎng)景下捕透, Jenkins 都能幫助解決,凡是需要自動(dòng)構(gòu)建自動(dòng)部署的碴萧,它都能幫上忙乙嘀。這里舉例大致說(shuō)下怎么使用,就以將某個(gè)業(yè)務(wù)系統(tǒng)前端代碼自動(dòng)構(gòu)建部署至nginx服務(wù)器為例破喻。
第一步:新建項(xiàng)目虎谢,左邊菜單第一項(xiàng)。
第二步:進(jìn)行相關(guān)配置曹质,填寫源碼配置婴噩,可選擇倉(cāng)庫(kù)源擎场,git和svn都支持。
第三步:進(jìn)行構(gòu)建觸發(fā)配置几莽,可設(shè)置觸發(fā)構(gòu)建的情形迅办,例如代碼提交時(shí)構(gòu)建,按日程表構(gòu)建等章蚣。
第四步:填寫構(gòu)建部署腳本站欺。
第五步:保存并進(jìn)行構(gòu)建,查看構(gòu)建情況纤垂。
詳細(xì)配置可以上Jenkins中查看矾策,構(gòu)建過(guò)程包括自動(dòng)更新svn代碼,安裝或更新npm包峭沦,進(jìn)行webpack打包贾虽,將打包后的代碼部署至靜態(tài)資源服務(wù)器。至此完成前端代碼的構(gòu)建和部署吼鱼,每次提交代碼蓬豁,構(gòu)建過(guò)程全自動(dòng)運(yùn)行,當(dāng)狀態(tài)指示燈變藍(lán)時(shí)就表示構(gòu)建成功蛉抓,我們可以訪問(wèn)服務(wù)器前端資源了庆尘。
這只是一個(gè)比較簡(jiǎn)單的例子,還有不少其他功能巷送,Jenkin有很多插件驶忌,總之很強(qiáng)大。當(dāng)然不同的項(xiàng)目可能會(huì)有不同的構(gòu)建過(guò)程笑跛,可以自己按需設(shè)定構(gòu)建過(guò)程付魔。
結(jié)語(yǔ)
結(jié)尾來(lái)個(gè)段子:
以前我堅(jiān)持認(rèn)為代碼應(yīng)該是 clean 的,架構(gòu)應(yīng)該是簡(jiǎn)潔的飞蹂,流程應(yīng)該是自動(dòng)化的几苍,文檔應(yīng)該是齊全的,技術(shù)是應(yīng)該分享的陈哑。 效率較高不加班妻坝,結(jié)果 kpi 被差評(píng),領(lǐng)導(dǎo)認(rèn)為我無(wú)所事事惊窖。 最近半年我換了風(fēng)格刽宪,架構(gòu)重度設(shè)計(jì),類名變量模糊不清界酒,沒(méi)有注釋圣拄,現(xiàn)在大家都離不開我了,kpi 也上去了毁欣。
段子笑一笑而已庇谆,最后還是希望能運(yùn)用到前面的持續(xù)集成工具來(lái)實(shí)現(xiàn)流程自動(dòng)化岳掐,重復(fù)性的工作盡量交給機(jī)器自己動(dòng)。