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