【雜談】是誰發明了輪子?有關前端組件的些許思考與總結

  從業時間稍微長一點咱們都會碰到一個問題:html

    「咱們天天都在進行重複的勞動,有什麼簡便的方式讓咱們擺脫這一枯燥乏味的無差異時間消耗麼?」前端

  也即因爲最近又一次造了一次「輪子」的經歷,讓筆者產生了寫下此文的想法。說正事以前讓咱們簡單回顧下,這個「輪子」的來歷。vue

  其實這大抵也是人類史上的一個謎團,相傳有人說是咱們的老祖宗公輸班在一次偶然的機會下發明的,可是聽說他看到了「風吹着草團滾動的情形」,天縱英才的他就靈感涌現的發明了輪子,固然,也有人說輪子的前身實際是「圓木」,就比如古埃及建造金字塔的時候,運輸碩大的巨石,不依靠圓木一類的工具,幾斤是不可能的;還有考古學家在波蘭的底下墓地中發現了公元4700年前刻在石壁之上有關車輪的描述。react

  總的來講,也許每一個文明都造出了輪子,雖然究竟是哪一個文明先發明瞭輪子是莫衷一是的,可是他們發明輪子都出於一個共同的目標,提供工做效率,下降工做負擔,這彷佛是值得確定的事實。android

  回到以前的話題,筆者最初「造輪子」也就是寫組件的初衷也基於此,而從新「造輪子」的緣由確實由於團隊的技術結構的改變。以前的組件並不是基於新的技術架構而構建,因此爲了適應新的技術架構,必須從新實現一次組件。到這裏這個「造輪子」的味道就變得很奇怪了,原本爲了不重複勞動而產生的避免重複勞動的行爲,最終仍是引發的了重複勞動,想着是否是有些本末倒置了呢?ios

  寫到這裏也讓筆者想起了去年前端圈子裏的比較轟動的事件,本文簡稱「真阿當」事件。隨着時代的進步,技術的發展,前端這個以前並不太受重視的圈子獲得了愈來愈多的關注,因而也有愈來愈多的工具、體系建設的出現,新的「輪子」不斷涌現,可是誰又真的能確信,那些東西真的是這個領域發展真的須要的?誰又能確信,過去的舊輪子真的會被淘汰?web

  其實這個話題自己就是一個羅生門,對於現實發生的事件,每一個人都有基於自身經歷所獨特的認知和理解,這即是人性。理解了這點,咱們且放下關於對錯的爭論,回過頭去看看這些輪子的出現給咱們的工做生活帶來了哪些變化?api

  在jQuery統治前端圈子的時候,幾乎不論大大小小的公司都會使用jQuery,而其自己高效易用的特性,也是其當之無愧的成爲了那個時代最快的最好的輪子。隨着HTML5時代的到來,昔日業界霸主終將走下神壇,如今的世界,React、vue等等一些列新的「輪子」相繼登場,它們在帶給咱們的,不只僅是優化開發模式這麼簡單的體驗了,高度的封裝,縝密的邏輯思想,都是值得咱們學習的地方,但突然有一天,咱們忽然須要dom操做了,咱們卻懵在了原地,不知所措。架構

  jQuery最使人稱道的地方,除了極其強大的鏈式調用(固然兼容性也是很大的有點),而後就是簡易的dom操做,而到了新的時代,新的輪子們經過對dom的抽象,經過使用模板引擎或者其餘的方式,或多或少的封裝了dom,準確的說應該就是隔離了dom,可是這個本來對於咱們來講是一個很好的消息(virtualDom的出現無疑提升了dom渲染的性能),而對於那些並不瞭解dom的新人來講,倒是一個無疑的災難。app

  另外,相信不少童鞋也有作SEO的經歷,若是面對搜索引擎優化,看似與技術並沒有太多關係的話題(的確,不少時候咱們只是從「詞的語義」的層面去優化搜索引擎),可是到了新時代,到了隔離了dom操做的時代,這卻不得不引發咱們又一次的重視(相信我,當你看到一整個頁面確實用div標籤拼接的時候,你也會有一樣的感嘆),要知道HTML5不只提供了新的特性與能力,在語義化上它也作出了更明確的進步,試圖經過規範去下降SEO的難度。

  其實聰明的你也許已經發現,筆者的觀點,也即

    「沒有最好的輪子,只有最適合某個場景、最適合某種業務、最適合某個具體團隊在某個歷史階段局部最優解的選擇罷了。」  

  看着這個模糊的不行的結論筆者本身也笑了XD

  洋洋灑灑地吹了那麼久的牛,也該作點實事了,如下便分享和記錄一下筆者目前的對前端組件認知吧:

  一、API到底該如何設計

  這也是個老大難的問題,如上文所說,「一千個讀者,一千個哈姆雷特」。什麼樣的API是最合理的?這是筆者在開發組件遇到的最頭疼的問題。簡單的API不能提供足夠的功能,複雜的API又提升了組件使用的門檻,而在這一切以前還有一個莫大的前提,你得能用盡量精簡的詞彙準確的表達你須要表達的意思,咱們能夠參考下經典而又複雜的dom操做的幾個API去找找靈感:

    getElementById

    getElelemtsByClassName

    getElementsByName

    getElementsByTagName

還有HTML5時代的兩個等價API:

    querySelectorAll

    querySelector

  筆者最後使用了設計界的一個基本原則——「KISS」,Keep it simple & stupid,極力保證api使用的低門檻(至於緣由後面會提到)。

  二、到底該如何阻止事件穿透

  相信你們在移動端開發都碰到過事件穿透的問題,有點擊事件穿透,有滾動事件穿透(準確的說這個其實並不能叫穿透),公認的阻止穿透的方法是event.preventDefault(),可是對於滾動的穿透則沒有那麼簡單(這種狀況一般發生在彈出層上),一般咱們都須要設置底部(也就是html)的overflow:hidden(一些狀況別忘了margin),可是這樣會致使頁面的scrollTop重置,在彈出層消失的時候咱們還須要去hack它,因此,咱們還會採起另一種曲線救國的方式去實現:即經過prevent touchmove事件阻止彈出層的滾動事件的發生以阻止其冒泡,同時爲了解決彈出層不能滾動的問題,咱們能夠經過touchmove,利用transform去本身實現scroll(固然你也可使用iscroll,也許這也正是iscroll流行的緣由)。

  三、有關全組件和半組件之爭

  簡單地說,對於固定或者相對固定的持續穩定的業務,全組件可以實現一個究極目標,即「最後的開發並不須要寫一句邏輯代碼,而只是須要不斷地調用組件就行了」。可是這是一個究極且十分理想的狀況,業務發展的速度,技術發展的速度,行業發展的速度,世界變化的速度,一切的一切都讓咱們朝向也最終將走向提供最核心最公共的功能的半組件化的道路上。

  四、組件的兼容  

  多是筆者組件開發的特殊性,筆者考慮的組件的特殊的兼容場景,也即筆者指望筆者的組件在react和類react體系中達到某種「巧妙」的平衡,就筆者的團隊而言,不久的未來頗有可能同時跑着以react、preact、inferno爲基礎實現的webapp(至於爲何,聰明的你能夠思考下XD),對於三種類似的平臺,筆者仍是抱着一顆想要全平臺兼容的美好願景的,固然現實是蠻殘酷的(preact和inferno都滿滿的吐槽了react關於refs糟糕的實現,preact則直接表示不予支持,inferno去掉了一些react自做聰明的語法糖,可是仍是閹割了一些功能)。固然爲了達到這個目的,大量的測試老是避免不了的。

  另外值得一提的就是移動時代的雙平臺兼容,受夠了pc上IE帶來的各類喪心病狂的feature以後,在移動端是否是好點了呢?仍是以滾動舉例,ios上webview滾動的時候js是阻塞不執行的,一直到滾動結束纔會執行一次,那麼咱們常常須要使用的吸頂menu不就無法實現了麼?關於這點ios爲本身的坑買了單,提供了position:sticky來作兼容,解決了這個問題。

  再舉一個例子,overflow屬性相信你們都用得不少,雖然一般都是在設置hidden這個屬性上,不過在某些狀況下,存在着須要使用其餘value的狀況,好比這句「overflow:auto」,在android上沒有問題,須要滾動的時候就出現滾動條,不須要滾動的時候這默認不顯示滾動條,可是這樣設置在android上沒什麼問題,在ios上則會出現滾動效果很奇怪的狀況(native快速回彈的效果竟然沒有!)這個時候還須要對ios添加「-webkit-overflow-scrolling: touch;」屬性,才能達到預期的效果,固然,若是你一開始就設置爲「overflow:scroll」的話,就可以開啓這個效果,不過雖然手機上沒問題了,默認scroll在PC上會出現一個滾動條也是一個很尷尬的事情,也正由於如此,纔會有這個屬性來解決這個奇異問題吧。

  固然,這些仍是比較理想的狀況,更復雜的是在Android的上,不一樣的系統內核的兼容性纔是真正頭疼的地方,更有甚者,還有某廠的自研內核,打着完美支持webgl的口號,連Array.prototype.find都不支持,實在使人哭笑不得。因此雖然歷史前進到了mobile上,可是兼容依然是一個任重而道遠的工做。

  五、組件的使用

  組件的使用?爲何的組件的使用會有須要總結的地方呢?讓咱們再看兩個例子:

  埃德溫·德雷克,他是美國第一口油井的鑽井者,也能夠說他就是石油的發現者,可是,他並無享受到發現石油帶來的任何紅利,而是潦倒的過完了本身的一輩子。

  托馬斯·愛迪生,這個你們應該都知道,可是他其實並非發明電燈的人,他甚至仍是一個號稱「飛機是人類歷史上最愚蠢的發明的人」,可是,他最終由於他的「發明」載入史冊,名留青史,他生前的那一堆胡話都變成了軼事。

  人們經常覺得是愛迪生髮明瞭電燈,其實,歷來都不是他發明的,可是,他之因此偉大,是由於他真正的實現了電燈的商業化。而德雷克上校,卻沒有。(限於篇幅筆者便不繼續展開了)回到咱們的話題,你的組件、你的輪子發明的做用就是爲了被使用,而如何讓別人可以更好的使用,這纔是你的組件最大的目標。而針對筆者所在團隊的人文環境和歷史階段,筆者也基於本身的判斷作出了本身的選擇。

  「對人類來講,你發明了什麼也許並不重要,真正重要的是你發明了什麼對人類可以切實起到做用的東西。」

  六、組件的將來

  雖然筆者選擇的半組件的方式,可是這並不意味着組件之間的關係就只是單純的依賴。隨着整個組件體系的完善,從基礎組件到最終成型的組件,高階組件的出現彷佛也是一種必然的選擇(雖然筆者仍在使用mixin),也是爲了以後的可擴展性,基類組件的抽象則是組件工做開始是最重要的一環。

  暫時能總結的就這麼多了。在過去的2016年,筆者的職業生涯迎來了一輪新的機遇與挑戰,也即由這些挑戰,讓筆者可以站在比過去更高的維度上去思考,前端的發展的潮流給做爲一個工程師的我所帶來的一切。

同時,在時代之光點亮了筆者的技術之路的時候,也淺淺的在筆者的生活之路上,勾勒出了一抹新的色彩。

相關文章
相關標籤/搜索