組件化已經(jīng)不是什么新名詞了冲秽,大公司好多大型app基本都要經(jīng)歷這個(gè)階段,不同的是我這次是對(duì)B端app做了組件化開(kāi)發(fā)的拆分矩父★鄙#可能有些人會(huì)不明白,B端app為什么會(huì)需要組件化窍株。大部分的B端app也確實(shí)不需要去組件化民轴,但是我們的app卻不同攻柠。我們的app集成了有好幾條業(yè)務(wù)線,隨著業(yè)務(wù)線越來(lái)越多后裸,每條業(yè)務(wù)線功能越來(lái)越重瑰钮,我們的app也越來(lái)越大。如果不組件化的話我們將面臨以下幾個(gè)問(wèn)題微驶!
1.雖然每條業(yè)務(wù)線的代碼是分不同文件夾管理浪谴,但是一些代碼還是不免會(huì)寫(xiě)到一起。比如掃碼因苹,剛開(kāi)始可能只有一個(gè)業(yè)務(wù)線需要掃碼核銷優(yōu)惠券苟耻,所以也就沒(méi)有去抽出共用的。后面又有一個(gè)業(yè)務(wù)線也需要掃碼功能扶檐,這時(shí)候也不復(fù)雜功能都一樣凶杖,就傳入個(gè)類型區(qū)別下也就可以共用了。但是后來(lái)就單單掃描二維碼功能就多了好幾種類型款筑,有的掃出來(lái)的直接是優(yōu)惠券碼智蝠,有的掃描出來(lái)的是個(gè)url,需要截取URL的參數(shù)才能進(jìn)行核銷醋虏。有的一次核銷就結(jié)束寻咒,有的可以多次核銷。這時(shí)候有做了些優(yōu)化颈嚼,去拆模塊毛秘,把公共的拆出來(lái),但是畢竟都是一個(gè)項(xiàng)目代碼都是在一塊的阻课。有些修改可能寫(xiě)在基類里面就一行代碼就能夠解決叫挟,但是也在業(yè)務(wù)類里面去寫(xiě)可能要多寫(xiě)好幾行代碼才能實(shí)現(xiàn)。這時(shí)候就無(wú)法保證開(kāi)發(fā)人員不會(huì)把業(yè)務(wù)代碼寫(xiě)到基類限煞。導(dǎo)致業(yè)務(wù)代碼下沉抹恳,沒(méi)注意的話可能還會(huì)影響其他業(yè)務(wù)線相關(guān)功能。所以我必須把基礎(chǔ)類抽離出去署驻,當(dāng)作一個(gè)單獨(dú)的組件奋献,所有業(yè)務(wù)線都可以依賴它,但不能隨意修改旺上。我把基礎(chǔ)組件單獨(dú)的一個(gè)git管理瓶蚂,控制寫(xiě)入權(quán)限,如果需要修改基礎(chǔ)組件必須要有充分的理由宣吱。最重要的還是讓開(kāi)發(fā)人員養(yǎng)成習(xí)慣窃这。
2.每個(gè)版本產(chǎn)品可能會(huì)同時(shí)進(jìn)行多條業(yè)務(wù)線功能迭代,這樣每次上線都需要協(xié)調(diào)多個(gè)服務(wù)端同時(shí)上線征候,只要有一方臨時(shí)出了問(wèn)題不能上線杭攻,就要等祟敛。等它可以上了,另外一條業(yè)務(wù)線又有別的事情兆解。每次上線發(fā)包都是很麻煩的說(shuō)馆铁。所以我們決定按業(yè)務(wù)線去拆分組件,每個(gè)業(yè)務(wù)線的功能都是一個(gè)單獨(dú)的組件痪宰,同樣有自己的代碼庫(kù)管理叼架,有自己的代碼版本。這樣如果某條業(yè)務(wù)線上不了衣撬,我們只要把這條業(yè)務(wù)線的代碼回滾到上個(gè)版本就可以乖订。其他業(yè)務(wù)線正常打包上線。
3.業(yè)務(wù)線之間的代碼不是全部解耦的具练,可能這次修改了這條業(yè)務(wù)線的某個(gè)功能乍构,可能影響到另外一條業(yè)務(wù)線的功能,但是測(cè)試不知道這2個(gè)業(yè)務(wù)有聯(lián)系或者忘記了去測(cè)試那條業(yè)務(wù)線的功能扛点,導(dǎo)致出現(xiàn)線上問(wèn)題哥遮。
總的來(lái)說(shuō)就是app越來(lái)越大組件化就是必然趨勢(shì),不管是c端app還是b端app都是一樣需要的陵究。唯一不同的是c端組件化考慮的比較多的是組件動(dòng)態(tài)替換眠饮,什么通過(guò)路由注冊(cè)組件切換組件等。而b端不看重這些铜邮,b端需要解決的是我們遇到的問(wèn)題仪召,業(yè)務(wù)組件不耦合,每個(gè)業(yè)務(wù)組件有自己的代碼版本管理松蒜。所以這就導(dǎo)致了組件拆分粒度上有很大的區(qū)別扔茅,我不會(huì)把一個(gè)詳情頁(yè)、一個(gè)首頁(yè)拆成一個(gè)組件秸苗,也不需要通過(guò)修改配置修改某個(gè)頁(yè)面的路由召娜,來(lái)改變進(jìn)入下個(gè)頁(yè)面/組件路徑。
那么在實(shí)現(xiàn)技術(shù)上是否有區(qū)別呢惊楼?
我覺(jué)得應(yīng)該是沒(méi)有啥區(qū)別的玖瘸,每個(gè)組件也都是一個(gè)個(gè)靜態(tài)庫(kù),你可以通過(guò)cocospod的私有庫(kù)來(lái)管理檀咙,也可以通過(guò).xcworkspace等別的方式來(lái)管理你的組件店读。這些都只是方式不一樣應(yīng)用,原理都是一樣的攀芯。組件化需要踩的坑我想應(yīng)該也是差不多的吧!這里簡(jiǎn)單說(shuō)下我們組件化踩過(guò)的坑越到的難點(diǎn)文虏。
1.全局變量侣诺,這個(gè)比較頭疼殖演,由于是同一個(gè)項(xiàng)目所以用的時(shí)候就沒(méi)那么注意。拆的時(shí)候只能去分析年鸳,需要用到的時(shí)候傳入到組件趴久。把你組件里面用到的全局變量都改成你需要的入?yún)ⅰ?/p>
2.宏定義,接口宏都是寫(xiě)在一起的搔确,一個(gè)文件彼棍。這時(shí)候需要去選出你這個(gè)組件需要的比把它們移走。
3.用戶信息和權(quán)限膳算,這個(gè)可能是b端app特有的座硕,可以說(shuō)所有業(yè)務(wù)線都需要根據(jù)權(quán)限來(lái)判斷是否有權(quán)限操作某個(gè)功能。在更新賬號(hào)信息或權(quán)限變更的時(shí)候需要通知到區(qū)別業(yè)務(wù)線(組件)涕蜂。之前用戶信息和權(quán)限是全局變量华匾,所以不需要去通知變更。現(xiàn)在不一樣了机隙,每個(gè)組件需要自己去維護(hù)用戶信息和權(quán)限蜘拉,但又必須和整個(gè)項(xiàng)目保存同步。我把登錄拆成一個(gè)組件有鹿,用戶信息和權(quán)限是來(lái)源于登錄組件旭旭,但是其他業(yè)務(wù)組件又需要這些信息,業(yè)務(wù)組件之前要解藕不能有依賴葱跋,也就是說(shuō)持寄,其他業(yè)務(wù)組件不能直接依賴登錄組件。所以只能通過(guò)主工程來(lái)協(xié)調(diào)年局。
4.我的設(shè)置模塊际看,一個(gè)app往往就只有一個(gè)我的界面,所有業(yè)務(wù)線的設(shè)置都在一起矢否,而這些設(shè)置又會(huì)直接影響業(yè)務(wù)線功能仲闽。如微客服的設(shè)置,我可以設(shè)置是否顯示消息詳情僵朗,也可以開(kāi)啟夜間防打擾模式等赖欣。這個(gè)明顯要調(diào)用到具體業(yè)務(wù)線的方法⊙槊恚可以說(shuō)我的模塊和各個(gè)業(yè)務(wù)線都有關(guān)聯(lián)顶吮。乍看好像拆不了了,難到我們的組件化之路到這就結(jié)束了粪薛?最后做了個(gè)大膽的決定悴了,把設(shè)置頁(yè)面拆開(kāi),屬于自己業(yè)務(wù)線的設(shè)置自己移走。對(duì)一個(gè)頁(yè)面被拆到不同組件里面去了湃交!我的模塊里面的設(shè)置頁(yè)面沒(méi)有邏輯了熟空,有的只是頁(yè)面的組裝。為了業(yè)務(wù)組件的解藕搞莺,我不能在設(shè)置模塊引入其它模塊的類息罗,只能通過(guò)中間件來(lái)實(shí)現(xiàn)。這和c端的路由有點(diǎn)像才沧,只是配置路徑?jīng)]有放到服務(wù)端下發(fā)迈喉。
5.關(guān)于AppDelegate解藕,有些組件的某些數(shù)據(jù)方法需要在AppDelegate中初值化温圆,這就又讓他們耦合在一起了挨摸,所以解藕是必須的。具體的技術(shù)方案可以看這里
6.圖片等資源文件捌木,這個(gè)是組件化必須要面對(duì)的問(wèn)題油坝,但是好多c端文章都沒(méi)提到過(guò),我不知道他們是什么處理的刨裆。這里說(shuō)說(shuō)我的做法澈圈,大家都知道每個(gè)組件其實(shí)就是一個(gè)個(gè)靜態(tài)庫(kù)(如果不能理解可以看我上一篇文章)。靜態(tài)庫(kù)要帶資源就必須打包成.bundle文件帆啃,而在引用的時(shí)候路徑就會(huì)不一樣瞬女。這意味著你所有用到的資源文件的地方都需要改代碼。這個(gè)工作量太大了努潘,而且容易出錯(cuò)诽偷。
有沒(méi)有啥更好的方法嗎?
想了好久最后cocospod給我靈感疯坤,在編譯的時(shí)候通過(guò)腳本合并資源文件报慕。解壓.app文件可以看到所有資源都是放一起的,我們只需要把靜態(tài)庫(kù)下的資源復(fù)制到.app下就可以了压怠。
有更好的方法歡迎指正交流眠冈!
其實(shí)對(duì)這個(gè)圖片方法我不是很滿意,這里說(shuō)個(gè)思路菌瘫,有知道做法的歡迎留言∥贤纾現(xiàn)在多app都用了Assets.xcassets來(lái)管理圖片資源,這個(gè)編譯后的圖片是不可見(jiàn)的加密過(guò)的文件雨让,更加安全雇盖。但是組件里面的資源我也想用Assets.xcassets來(lái)管理圖片,但是編譯好的Assets.xcassets無(wú)法合并栖忠。(簡(jiǎn)單來(lái)說(shuō)就是如何把Assets.xcassets用到靜態(tài)庫(kù))
于是破解了qq崔挖,微信等大型app看他們的圖片也是沒(méi)有用Assets.xcassets來(lái)管理贸街。不知道是不是和我遇到一樣的問(wèn)題……
有方案的歡迎留言