《機票航班列表》項目總結

很快沒在公司參考這麼大的項目升級工做了。工做的內容聽起來很簡單,將React改爲咱們平臺事業部的迷你React框架Qreact(https://github.com/RubyLouvre...),讓它能在IE8下跑起來。但事實上讓咱們屢屢碰壁,這是一個很古老很龐大的項目,裏面還有0.14以前的createClass API,須要臨時爲Qreact/anu添加支持。項目在打包時一共涉及到820個模塊,裏面有多少JS文件就更很差說了,你沒法預先裏面有多少怪異寫法,必須讓Qreact/anu能徹底支持這些寫法,不管它是多偏門。javascript

clipboard.png

從7月31日到8月29日,從自信滿滿到愁腸寸斷,開着飛機修引擎,不斷修BUG發版本,裏面的核心算法改了好幾趟。更讓人發愁的是,mac下的虛擬機太很差用了,卡得要命了,總在挑戰咱們的耐性。IE下進行調試是很是痛苦,裏面進行斷點很是麻煩,console.log也比較弱智,不能分析對象裏面有什麼東西。vue

第一個遇到的大麻煩是React的更新機制,這是一個基於列隊的異步操做,不一樣於avalon/vue那樣的基於mircotack(nextTick)的異步操做,也不一樣於angular那樣的基於Promise的異步操做,很具備迷惑性,文檔上也沒有說起到這個實現,只能翻源碼。早期參考dio.js,搞了一個scheduler模塊大抵能契合95%的場影,但咱們須要的是100%兼容。只要用到setTimeout, Promise, requestAnimationFrame這些API就是不正確的。java

第二個是mouseenter/mouseleave事件,這兩個事件沒法冒泡,而react的事件系統是創建在事件代理的基石之上。所以你必須將它冒泡上去,在IE8下咱們想到事件冒充,經過mouseover/mouseout這兩個事件。但在標準瀏覽器,光是事件捕獲也不能模擬事件冒泡的效果,而且它們不是冒泡到頂端,所以事件的觸發路徑須要進行裁減,看一下React的源碼是經過LAC算法實現的(最近公共祖先)。而且在IE8下,如何求取relatedTarget,咱們卡了很久。下面是咱們找到的資料,但有紕漏,咱們改了一下:react

DOM經過event對象的relatedTarget屬性提供了相關元素的信息。這個屬性只對於mouseover和mouseout事件才包含值;git

對於其餘事件,這個屬性的值是null。IE不支持realtedTarget屬性,但提供了保存着一樣信息的不一樣屬性。es6

在mouseover事件觸發時,IE的fromElement屬性中保存了相關元素;在mouseout事件出發時,IE的toElement屬性中保存着相關元素。github

但fromElement與toElement可能同時都有值!算法

//最後找到的方案
function getRelatedTarget(e) {
    if (!e.timeStamp) {
        e.relatedTarget = e.type === 'mouseover'?  e.fromElement: e.toElement 
    }
    return e.relatedTarget
}

https://github.com/RubyLouvre...瀏覽器

機票那邊用了許多浮層,浮層用了mousenter來實現它們。爲了搞清mouseenter的兼容問題,咱們可悲地卡了三個星期。咱們最後才明白,jQuery源碼那個方案也是有問題的。babel

最後一個是打包上線的問題,在壓縮的狀況下IE下出BUG了,老是報anu的某個位置出問題,但將anu剝離出來,又報其餘位置出問題。說明IE報BUG的位置是不對的,但有時是這處出錯,有時是另外一處出錯。咱們懷疑過uglify的壓縮問題,懷疑過es5-shim、es6-sham亂打補丁的問題,懷疑過babel-polyfill的問題。最後給咱們查出是requestAnimationFrame的問題,因爲這是一個DOM API,IE10才支持。而es5-shim,es6-sham,babel-polyfill都是針對JS語言自己,所以怎麼也修復不了。還好,這只是卡了兩星期。

其間,Qreact從1.0迭代到1.0.4,內部的開發版本更是多達7,8次,嚴重考慮人的心智與耐心。最大的收穫是, Qreact終於有高度可用的版本了,也有一個能夠爲本身代言的大項目,咱們的調試技術又大大提升了(二分法老是最有效的)。最大特別感謝馮木地,蒲天依,祝鑫奔,周鑫珏等人的信賴與支持。

https://github.com/RubyLouvre...

相關文章
相關標籤/搜索