深入Weex中的transformer實(shí)現(xiàn)原理(上篇)

0x1 讀完后希望你會(huì)

  • 了解Weex中,we腳本的各個(gè)標(biāo)簽<template><script><style>解析實(shí)現(xiàn)方式玉转,如何生成可以運(yùn)行的js腳本文件。
  • 基于標(biāo)簽tag,自己實(shí)現(xiàn)一套你喜歡的類(lèi)似we或者微信小程序的腳本語(yǔ)言熄阻。
    • 可以包含表達(dá)式計(jì)算
    • 流程控制

0x2 背景

目前線上App接入的weex版本為0.8.X,距目前最新的0.10.X系列跨度相差較大倔约,但是在保證目前業(yè)務(wù)穩(wěn)定的前提下秃殉,不能直接升級(jí)Weex SDK到最新版。

在升級(jí)前期浸剩,不得不面對(duì)的幾個(gè)問(wèn)題:

  • 目前已開(kāi)發(fā)的大量.we頁(yè)面是否可以在新版Weex運(yùn)行钾军。
  • 繼續(xù)使用已被廢棄的we腳本開(kāi)發(fā)新需求(Weex已經(jīng)推薦用vue來(lái)寫(xiě)頁(yè)面)
    • Vue與Weex兩大生態(tài)的聯(lián)手,Weex官方也在推進(jìn)vue來(lái)編寫(xiě)界面.
    • we腳本將來(lái)很有可能面臨不再被擴(kuò)展維護(hù)乒省,也就是weex很多的新特性在we中不一定會(huì)被支持,除非we與vue的feature更新節(jié)奏保持一致畦木。
    • 據(jù)說(shuō)手淘與貓客已不再使用we編寫(xiě)weex袖扛,而是全部采用vue(求證)。
    • Vue自身生態(tài)龐大十籍,對(duì)vue更好的支持蛆封,反而更利于weex的推廣。

所以在升級(jí)之前勾栗,以weex的transform流程原理為開(kāi)端惨篱,展開(kāi)一些前期的調(diào)研工作,順便學(xué)習(xí)一下weex的toolkit實(shí)現(xiàn)原理围俘。
據(jù)weex的同學(xué)說(shuō)新版的weex是可以跑老we的砸讳,不過(guò)要保證we腳本代碼的嚴(yán)謹(jǐn)性,因?yàn)樾掳娴膉sf runtime校驗(yàn)機(jī)制界牡,更加嚴(yán)格簿寂,某些頁(yè)面可能白屏(What?K尥觥3K臁)。
老話常談挽荠,“Talk is cheap,Show me the code”克胳。

0x3 驗(yàn)證思路

一個(gè)we頁(yè)面被渲染執(zhí)行平绩,可以大致拆分為兩部分。
【.we腳本的打包與編譯】(weex/vue loader漠另,生成標(biāo)準(zhǔn)的js腳本)

    [.we] -> [build] -> output [*.js]

【W(wǎng)eex JS 運(yùn)行時(shí)環(huán)境(JSF)】(負(fù)責(zé)解析運(yùn)行編譯好的js腳本)

    [*.js] -> [weex runtime] -> render [view:page]
Weex模塊構(gòu)成.png

從圖中可以看出 Weex 整體的工作流程捏雌。
首先開(kāi)發(fā)者編寫(xiě) .we 文件。
通過(guò) weex-toolkit 提供的工具將 .we 文件轉(zhuǎn)為js酗钞。

JS Framework 接收并執(zhí)行 js 的代碼腹忽,執(zhí)行數(shù)據(jù)綁定、模板編譯等操作砚作,然后輸出 json 格式的 Virtual DOM 傳遞給移動(dòng)端窘奏。

這篇文章主要分析第一層的transformer的實(shí)現(xiàn)原理。

0x4 we/vue 腳本是如何被解析的

不可不說(shuō)的parse5:
weex-loader中葫录,對(duì)we文件的解析主要依賴第三方開(kāi)源npm組件着裹,html標(biāo)簽解析的parse5,對(duì)輸入的html標(biāo)簽類(lèi)文本,解析后輸出json對(duì)象米同。
關(guān)于輸出的json格式骇扇,可以參考官方的在線playground,http://astexplorer.net/#/1CHlCXc4n4

weex-loader首先通過(guò)parse5 得到we文本的json 結(jié)構(gòu)的樹(shù)結(jié)構(gòu)面粮,
然后Weex-loader的處理流程中少孝,針對(duì)不同標(biāo)簽(<template/> <script/><style/>),分別有對(duì)應(yīng)的解析處理模塊,

Paste_Image.png

大致流程如上圖,從左向右依次為:
1.輸入為原始we腳本文件熬苍。
2.通過(guò)parse5組件解析出對(duì)應(yīng)的jsonobject
3.根據(jù)json object中描述的各部分tag交給對(duì)應(yīng)的處理模塊稍走。

例如一個(gè)template標(biāo)簽的json對(duì)象,在loader中是這樣被處理的柴底,

Paste_Image.png

源碼地址: weex-loader/lib/loader.js

不同的標(biāo)簽類(lèi)型文本會(huì)分配給專(zhuān)門(mén)的parse組件.

Paste_Image.png

源碼地址:weex-loader/lib/parser.js

標(biāo)簽對(duì)應(yīng)的處理模塊如下:
<script> 標(biāo)簽 ————> weex-templater
<style > 標(biāo)簽 ————> weex-styler
<script> 標(biāo)簽 ————> weex-scripter

0x5 weex-styler 簡(jiǎn)介以及CSS預(yù)備知識(shí)

weex-styler負(fù)責(zé)處理weex所支持的css樣式婿脸,以及驗(yàn)證開(kāi)發(fā)者所寫(xiě)的css樣式是否正確。
其中實(shí)現(xiàn)原理是使用開(kāi)源css https://www.npmjs.com/package/css 組件柄驻,根據(jù)css代碼的文本段狐树,生成json object類(lèi)型的 ast節(jié)點(diǎn)信息。要了解weex-styler的處理流程鸿脓,勢(shì)必要了解一下ast以及css的基本概念抑钟。

一張圖看懂CSS構(gòu)成.

A CSS rule-set consists of a selector and a declaration block:

Paste_Image.png

rule-set:包含一個(gè)selector 以及多個(gè)declaration。
selector:樣式選擇器野哭,主要用來(lái)定位元素
declaration:定義樣式屬性以及值味赃。

了解這三個(gè)基本概念之后,看scripter也是輕車(chē)熟路了虐拓,快上車(chē)心俗。
scripter當(dāng)中,通過(guò)css parser得到AST json object,讀取ast.stylesheet.rules獲得到當(dāng)前樣式的rule-set,然后遍歷所有的declaration城榛,校驗(yàn)樣式是否被weex所支持的(因?yàn)閣eex中支持css的樣式有限)揪利,以及簡(jiǎn)單的value字段合法性校驗(yàn)。

![Uploading Paste_Image_374004.png . . .]

源碼:/weex-styler/index.js

weex-styler新老版之差異狠持。

對(duì)Pseudo class樣式進(jìn)行了支持疟位。

Paste_Image.png

新版weex中,支持shorthand writing寫(xiě)法的transition樣式喘垂。

// shorthand writing 
div {
    transition: width 2s linear 1s;
}

div {
    transition-property: width;
    transition-duration: 2s;
    transition-timing-function: linear;
    transition-delay: 1s;
}

0x6 weex-templater 簡(jiǎn)介

解析we腳本中的<template/>標(biāo)簽內(nèi)容甜刻,其核心節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)也是基于parse5解析出的json object,同時(shí)也會(huì)做數(shù)據(jù)綁定正勒,標(biāo)簽驗(yàn)證得院,自動(dòng)修復(fù)common錯(cuò)誤的處理。

<template>
  <div if={{x}}>
    <text onclick="toggle">Toggle: {{result}}</text>
  </div>
</template>
  • 數(shù)據(jù)綁定:
    <text>標(biāo)簽內(nèi)的value,”Toggle: {{result}}”,
    <div>標(biāo)簽內(nèi)的attribute if 中的 “{{x}}”,
    也就這種用戶可以編輯的文本段章贞,需要對(duì)包含的表達(dá)式以及變量進(jìn)行處理,這里的實(shí)現(xiàn)就在var exp = require('./exp’)這個(gè)模塊當(dāng)中祥绞,

該exp函數(shù)有2個(gè)參數(shù),需要轉(zhuǎn)換的字符串文本,以及是否需要轉(zhuǎn)換成function對(duì)象鸭限。

![Uploading Paste_Image_402398.png . . .]

/weex-templater/lib/exp.js

將雙引號(hào)“替換為單引號(hào)’蜕径,去除所有\(zhòng)n換行控制字符。
判斷文本中是否包含表達(dá)式败京,如果不包含兜喻,直接返回原始文本。
根據(jù)生成的token列表赡麦,
文本會(huì)在兩端加入單引號(hào)’
表達(dá)式在兩端(),顯式的加入運(yùn)算優(yōu)先級(jí)朴皆。
比如Toggle: {{result}} => [‘\’Toggle:\’’,’(result)’]
這樣在最后,只需要把結(jié)果列表中的所有元素做一次’+’.join操作隧甚,就可以構(gòu)成了一個(gè)合法的js語(yǔ)句车荔。

  • 事件綁定:
    text中的onclick屬性的值渡冻,templater會(huì)自動(dòng)生成可以調(diào)用toggle函數(shù)的js代碼戚扳。當(dāng)標(biāo)簽的屬性名包含on前綴時(shí),將進(jìn)行事件綁定族吻。
Paste_Image.png

weex-templater/index.js

在checkEvent方法中帽借,通過(guò)把封裝好的function描述字符串eval對(duì)象賦值給value,達(dá)到事件發(fā)生時(shí)觸發(fā)函數(shù)的機(jī)制超歌。


  • 對(duì)template的內(nèi)容砍艾,對(duì)元素標(biāo)簽(如<div/><a/><img/等>),控制語(yǔ)句(if,else,repeat等)做validation,針對(duì)不同標(biāo)簽巍举,會(huì)有額外特殊的驗(yàn)證操作脆荷。

下面舉幾個(gè)典型例子,

  1. 【If】 validation: <if={{x == 1}}> 驗(yàn)證if中包含的value,以及value是否是一個(gè)合法的表達(dá)式蜓谋。
Paste_Image.png
  1. 【else】 validation:當(dāng)遍歷到一個(gè)節(jié)點(diǎn)中包含else時(shí)梦皮,就會(huì)驗(yàn)證前一個(gè)節(jié)點(diǎn)中是否包含了if。
  2. Tag(標(biāo)簽)validation:
    Tag的驗(yàn)證相對(duì)多一點(diǎn)桃焕,因?yàn)椴煌膖ag會(huì)有其特殊的規(guī)則剑肯,
    例如最外層的<template/>只能包含一個(gè)root子節(jié)點(diǎn)。
    container類(lèi)型的標(biāo)簽可以嵌套標(biāo)簽观堂,非container則不可让网。
    <cell>標(biāo)簽可以自動(dòng)補(bǔ)全tree屬性。
  3. <text>標(biāo)簽比較特殊师痕,因?yàn)閠ext里面可以包含任意的字符串溃睹,變量,表達(dá)式,
    例如下面的腳本七兜。
  • 修復(fù)一些簡(jiǎn)單的common問(wèn)題丸凭。
    舉個(gè)例子,比如圖像內(nèi)容腕铸,既可以寫(xiě)成<img>也可以寫(xiě)成<Image>,在templater中是有處理的惜犀。

源碼地址:weex-templater/lib/validator.js

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市狠裹,隨后出現(xiàn)的幾起案子虽界,更是在濱河造成了極大的恐慌,老刑警劉巖涛菠,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莉御,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡俗冻,警方通過(guò)查閱死者的電腦和手機(jī)礁叔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)迄薄,“玉大人琅关,你說(shuō)我怎么就攤上這事〖ケ危” “怎么了涣易?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)冶伞。 經(jīng)常有香客問(wèn)我新症,道長(zhǎng),這世上最難降的妖魔是什么响禽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任徒爹,我火速辦了婚禮荚醒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘隆嗅。我一直安慰自己腌且,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布榛瓮。 她就那樣靜靜地躺著铺董,像睡著了一般。 火紅的嫁衣襯著肌膚如雪禀晓。 梳的紋絲不亂的頭發(fā)上精续,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音粹懒,去河邊找鬼重付。 笑死,一個(gè)胖子當(dāng)著我的面吹牛凫乖,可吹牛的內(nèi)容都是我干的确垫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼帽芽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼删掀!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起导街,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤披泪,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后搬瑰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體款票,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年泽论,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了艾少。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡翼悴,死狀恐怖缚够,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抄瓦,我是刑警寧澤潮瓶,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布陶冷,位于F島的核電站钙姊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏埂伦。R本人自食惡果不足惜煞额,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧膊毁,春花似錦胀莹、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至栅螟,卻和暖如春荆秦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背力图。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工步绸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吃媒。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓瓤介,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親赘那。 傳聞我的和親對(duì)象是個(gè)殘疾皇子刑桑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載 :OpenDiggawesome-github-vue 是由OpenDigg整理并維護(hù)的Vue相關(guān)開(kāi)源項(xiàng)目庫(kù)...
    果汁密碼閱讀 23,137評(píng)論 8 124
  • 來(lái)源:github.com Vue.js開(kāi)源項(xiàng)目速查表:https://www.ctolib.com/cheats...
    zhangtaiwei閱讀 11,626評(píng)論 1 159
  • 前幾天工作遇到不可理喻的事情,很生氣募舟,沒(méi)忍住的就在聊天框里和門(mén)店員工理論了幾句漾月,估計(jì)當(dāng)時(shí)如果是面對(duì)面就吵起來(lái)了,但...
    消失的書(shū)店閱讀 349評(píng)論 0 0
  • 當(dāng)你迷茫的時(shí)候,你不應(yīng)該為此而感到迷茫觅彰。 當(dāng)你孤獨(dú)的時(shí)候吩蔑,...
    ZZZyyyfffang閱讀 1,026評(píng)論 0 0
  • Day 1 火急火燎地趕到機(jī)場(chǎng),往火爐奔去填抬。 8點(diǎn)的重慶還亮著天烛芬,攜程約來(lái)的商務(wù)車(chē)帶我們穿過(guò)大佛寺長(zhǎng)江大橋、五層立...
    月色的筆尖閱讀 537評(píng)論 0 0