目錄:
1.為什么要使用熱發(fā)布沛贪;
2.行業(yè)現(xiàn)狀;
3.熱發(fā)布整體設(shè)計(jì)方案废登;
4.上線功能和數(shù)據(jù)情況淹魄;
5.使用過(guò)程中遇到的問(wèn)題;
6.之后需要做的事情堡距;
一甲锡、為什么使用熱發(fā)布
1.實(shí)時(shí)性限制
考拉作為一個(gè)跨境電商類(lèi)的App兆蕉,從最開(kāi)始就注定會(huì)受到政策類(lèi)的條款限制,從而導(dǎo)致經(jīng)常會(huì)出現(xiàn)一些實(shí)時(shí)變更的需求缤沦。而目前這些實(shí)時(shí)性的需求又必須通過(guò)App的直接發(fā)版本來(lái)解決虎韵,不僅發(fā)布周期長(zhǎng),應(yīng)用市場(chǎng)的審核很浪費(fèi)時(shí)間缸废,而且用戶(hù)升級(jí)率也不高包蓝。
2.新功能依賴(lài)升級(jí)
當(dāng)產(chǎn)品策劃提到一些新功能場(chǎng)景時(shí),都必須通過(guò)一個(gè)完整的迭代流程來(lái)進(jìn)行開(kāi)發(fā)企量,最終通過(guò)發(fā)布新版本來(lái)讓用戶(hù)使用到新的功能测萎,開(kāi)發(fā)和測(cè)試周期長(zhǎng)。同時(shí)届巩,用戶(hù)如果想使用新功能硅瞧,必須依賴(lài)升級(jí)。無(wú)法讓舊版本的用戶(hù)使用到新功能恕汇。
3.Bug無(wú)法熱修復(fù)
移動(dòng)開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)出現(xiàn)因?yàn)榭紤]不周導(dǎo)致的一些線上邏輯問(wèn)題或者崩潰問(wèn)題腕唧,一般情況下都會(huì)通過(guò)重新打包發(fā)布應(yīng)用市場(chǎng)來(lái)解決,目前也有更方便的通過(guò)補(bǔ)丁來(lái)解決問(wèn)題拇勃。通過(guò)動(dòng)態(tài)化方案也可以更好的通過(guò)熱發(fā)的方式來(lái)修復(fù)bug四苇。簡(jiǎn)單高效。
4.多端協(xié)作成本高
目前整個(gè)移動(dòng)市場(chǎng)是分為android和ios方咆,當(dāng)需求提出的時(shí)候月腋,會(huì)同時(shí)通知到android和ios兩位開(kāi)發(fā),進(jìn)行需求評(píng)審和功能迭代瓣赂,在需求溝通和實(shí)現(xiàn)過(guò)程中總會(huì)出現(xiàn)各種溝通問(wèn)題導(dǎo)致需求實(shí)現(xiàn)效果不統(tǒng)一榆骚,同時(shí)兩位開(kāi)發(fā)也會(huì)很浪費(fèi)人力。通過(guò)動(dòng)態(tài)化方案煌集,兩端可以共用同一套代碼妓肢,來(lái)解決各自的邏輯,能夠節(jié)省很多人力苫纤。
二碉钠、行業(yè)現(xiàn)狀
目前比較流行的兩種熱發(fā)布解決方案是,facebook的React Native和阿里的weex卷拘。
兩種方案的比較:
相同點(diǎn):
1.兩者的思想是一樣的喊废,都是通過(guò)將js轉(zhuǎn)換成Virtual-dom再映射到Native的對(duì)應(yīng)view組件;
2.遵循 W3C 標(biāo)準(zhǔn)實(shí)現(xiàn)了統(tǒng)一的 JSEngine 和 DOM API栗弟,能夠以web的方式(HTML+CSS+JS)來(lái)開(kāi)發(fā)native頁(yè)面和應(yīng)用污筷;
3.都能夠完成三端渲染,以及功能模塊的動(dòng)態(tài)下發(fā)乍赫;
不同點(diǎn):
1.上層DSL語(yǔ)言不同瓣蛀,前端流行的兩大框架就是React和Vue陆蟆,React Native使用的自家的React,而weex使用的是vue惋增;
2.RN支持ios和Android兩個(gè)平臺(tái)叠殷,web端需要自己支持和兼容;Weex號(hào)稱(chēng)支持到三端诈皿,但是還是有很多的兼容任務(wù)溪猿;
3.RN在打包的時(shí)候會(huì)將基礎(chǔ)解析部分和業(yè)務(wù)邏輯一起打包,所以js文件會(huì)比較大纫塌,而weex只是將業(yè)務(wù)部分打包诊县,具體的解析過(guò)程是在sdk中;所以bundle會(huì)比較写胱蟆依痊;
使用感受:兩種方案我們都進(jìn)行過(guò)調(diào)研,發(fā)現(xiàn)RN在編寫(xiě)過(guò)程中要求還是比較高怎披,沒(méi)有vue上手快胸嘁,而且RN更像是一門(mén)新語(yǔ)言,他為不同的端提供了不同的組件凉逛,而weex更希望這些工作由native做性宏,在weex頁(yè)面中三端使用都是相同的;而且當(dāng)時(shí)RN提供的list組件性能并不是很好状飞,weex提供的是RecyclerView性能相對(duì)好很多毫胜;
因此我們移動(dòng)端動(dòng)態(tài)化采用了weex的方案進(jìn)行。其實(shí)這兩種方案都是采用virtual-dom渲染的方式來(lái)實(shí)現(xiàn)的诬辈,下面簡(jiǎn)單介紹一下weex方案的原理.
weex的原理:
上面這張圖就是weex的原理圖酵使,首先最開(kāi)始是通過(guò)上層的DSL語(yǔ)言來(lái)實(shí)現(xiàn)業(yè)務(wù)功能,實(shí)現(xiàn)完成后會(huì)通過(guò)一些構(gòu)建方式來(lái)進(jìn)行打包焙糟,通過(guò)打包可以將整個(gè)業(yè)務(wù)邏輯打包成一個(gè)jsBundle口渔,jsBundle里面就包含了所實(shí)現(xiàn)的功能,以及可以被下層jsFramework識(shí)別的代碼穿撮。
有了jsBundle之后就可以將它放在后臺(tái)系統(tǒng)中缺脉,這個(gè)就是我們需要熱發(fā)布的功能。
下面一層就是sdk做的事情悦穿,sdk在拿到j(luò)sBundle之后會(huì)通過(guò)jscore進(jìn)行解析攻礼,轉(zhuǎn)換成一個(gè)虛擬dom樹(shù),不同的端在各自的sdk中解析虛擬的dom樹(shù)再渲染成各自端的組件進(jìn)行頁(yè)面的展示咧党。了解了weex的功能原理之后秘蛔,下面介紹下我們整體的熱發(fā)布應(yīng)用方案陨亡。
三、動(dòng)態(tài)化方案整體設(shè)計(jì)
整體的動(dòng)態(tài)化方案功能涉及到前端,后端和移動(dòng)端逞敷,三端的功能需求實(shí)現(xiàn)岛蚤,具體的結(jié)構(gòu)圖如下。
1.整體流程的思維導(dǎo)圖
主要包括三大部分:
weex層芜壁,weex工程負(fù)責(zé)業(yè)務(wù)頁(yè)面的編寫(xiě),打包和發(fā)布;
后臺(tái)層叠赐,熱發(fā)布的后臺(tái)負(fù)責(zé)配置相對(duì)應(yīng)的功能頁(yè)面,提供App檢測(cè)更新的能接口和推送下發(fā)更新包的能力屡江;
app層芭概,App端負(fù)責(zé)檢測(cè)更新,緩存Bundle惩嘉,以及渲染展示的策略罢洲;
下面可以看下整體的熱發(fā)布流程:
最開(kāi)始是編寫(xiě)weex的代碼實(shí)現(xiàn)功能需求,之后通過(guò)webpack打包構(gòu)建jsBundle文黎,將打包構(gòu)建好的jsBundle發(fā)布到自己的服務(wù)器上惹苗,目前使用的是ndp平臺(tái)和nginx服務(wù)器,在ndp平臺(tái)配置好cdn規(guī)則耸峭,這樣每一個(gè)js文件就會(huì)有一個(gè)單獨(dú)的靜態(tài)資源地址桩蓉。之后會(huì)把這個(gè)靜態(tài)地址和頁(yè)面路由信息配置在我們的熱發(fā)布后臺(tái)。用戶(hù)在使用App的時(shí)候就可以拿到熱發(fā)的頁(yè)面渲染劳闹。當(dāng)然再App端也是有兩種方式院究,一種是用戶(hù)主動(dòng)打開(kāi)頁(yè)面觸發(fā)更新接口拉取新數(shù)據(jù),另一種是后臺(tái)發(fā)布后推送給App進(jìn)行后臺(tái)更新本涕。
因?yàn)槲覀冋麄€(gè)策略是分為三部分儡首,所以下面詳細(xì)介紹一下各個(gè)部分所做的工作。
a.weex頁(yè)面開(kāi)發(fā)部署流程
因?yàn)槲冶旧硎强蛻?hù)端開(kāi)發(fā)偏友,對(duì)前端的開(kāi)發(fā)流程不甚了解蔬胯,所以在開(kāi)發(fā)過(guò)程中走了很多彎路。
其實(shí)前端已經(jīng)有很多年的歷史位他,很多開(kāi)發(fā)工具都很完善氛濒,目前我在項(xiàng)目中使用的也是webpack來(lái)進(jìn)行打包構(gòu)建。
因?yàn)閣eex上層的DSL選擇的是vue鹅髓,所以具體需求頁(yè)面的代碼都建議采用vue來(lái)編寫(xiě)(遇到的問(wèn)題可以參考vue的官方文檔https://vuejs.org/index.html舞竿,不過(guò)weex由于是在客戶(hù)端渲染,所以有些vue中俄功能無(wú)法使用到窿冯。
代碼編寫(xiě)不是重點(diǎn)骗奖,重點(diǎn)說(shuō)下webpack打包時(shí)候的配置,我目前是在package.json中配置了兩種打包方案。區(qū)分了開(kāi)發(fā)和生產(chǎn)環(huán)境执桌。在生產(chǎn)環(huán)境下可以對(duì)js文件進(jìn)行壓縮和混淆鄙皇。
通過(guò)webpack在build文件的入口處可以設(shè)置一些公共的組件,減少vue代碼中的引入:
const App = require("${relativePath}")
//全局注冊(cè)組件
Vue.component('wrapperLayout', require("components/wrapper-layout.vue"))
App.el = '#root'
new Vue(App)
我們這里配置了一個(gè)通用的頁(yè)面框架仰挣,包括導(dǎo)航條和網(wǎng)絡(luò)請(qǐng)求loading效果伴逸。
在vue文件build的過(guò)程中要設(shè)置"weex-loader":
let weexConfig = getBaseConfig()
weexConfig.output.filename = 'weex/[name].js'
weexConfig.module.loaders[1].loaders.push('weex-loader')
module.exports = [weexConfig]
build完成之后會(huì)生成對(duì)應(yīng)頁(yè)面的js文件。與java不同膘壶,這些js文件會(huì)將引入的組件和方法全部包含進(jìn)來(lái)错蝴,所以一個(gè)頁(yè)面只有一個(gè)js文件,這樣也就導(dǎo)致了這個(gè)js文件可能會(huì)比較大颓芭。目前來(lái)看顷锰,我們開(kāi)發(fā)的復(fù)雜頁(yè)面最大在2-300k上下。
打包完成后會(huì)將所有的js文件和資源文件通過(guò)構(gòu)建平臺(tái)部署在negix服務(wù)器上亡问,并且關(guān)聯(lián)到cdn馍惹,這樣在頁(yè)面設(shè)置的時(shí)候可以直接使用cdn的鏈接。
b.資源圖片處理過(guò)程
資源圖片目前了解到的可以采用五種方式:local,base64,CDN,iconfont,SVG玛界。目前我們采用的主要是base64和CDN的方式万矾,而前端活動(dòng)頁(yè)采用的方式是iconfont。
2.后臺(tái)接口和數(shù)據(jù)庫(kù)設(shè)計(jì)
a.后臺(tái)數(shù)據(jù)庫(kù)表結(jié)構(gòu)設(shè)計(jì)
后臺(tái)數(shù)據(jù)庫(kù)中存放bundle信息的表結(jié)構(gòu)參數(shù)為:
bundleId慎框,minSupportVersion良狈,bundleVersion,bundleModule笨枯,fileDownloadUrl薪丁,loadType,desc馅精,person严嗜,time
bundleId:當(dāng)前頁(yè)面的唯一標(biāo)識(shí);
minSupportVersion:當(dāng)前頁(yè)面最低可以支持到的App版本號(hào)洲敢;
bundleVersion:當(dāng)前bundle的發(fā)布版本漫玄;
bundleModule:當(dāng)前bundle所屬模塊;
fileDownLoadUrl:bundle的下載地址压彭;
loadType:當(dāng)前bundle頁(yè)面可以使用的加載方式睦优,1:網(wǎng)絡(luò)檢查,先使用本地壮不,二次加載最新汗盘;2:網(wǎng)絡(luò)檢查更新,當(dāng)此即加載询一,使用最新隐孽;
desc:當(dāng)前bundle更新情況的的描述信息癌椿;
person:更新者;
time:更新和上傳時(shí)間菱阵;
數(shù)據(jù)庫(kù)中的表結(jié)構(gòu)為:
bundleId | minSupportVersion | bundleVersion | bundleModule | fileDownloadUrl | loadType | desc | person | time |
---|---|---|---|---|---|---|---|---|
recommendDetail | 3.9 | 1 | seeding | http://gala/3.9/recommend/recommenddetail.js | 1 | 更新了xxx,changeLog... | 張三 | 2017-10-16 |
** 其中bundleId和minSupportVersion一起作為唯一標(biāo)識(shí) **踢俄;一旦兩個(gè)有一個(gè)有變化,就做為一條新的數(shù)據(jù)
** 數(shù)據(jù)庫(kù)的操作有兩種情況: **
** 1.native無(wú)改動(dòng) **
某次更新的內(nèi)容送粱,并不依賴(lài)于WeexSdk和Native的更改,所以之前的所有版本都支持掂之,則后臺(tái)接口直接數(shù)據(jù)庫(kù)中根據(jù)bundleId和appVersion查詢(xún)到當(dāng)前這條數(shù)據(jù)抗俄,更新bundleVersion(加一),替換fileDownloadUrl為新的地址即可世舰。
例如:原來(lái)數(shù)據(jù)庫(kù)中存的是:
bundleId | minSupportVersion | bundleVersion | bundleModule | fileDownloadUrl | loadType | desc | person | time |
---|---|---|---|---|---|---|---|---|
recommendDetail | 3.9 | 1 | seeding | http://gala/3.9/recommend/recommenddetail.js | 1 | 更新了xxx,changeLog... | 張三 | 2017-10-16 |
則更新成:
bundleId | minSupportVersion | bundleVersion | bundleModule | fileDownloadUrl | loadType | desc | person | time |
---|---|---|---|---|---|---|---|---|
recommendDetail | 3.9 | 2 | seeding | http://gala/3.9/recommend/recommenddetail.js | 1 | 更新了xxx,changeLog... | 張三 | 2017-10-16 |
只是文件和版本變了动雹,其他都不變;這樣3.9和4.0版本的App都可以使用此次開(kāi)發(fā)的新功能跟压。
** 2.native有改動(dòng) **
之前的某個(gè)版本在數(shù)據(jù)庫(kù)中有一條當(dāng)前頁(yè)面的數(shù)據(jù)胰蝠。新版本這次更新的內(nèi)容,最新版本才可以用震蒋,之前所有的舊版本都無(wú)法使用茸塞,則在數(shù)據(jù)庫(kù)中插入一條新數(shù)據(jù)。
例如:原來(lái)數(shù)據(jù)庫(kù)中存的是:
bundleId | minSupportVersion | bundleVersion | bundleModule | fileDownloadUrl | loadType | desc | person | time |
---|---|---|---|---|---|---|---|---|
recommendDetail | 3.9 | 1 | seeding | http://gala/3.9/recommend/recommenddetail.js | 1 | 更新了xxx,changeLog... | 張三 | 2017-10-15 |
則更新成:
bundleId | minSupportVersion | bundleVersion | bundleModule | fileDownloadUrl | loadType | desc | person | time |
---|---|---|---|---|---|---|---|---|
recommendDetail | 3.9 | 1 | seeding | http://gala/3.9/recommend/recommenddetail.js | 1 | 更新了xxx,changeLog... | 張三 | 2017-10-15 |
recommendDetail | 4.0 | 1 | seeding | http://gala/4.0/recommend/recommenddetail.js | 1 | 更新了xxx,changeLog... | 張三 | 2017-10-16 |
此次更新之后查剖,數(shù)據(jù)庫(kù)中針對(duì)recommendDetail的bundleId會(huì)存在兩條信息钾虐,第一條給3.9到4.0版本之間的App使用,第二條給4.0版本之后的App使用笋庄。
b.后臺(tái)接口設(shè)計(jì)
app中檢測(cè)更新的接口:
requestParams:bundleId效扫,appVersion;
后臺(tái)接口需根據(jù)bundleId直砂,appVersion在數(shù)據(jù)庫(kù)中查詢(xún)得到不大于appVersion的minSupportVersion最大的一條數(shù)據(jù)返回菌仁;
response:
{
"bundleId":"recommendDetail",
"minSupportVersion":3.9,
"bundleVersion":1,
"fileDownloadUrl":"http://gala/3.9/recommend/recommendDetail.js",
"loadType":1
}
例如:
1.如果當(dāng)前App的版本是3.9,
針對(duì)上面的第一種情況静暂,后臺(tái)要返回給我最新的bundleVersoin為2的recommendDetail.js文件
針對(duì)第二種情況济丘,后臺(tái)要返回給我3.9版本可用的recommendDetail.js文件,
2.如果當(dāng)前App的版本是4.0洽蛀,
針對(duì)上面的第一種情況闪盔,后臺(tái)要返回給我minSupportVersion為3.9,
針對(duì)第二種情況辱士,后臺(tái)要返回給我4.0版本可用的recommendDetail.js文件泪掀。
c.后臺(tái)配置管理系統(tǒng)
3.App端更新展示策略
a.更新邏輯整體架構(gòu)
通過(guò)熱發(fā)后臺(tái)我們可以根據(jù)對(duì)應(yīng)的bundleId拿到需要顯示的Bundle信息,那么我們的native頁(yè)面又是如何知道要用那個(gè)bundleId去請(qǐng)求颂碘,以及顯示的呢异赫?下面看下我們App端的策略椅挣,這個(gè)圖是我們整個(gè)App端的架構(gòu),其中又分為兩大部分塔拳,一部分是路由策略鼠证,一部分是檢測(cè)更新策略。
路由策略
整個(gè)weex頁(yè)面都是基于路由功能來(lái)進(jìn)行展示和跳轉(zhuǎn)的靠抑。也就是說(shuō)每個(gè)weex頁(yè)面都會(huì)有一個(gè)唯一的uri量九。舉一個(gè)例子,比如在App中的A頁(yè)面颂碧,這時(shí)候點(diǎn)了一個(gè)按鈕跳轉(zhuǎn)到B頁(yè)面荠列,而B(niǎo)頁(yè)面是一個(gè)weex頁(yè)面,那么A就會(huì)將B的路由信息傳遞給Router载城,Router會(huì)解析這個(gè)路由信息將他對(duì)應(yīng)的bundleId傳給weexVersionManager肌似,即weex版本管理器,在管理器里拿到bundle進(jìn)行顯示诉瓦,如果B頁(yè)面再出現(xiàn)了跳轉(zhuǎn)邏輯川队,就會(huì)通過(guò)weex和Native的橋接器再將路由信息傳遞給Router進(jìn)行下一次跳轉(zhuǎn)。
顯示更新策略
上面這部分就是Bundle加載和檢測(cè)更新的部分睬澡,具體流程可以看下下面的流程圖固额,這里主要分為兩部分,一部分是顯示策略煞聪,一部分是檢測(cè)更新策略对雪。
先看一下顯示的流程,根據(jù)之前的流程米绕,路由中將頁(yè)面對(duì)應(yīng)的bundleId傳給VersionManager瑟捣,versionManager在拿到bundleId之后會(huì)先在本地檢查是否有可以使用的緩存,如果有緩存會(huì)先取緩存來(lái)加載栅干,如果本地沒(méi)有緩存迈套,則會(huì)去熱發(fā)布后臺(tái)請(qǐng)求最新的bundle,請(qǐng)求回來(lái)之后再判斷是否需 要刷新當(dāng)前頁(yè)面來(lái)進(jìn)行顯示碱鳞。如果網(wǎng)絡(luò)失敗了也會(huì)給用戶(hù)一個(gè)網(wǎng)絡(luò)錯(cuò)誤的提示桑李。
右邊這部分就是檢測(cè)更新的流程,檢測(cè)更新的過(guò)程是在后臺(tái)執(zhí)行的窿给,不會(huì)影響用戶(hù)前臺(tái)的交互贵白。在開(kāi)始檢測(cè)的時(shí)候會(huì)去后臺(tái)查詢(xún)是否有新的bundle可用,拿到返回的數(shù)據(jù)后會(huì)判斷當(dāng)前這個(gè)bundle是否已經(jīng)下載過(guò)了崩泡,如果已經(jīng)下載過(guò)了說(shuō)明本地就是最新的禁荒,則不會(huì)再做其他事情,也不會(huì)影響用戶(hù)的使用角撞。如果 本地沒(méi)有下載過(guò)呛伴,說(shuō)明需要更新和覆蓋之前的緩存勃痴,那么就會(huì)去下載這個(gè)jsBundle,下載成功后將jsBUndle緩存起來(lái)热康。再根據(jù)之前協(xié)議規(guī)則中設(shè)置的loadType進(jìn)行區(qū)分沛申。之前提到了loadType是分為當(dāng)次加載和二次加載,如果是當(dāng)次加載會(huì)直接刷新頁(yè)面姐军,如果是二次加載則等到用戶(hù)第二次進(jìn)入 的時(shí)候才會(huì)使用這個(gè)最新的铁材。
四、線上頁(yè)面及數(shù)據(jù)情況
在考拉AndroidApp中奕锌,目前weex頁(yè)面在考拉App中的占比達(dá)到了10%著觉。目前上線的功能是種草社區(qū)和小考拉問(wèn)答絕大部分頁(yè)面。如下圖:
性能情況:整個(gè)頁(yè)面的渲染時(shí)長(zhǎng)可以維持在1秒內(nèi)歇攻。其中下載js時(shí)長(zhǎng)是:100-200ms固惯。正常頁(yè)面渲染時(shí)長(zhǎng)在150-300ms左右
五梆造、一些經(jīng)驗(yàn)總結(jié)
1.關(guān)于.9圖片的使用:
在img標(biāo)簽里可以使用.9圖片缴守,但是要將resize屬性設(shè)置為stretch,如下:
<img class="comment-reply-bg" src="local: //res/bg_comment_reply" resize="stretch"/>
2.關(guān)于class樣式切換:
<div class="focus-common" :class="[focusStatus?'focused-container':'focus-container']" >
3.style樣式切換:
:style="{color: focusStatus?'#999999':'#8CAA5E'}"`
4.父組件調(diào)用子組件的方法和data:
在子組件中設(shè)置ref即id镇辉,在父組件中即可通過(guò)ref來(lái)獲取到對(duì)應(yīng)的子view調(diào)用子view的方法:
父vue:
<recommendDetailPage ref="detailPage"></recommendDetailPage>
this.$refs.detailPage.setData(this.$refs.detailPage[0].recommendDetail)
5.子組件給父組件回調(diào):
//子組件通過(guò)emit通知父組件屡穗,event中傳參數(shù)
showGoBack(event) {
this.$emit('showgoback',event);
},
//父組件使用子組件時(shí),html中聲明這個(gè)方法忽肛,js中調(diào)用方法
<bridgeWebview :loadUrl="url" class="webview_style" @showgoback="showGoBack"></bridgeWebview>
showGoBack(event) {
console.log("event.canGoBack2:"+event.canGoBack);
},
6.text顯示問(wèn)題
text標(biāo)簽中的內(nèi)容不能換行村砂,否則在手機(jī)上顯示會(huì)出現(xiàn)換行;下面代碼中第二個(gè)會(huì)顯示兩行屹逛。例如:
1. <text >hello world</text>
2. <text >hello world
</text>
六础废、之后還需要做的事情
1.三端共建,提高效率
我們考拉移動(dòng)端目前也在三端通用性上進(jìn)行了進(jìn)一步的調(diào)研和實(shí)現(xiàn)罕模。因?yàn)閕os和android兩端之前的底層支持情況不一樣评腺,導(dǎo)致在共建底層接口和共建組件,以及溝通上會(huì)花費(fèi)一些時(shí)間淑掌。之后的目的主要是可以完善底層的共建框架蒿讥,這樣上層的業(yè)務(wù)才可以在三端通用,提高開(kāi)發(fā)效率抛腕。
2.組件weex的熱發(fā)布
目前我的開(kāi)發(fā)的weex都是頁(yè)面級(jí)別的芋绸,后續(xù)會(huì)在組件級(jí)別上進(jìn)行一些嘗試。并且抽離這些公共組件担敌,打包成npm包摔敛,可以在多個(gè)項(xiàng)目中共用。