摘要:讓人又愛又恨的微信小程序自微信小程序以下簡稱小程序誕生以來,就伴隨著贊譽(yù)與爭議不斷。同時于開發(fā)者來說,小程序的生態(tài)不斷在完善,許多的坑已被踩平,雖然還是存在一些令人詬病的問題,但已經(jīng)足見微信的誠意了。
Taro 介紹
在互聯(lián)網(wǎng)不斷發(fā)展的今天,前端程序員們也不斷面臨著新的挑戰(zhàn),在這個變化多端、不斷革新自己的領(lǐng)域,每一年都有新的美好事物在發(fā)生。從去年微信小程序的誕生,到今年的逐漸火熱,以及異軍突起的輕應(yīng)用、百度小程序等的出現(xiàn),前端可以延伸的領(lǐng)域已經(jīng)越來越廣,當(dāng)然也意味著業(yè)務(wù)在不斷擴(kuò)大。這時候,如何通過技術(shù)手段來提升開發(fā)效率,應(yīng)對不斷增長的業(yè)務(wù),京東前端凹凸實(shí)驗(yàn)室開源多 Taro 就此誕生。讓人又愛又恨的微信小程序
自 2017-1-9 微信小程序(以下簡稱小程序)誕生以來,就伴隨著贊譽(yù)與爭議不斷。從發(fā)布上線時的不被大多數(shù)人看好,到如今的逐漸火熱,甚至說是如日中天也不為過,小程序用時間與實(shí)踐證明了自己的價值。同時于開發(fā)者來說,小程序的生態(tài)不斷在完善,許多的坑已被踩平,雖然還是存在一些令人詬病的問題,但已經(jīng)足見微信的誠意了。這個時候要是還沒有上手把玩過小程序,就顯得非常OUT了。
小程序?qū)τ谇岸顺绦騿T來說應(yīng)該算得上是福音了,用前端相關(guān)的技術(shù),獲得絲般順滑的 Native 體驗(yàn)。小程序給前端程序員打開了一扇新的大門,大家都應(yīng)該感謝微信,但是從開發(fā)的角度來說,小程序的開發(fā)體驗(yàn)就非常值得商榷了,不僅語法上顯得有些不倫不類,而且有些莫名其妙的坑也經(jīng)常讓人不經(jīng)意間感嘆,從市面上層出不窮的小程序開發(fā)框架就可見一斑。以下就盤點(diǎn)部分小程序開發(fā)的痛點(diǎn)。
代碼組織與語法在小程序中,一個頁面 page 可能擁有 page.js、page.wxss、page.wxml 、page.json 四個文件
這樣在開發(fā)的時候就需要來回進(jìn)行文件切換,尤其是在同時開發(fā)模板和邏輯的時候,切來切去會顯得尤其麻煩,影響開發(fā)效率。
而在語法上,小程序的語法可以說既像 React ,又像 Vue,不能說顯得有點(diǎn)不倫不類,但在使用上總是感覺有些別扭,對于開發(fā)者來說,等于又要學(xué)習(xí)一套新的語法,提升了學(xué)習(xí)成本。而且,小程序的模板由于沒有編輯器插件的支持,書寫的時候也沒有智能提示與 lint 檢查,書寫起來顯得有些麻煩。
命名規(guī)范在小程序中到處可見規(guī)范不統(tǒng)一的情況
例如組件的屬性,以最簡單的 button 組件為例,在小程序官方文檔中,該組件的屬性部分截圖如下
button 組件
屬性名既有以中劃線分割多個單詞的情況 session-form,也有多個單詞連寫的情況 bindgetphonenumber。當(dāng)然這也不是最嚴(yán)重的,你可以說事件綁定的規(guī)范就是 bind + 事件名 ,而其他屬性的規(guī)范就是中劃線分割單詞,然而這并不是作為標(biāo)準(zhǔn)
progress 組件
這不統(tǒng)一的標(biāo)準(zhǔn)使得開發(fā)者體驗(yàn)極其難受。
同樣的情況也出現(xiàn)在 頁面 與 組件 的生命周期方法中,頁面 的生命周期方法有 onLoad、onReady、onUnload 等,但到了 組件 中則是 created、attached 、ready 等,這樣規(guī)范又不統(tǒng)一了,為啥 頁面 的生命周期方法是 on+Xxx 的格式,但到了 組件 里卻不一樣了呢,讓人費(fèi)解。
開發(fā)方式小程序官方提供了 微信開發(fā)工具 作為開發(fā)編譯工具,而對于代碼本身沒有提供一個類似 webpack 的工程化開發(fā)工具,來解決開發(fā)中的一些問題,所以小程序原生的開發(fā)方式顯得不那么現(xiàn)代化,這也是很多小程序開發(fā)框架致力于解決的問題。例如,在小程序開發(fā)中
不能使用 npm 管理依賴,在小程序中需要手動把第三方代碼文件下載到本地,然后再 reuqire 進(jìn)行使用,顯得不那么優(yōu)雅
不能使用 Sass 等 CSS 預(yù)處理器,由于沒有預(yù)編譯的概念,小程序開發(fā)中無法使用市面上流行的 CSS 預(yù)處理器,這樣會使得樣式代碼難以管理
不完整的 ES Next 語法支持,小程序默認(rèn)只能支持極少一部分 ES6 規(guī)范的語法,而 ES 是不斷往前發(fā)展的,一些非常優(yōu)秀的新語法特性就不能使用了
手動的文件處理,像圖片壓縮、代碼壓縮等等的一些文件操作,必須手工來處理,顯得有些繁瑣
以上就是從開發(fā)者的角度看到的一些小程序的開發(fā)問題,不過縱然有千般困難,我們總要面對,作為新時代的前端開發(fā)工程師,我們不能一味忍受問題,要保持技術(shù)的頭腦,以技術(shù)作為武器,用技術(shù)手段去提升的我們開發(fā)體驗(yàn)。
能不能用React來寫小程序目前前端界言及前端框架,必離不開依然保持著統(tǒng)治地位的 React 與 Vue,這兩個都是非常優(yōu)秀的前端 UI 框架,而且在網(wǎng)上也經(jīng)常能看到兩個框架的粉絲之間熱情交流,碰撞出一些思想火花,顯得社區(qū)異?;钴S。
而我們團(tuán)隊(duì)也在去年勇敢地拋棄了歷史包袱,非常榮幸地引入了 React 開發(fā)方式,讓我們團(tuán)隊(duì)丟掉了煤油燈,開始通上了電。而且也研發(fā)出了一款優(yōu)秀的類 React 框架 Nerv ,讓我們和 React 開發(fā)思想結(jié)合得更深。
與小程序的開發(fā)方式相比,React 明顯顯得更加現(xiàn)代化、規(guī)范化,而且 React 天生組件化更適合我們的業(yè)務(wù)開發(fā),JSX 也比字符串模板有更強(qiáng)的表現(xiàn)力。那么這時候我們就在思考,我們能不能用 React 來寫小程序?
類比
通過對比體驗(yàn) 小程序和 React ,我們還是能發(fā)現(xiàn)兩者之間相似的地方
生命周期
小程序的生命周期和 React 的生命周期,在很大程度上是類似的,我們甚至能找到他們之間的對應(yīng)關(guān)系
app 及頁面的生命周期
可以看出,對于 app 及 頁面 來說,除了 onShow 與 onHide 兩個方法,其他方法都能在 React 中找到對應(yīng)。
數(shù)據(jù)更新方式
在 React 中,組件的內(nèi)部數(shù)據(jù)是用 state 來進(jìn)行管理的,而在小程序中組件的內(nèi)部數(shù)據(jù)都是用 data 來進(jìn)行管理,兩者具有一定相似性。而同時在 React 中,我們更新數(shù)據(jù)使用的是 setState 方法,傳入新的數(shù)據(jù)或者生成新數(shù)據(jù)的函數(shù),從而更新相應(yīng)視圖。在小程序中,則對應(yīng)的有 setData 方法,傳入新的數(shù)據(jù),從而更新視圖。
兩者都是以數(shù)據(jù)驅(qū)動視圖的方式進(jìn)行更新,而且 api 神似。
事件綁定
小程序中綁定事件使用的是 bind + 事件名 的方式,例如點(diǎn)擊事件,小程序中是 bindtap
1
而在 React 里,則是 on + 事件名 的方式,例如點(diǎn)擊事件, React web 中是 onClick
1
雖然看上去不一樣,但其實(shí)是可以類比的,我們只需要在編譯時將 on + 事件名 的形式編譯成 bind + 事件名 的形式就可以了。
如此看來,兩者之間有些相似,用 React 來寫小程序貌似是可行的,但接下來我們就發(fā)現(xiàn)了巨大的差異。巨大的差異
React 與小程序之間最大的差異就是他們的模板了,在 React 中,是使用 JSX 來作為組件的模板的,而小程序則與 Vue 一樣,是使用字符串模板的。這樣兩者之間就有著巨大的差異了。
JSX
render () { return ({this.state.list.map((item, idx) => ( ) }{item} ))}
小程序模板
{{item}} 走你
眾所周知,JSX 其實(shí)本質(zhì)上就是 JS,我們可以在里面寫任意的邏輯代碼,這樣一來就比字符串模板的表現(xiàn)力與操作性要強(qiáng)多了,況且,小程序的字符串模板功能比較羸弱,只有一些比較基本的功能。那這樣的話,要如何來實(shí)現(xiàn)用 JSX 來寫小程序模板呢。
編譯原理的力量我們可以仔細(xì)來分析我們的需求,我們期望使用 JSX 來書寫小程序模板,但小程序顯然是不支持執(zhí)行 JSX 代碼的(要是支持的話,Taro 應(yīng)該也就不存在了吧),我們也不能期望微信能給我們開個后門來跑 JSX。那么這個時候我們就想,我們要是能夠?qū)?JSX 編譯成小程序模板就好了。
事實(shí)上在我們平時的開發(fā)中,這種編譯的操作到處可見,babel 就是我們最常用的 JS 代碼編譯器,一般瀏覽器是不能支持一些非常新的語法特性的,但我們又想使用它們,這個時候就可以借助 babel 來將我們的高版本的 ES 代碼,編譯成瀏覽器可以運(yùn)行的 ES 代碼。而我們像要將 JSX 編譯成小程序模板,也是同樣的道理。我們首先來了解一下 Babel 的運(yùn)行機(jī)制。
Babel 作為一個 代碼編譯器 ,能夠?qū)?ES6/7/8 的代碼編譯成 ES5 的代碼,其核心利用的就是計(jì)算中非?;A(chǔ)的編譯原理知識,將輸入語言代碼,通過編譯器執(zhí)行,輸出目標(biāo)語言的代碼。編譯原理的一般過程就是,輸入源程序,經(jīng)過詞法分析、語法分析,構(gòu)造出語法樹,再經(jīng)過語義分析,理解程序正確與否,再對語法樹做出需要的操作與優(yōu)化,最終生成目標(biāo)代碼。
Babel 的編譯過程亦是如此,主要包含三個階段
解析過程,在這個過程中進(jìn)行詞法、語法分析,以及語義分析,生成符合 ESTree 標(biāo)準(zhǔn) 虛擬語法樹 AST
轉(zhuǎn)換過程,針對 AST 做出已定義好的操作,babel 的配置文件 .babelrc 中定義的 preset 、 plugin 就是在這一步中執(zhí)行并改變 AST 的
生成過程,將前一步轉(zhuǎn)換好的 AST 生成目標(biāo)代碼的字符串
為了更好地理解這些過程,大家可以利用 Ast Explorer 這個網(wǎng)站接一下自己的代碼,感受一下每一部分代碼所對應(yīng)的 AST 結(jié)構(gòu)。
可以看到,一份源碼經(jīng)過編譯器解析后,會變成類似如下的結(jié)構(gòu)
{ type: "Program", start: 0, end: 78, loc: { start, end } sourceType: "module", body: [ { type: "VariableDeclaration", ... }, { type: "VariableDeclaration", ... }, { type: "FunctionDeclaration", ... }, { type: "ExpressionStatement", ... } ] ... }
其中,body 里包含的就是我們示例代碼的語法樹結(jié)構(gòu),第一個 VariableDeclaration 對應(yīng)的是 const a = 1,第三個 FunctionDeclaration 對應(yīng)的則是 function sum (a, b) { },分別就是 JS 中的變量定義與函數(shù)定義,每一個樹節(jié)點(diǎn)里都會包含許多子節(jié)點(diǎn),這樣就形成了一個樹形結(jié)構(gòu),更多的節(jié)點(diǎn)類型,請參考 babel types。
當(dāng)然我們在這兒只是簡單介紹下編譯原理與 babel,編譯原理是一門非常深奧的課程, babel 也是一個非常優(yōu)秀的工具,希望在后續(xù)的文章中能和大家再詳細(xì)探討這一部分內(nèi)容。
再次回到我們的需求,將 JSX 編譯成小程序模板,非常幸運(yùn)的是 babel 的核心編譯器 babylon 是支持對 JSX 語法的解析的,我們可以直接利用它來幫我們構(gòu)造 AST,而我們需要專注的核心就是如何對 AST 進(jìn)行轉(zhuǎn)換操作,得出我們需要的新 AST,再將新 AST 進(jìn)行遞歸遍歷,生成小程序的模板。
JSX 代碼
{this.props.counter.num}
編譯生成小程序模板
{{counter.num}}
以上僅僅是轉(zhuǎn)換規(guī)則的冰山一角,JSX 的寫法極其靈活多變,通過窮舉的方式,將常用的、React 官方推薦的寫法作為轉(zhuǎn)換規(guī)則加以支持,而一些比較生僻的,或者是不那么推薦的寫的寫法則不做支持,轉(zhuǎn)而以 eslint 插件的方式,提示用戶進(jìn)行修改。目前我們支持的 JSX 轉(zhuǎn)換規(guī)則,大致能覆蓋到 JSX 80% 的寫法操作。
多端發(fā)布輸入一份源代碼,針對不同的端設(shè)定好對應(yīng)的轉(zhuǎn)換規(guī)則,再一鍵轉(zhuǎn)換出對應(yīng)端的代碼。而且由于我們已經(jīng)遵循 React 語法了,那我們再轉(zhuǎn)成 H5 端(使用 Nerv)與 RN 端(使用 React)也就有了天然的優(yōu)勢
設(shè)計(jì)思路但是仔細(xì)思考我們又會發(fā)現(xiàn),僅僅將代碼按照對應(yīng)語法規(guī)則轉(zhuǎn)換過去后,還遠(yuǎn)遠(yuǎn)不夠,因?yàn)椴煌藭凶约旱脑M件,端能力 API 等等,代碼直接轉(zhuǎn)換過去后,可能不能直接執(zhí)行。例如,小程序中普通的容器組件用的是 view ,而在 H5 中則是 div;小程序中提供了豐富的端能力 API,例如網(wǎng)絡(luò)請求、文件下載、數(shù)據(jù)緩存等,而在 H5 中對應(yīng)功能的 API 則不一致。
所以,為了彌補(bǔ)不同端的差異,Taro 需要訂制好一個統(tǒng)一的組件庫標(biāo)準(zhǔn),以及統(tǒng)一的 API 標(biāo)準(zhǔn),在不同的端依靠它們的語法與能力去實(shí)現(xiàn)這個組件庫與 API,同時還要為不同的端編寫相應(yīng)的運(yùn)行時框架,負(fù)責(zé)初始化等等操作。通過以上這些操作,就能實(shí)現(xiàn)一份一鍵生成多端的需求了。在 Taro 最初的設(shè)計(jì)中,我們組件庫與 API 的標(biāo)準(zhǔn)就是源自小程序的,既然已經(jīng)有定義好的組件庫與 API 標(biāo)準(zhǔn),那為啥不直接拿來使用呢,這樣不僅省去了定制標(biāo)準(zhǔn)的冥思苦想,同時也省去了為小程序開發(fā)組件庫與 API 的麻煩,只需要讓其他端來向小程序靠齊就好。
可能有些人會有疑問,既然是為不同的端實(shí)現(xiàn)了對應(yīng)的組件庫與端能力 API (小程序除外,因?yàn)榻M件庫和 API 的標(biāo)準(zhǔn)都是源自小程序),那么是怎么能夠只寫一份代碼就夠了呢?因?yàn)槲覀冇芯幾g的操作,在書寫代碼的時候,只需要引入標(biāo)準(zhǔn)組件庫 @tarojs/components 與運(yùn)行時框架 @tarojs/taro ,代碼經(jīng)過編譯之后,會變成對應(yīng)端所需要的庫。
既然組件庫以及端能力都是依靠不同的端做不同實(shí)現(xiàn)來抹平差異,那么同樣的,如果想為 Taro 引入更多的功能支持的話,有時候也需要按照這個套路來。例如,為了提升開發(fā)便利性,我們?yōu)?Taro 加入了 Redux 支持,做法就是,在小程序端,實(shí)現(xiàn) @tarojs/redux 這個庫來作為小程序的 Redux 輔助庫,并且以他作為基準(zhǔn)庫,它具有和 react-redux 一致的 API,在書寫代碼的時候,引用的都是 @tarojs/redux ,經(jīng)過編譯后,在 H5 端會替換成 nerv-redux(Nerv的 Redux 輔助庫),在 RN 端會替換成 react-redux。這樣就實(shí)現(xiàn)了 Redux 在 Taro 中的多端支持。
Taro 項(xiàng)目官網(wǎng):https://taro.aotu.io/
Taro GitHub:https://github.com/NervJS/taro
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102871.html
摘要:開發(fā)前需要安裝和以及一些需要用到的中間件如果在要使用的話,還需要引入這個庫或者使用示例下面通過實(shí)現(xiàn)一個快速上手。然后開始創(chuàng)建處理這兩個指令的。完成上述三步之后,我們就可以在應(yīng)用的主頁使用相應(yīng)修改并取得新的數(shù)據(jù)了。 本文適合有一定React和Redux基礎(chǔ)的用戶閱讀。 前言的前言 最近被一款來自京東凹凸實(shí)驗(yàn)室的多終端開發(fā)框架Taro吸粉了,官方對 Taro 的簡介是使用React語法,一...
摘要:其他的項(xiàng)目使用了拼裝樣式驗(yàn)證傳入的屬性是否是函數(shù)驗(yàn)證父組件傳入的數(shù)據(jù)格式是否正確五參考文獻(xiàn)談?wù)劦氖褂檬褂脠鼍? 仿 taro-ui 實(shí)現(xiàn) modal 組件 小程序組件. 簡介: 項(xiàng)目中使用到彈窗類的組件,重新制造了一個輪子. 源碼地址: https://github.com/xiangxiong... 編寫完modal組件總計(jì)花了28分鐘. 效果圖: showImg(htt...
摘要:其他的項(xiàng)目使用了拼裝樣式驗(yàn)證傳入的屬性是否是函數(shù)驗(yàn)證父組件傳入的數(shù)據(jù)格式是否正確五參考文獻(xiàn)談?wù)劦氖褂檬褂脠鼍? 仿 taro-ui 實(shí)現(xiàn) modal 組件 小程序組件. 簡介: 項(xiàng)目中使用到彈窗類的組件,重新制造了一個輪子. 源碼地址: https://github.com/xiangxiong... 編寫完modal組件總計(jì)花了28分鐘. 效果圖: showImg(htt...
摘要:多端統(tǒng)一開發(fā)框架優(yōu)秀學(xué)習(xí)資源匯總官方資源項(xiàng)目倉庫官方文檔項(xiàng)目倉庫官方文檔微信小程序官方文檔百度智能小程序官方文檔支付寶小程序官方文檔字節(jié)跳動小程序官方文檔文章教程不敢閱讀包源碼帶你揭秘背后的哲學(xué)從到構(gòu)建適配不同端微信小程序等的應(yīng)用小程序最 Awesome Taro 多端統(tǒng)一開發(fā)框架 Taro 優(yōu)秀學(xué)習(xí)資源匯總 showImg(https://segmentfault.com/img/r...
摘要:個人所有文章同步到前言最近公司準(zhǔn)備開發(fā)幾款可以在微信小程序端和端同時運(yùn)行的一套商城,接著就是任務(wù)下發(fā)嘍,但是有一點(diǎn),時間緊任務(wù)重,直接說其他的不管,反正幾個星期之內(nèi)必須上線,頭疼。 個人所有文章同步到:https://github.com/zhengzhuan... 前言 最近公司Boss準(zhǔn)備開發(fā)幾款可以在微信小程序端和H5端同時運(yùn)行的一套商城,接著就是任務(wù)下發(fā)嘍,但是有一點(diǎn),時間緊任...
閱讀 2193·2021-11-24 09:38
閱讀 3255·2021-11-08 13:27
閱讀 3095·2021-09-10 10:51
閱讀 3162·2019-08-29 12:20
閱讀 674·2019-08-28 18:28
閱讀 3470·2019-08-26 11:53
閱讀 2718·2019-08-26 11:46
閱讀 1527·2019-08-26 10:56