談,前端框架的『御劍之道』

Berwin發表於2018-10-10

你在使劍,是的,但是你的目的是殺人,直追你的目標,忘記手中長劍,才能使出最高的劍法... 而這世上又有多少劍客, 拘泥於手中快劍而落入俗套,終究無法到達登峰造極的境界... ----阿萊克西斯

劍,是劍客的武器,而現代前端工程師的劍可以理解為前端框架(當然不止是前端框架,但今天我們只談前端框架)。

所謂御劍之道,指的是如何駕馭所有前端框架。對,你沒有看錯,是所有,而不是某一個。

如果是介紹如何駕馭某一個框架,那麼本文的標題可能就要改成“御劍之術”,但本文介紹的是“御劍之道”。

現代前端程式設計師剛一入行就要選擇一款前端框架來作為自己的技術棧,比如Vue,React,Angular等。包括各種公司的招聘資訊上也會寫上自己希望應聘者掌握至少一種前端框架。所以很多人就會有一種困惑:我應該選擇哪款框架作為我的技術棧?

圖片來自@jwcarrol
圖片來自@jwcarrol

如果你存在下面這些困惑,那麼本篇文章會幫助到你:

  1. 你是初學者,不知道應該學習哪款框架來入門。
  2. 你是有經驗的程式設計師,對於不斷出現的新東西感到困惑,不知道應該“投資”哪種技術。
  3. 剛學會一個新東西,然後就發現過時了。累覺不愛,求別更新老子學不動了。
  4. 你的團隊為使用哪個框架而爭論不休,甚至發生宗教鬥爭。

我本人對Vue是最熟的,熟悉到什麼程度呢?幾個月前我就已經寫完了一本介紹Vue原理的書(《深入淺出Vue.js》)還沒上市,但我並不覺得自己是Vue陣營的人。我覺得自己是無陣營的,或者換一種角度來講,“框架並不是我的劍”。

這本書是與人民郵電出版社簽約的,預計過不了多久就會和大家見面了。

對於這本書的內容質量大家儘管放心。人民郵電出版社出版的書,質量都不會差。就算大家不相信我,也要相信出版社。

對於初學者來說,開局能夠掌握一把絕世好劍,固然會在前期得到很大的幫助,一招練成,出手就能傷人。但也正是這把劍,如果不能在合適的階段把它丟掉,那麼它會限制自己無法到達登峰造極的境界。

獨孤求敗被稱為『劍魔』,而他最終的境界是無劍。

《天龍八部》中描述段譽無形有質的六脈神劍時,曾寫道:“使劍全仗手腕靈活,但出劍收劍,不論如何迅速,總是有數尺的距離,他以食指運那無形劍氣,卻不過是手指在數寸範圍內轉動,一點一戳,何等方便?(沒錯,前端工程師的劍也是同樣的道理)

1. 重視框架特性,而不是框架語法

很多人在學習前端框架時,會進入到一個誤區,這個誤區是太過在意框架提供的語法(API)。並且喜歡對各種框架孰優孰劣要爭論個高低。

在實際工作中我從來不和人爭論這些,但有一次和朋友們聊天剛好聊到這個話題,我說所有框架都一樣用,只不過語法有點區別。其中一個朋友可能並沒有理解我這句話的意思,然後發了一篇文章說Vue和React在設計理念上是有一些區別的,不只是語法。

設計理念不同導致提供的語法不同,但再怎麼不同,差異再怎麼大,它們要解決的問題是相同的。現在這些框架其實沒有什麼React能做到的事換成Vue就做不了。反而是React能做的事,使用Vue都能做,反之亦然。那麼對於我來說,這兩把劍就是一樣的,只是使用起來手感不太一樣。還是那句話,要直追我們的目標,不要拘泥於手中的劍。

站在“術”的角度看,它們確實不一樣,而且可以說幾乎沒有一樣地方。但是站在道的角度看,它們是一樣的。

所以你會發現,我關注的根本就不是框架提供的語法,我關注的是框架的特性。我說的框架特性,指的不是React提供了JSX,或者Vue提供了模板語法。這些不是我所說的特性,這些其實還是語法。

那麼框架的特性到底指的是什麼呢?我們舉兩個例子來感受一下。

1.1 宣告式 & 資料驅動渲染

更深一步思考,React提供的JSX和Vue提供的模板,它們的目的是什麼?目的是為了實現宣告式渲染的功能。不論是JSX,或者是Vue中的模板,本質上都是描述了『狀態』與『檢視』之間的對映關係。

所以宣告式渲染是框架的特性。

宣告瞭對映關係之後,可以得到一個公式:

UI = render(state)

狀態與檢視之間的對映關係,等同於render函式。熟悉React的同學對這個公式應該並不陌生。JSX與Vue的模板在這一點上是相同的。在框架的內部,不論是JSX還是Vue的模板,最終會編譯成render函式。

上面這個公式,輸入的是state,輸出的是DOM。所以輸入變了輸出就變了。

這個特性就是我們常說的資料驅動檢視。

這裡會引出一個問題,框架必須要知道Web應用在執行時”狀態“是否發生了變化,然後才能使用前面提到的公式重新輸出一個新的UI。所以如何知道Web應用的狀態在執行時是否發生了變化這個問題是所有框架必須去解決的。

解決方案有很多種。不同框架,或者同一個框架的不同版本對這個問題的解決方案都不同,但相同的是都可以解決問題。關於這個問題如何解決,我在曾在我的文章、分享的PPT以及目前還未上市的書中都有詳細的介紹。這個問題不是本文所討論的重點,感興趣的同學可以點選這裡瞭解更多資訊

不同的解決方案,導致的直接結果就是它所提供給使用者的上層語法或API完全不一樣。

不同的永遠是語法,相同的永遠是特性。----Berwin

1.2 元件

現代主流框架都具備的一個特性是“元件”,它們都會以“元件”作為一個基本的抽象單元。

可能不同的框架,它所提供的操控元件的方式不一樣,但概念上是相似的。

之前聽過一次尤雨溪的知乎Live,他將實際應用中的元件分為四種型別並依次介紹了四種元件之間的區別:

  • 展示型元件

    展示型元件是最直接也是最常用的元件,就是用資料渲染檢視,“資料進,DOM出”。

  • 接入型元件

    接入型元件通常會跟接入資料的service層打交道。包含一些和伺服器或資料來源打交道的邏輯,然後接入型元件會將資料往下傳,傳給比較簡單的展示型元件。在React中這種型別的元件被稱為“容器元件(container component)”。

  • 互動型元件

    互動型元件典型的例子是對錶單元件的封裝和增強。大部分元件庫,像ElementUI都是以互動型元件為主。這一類元件會有比較複雜的互動邏輯,但是它是一個非常通用的邏輯,所以它強調複用。

  • 功能型元件

    功能型元件是比較抽象的元件。用Vue舉例,路由的<router-view>和Vue自帶的<transition>都屬於功能型元件。它本身不渲染任何內容,它是一個邏輯型的元件。它通常作為一個擴充套件或一種抽象機制存在。

不同框架操控元件的方式可能不一樣,但使用元件的“心法”永遠是一樣的。這就是關注特性帶來的好處,你可以切換到任意一個框架,使用元件或封裝元件時,總是上面列出的幾種型別。

掌握了“心法”的程式設計師在切換框架時,他的狀態通常是這樣的:我現在想寫一個互動型元件,這個框架都提供了哪些API?去翻翻文件看一下。然後就可以寫出一個很優雅的元件出來,哪怕剛使用這個框架才不到一天。

如果沒有掌握“心法”,用了一個框架寫出的程式碼很糟糕,那麼換了一個框架也不會寫出更好的程式碼,甚至更糟糕。

絕頂劍法,不在於使用的是什麼劍,而是使劍的人。

1.3 其他特性

前面詳細介紹了兩個特性給大家感受下為什麼要重視特性。框架的特性太多不能每一個都詳細介紹,下面列出一些大家比較熟悉的通用特性:

  • 路由
  • 狀態和資料流管理
  • CLI工具
  • 同構/服務端渲染
  • CSS 管理方案
  • ...

1.5 小結

對於初學者不知道應該學哪種框架的問題,其實大可不必這麼糾結,隨便選一個去學(當然是學特性),以後切換到其他框架也是很輕鬆的事情。

有經驗的程式設計師也無需擔心投資了一個框架,剛學會就過時了。框架雖然過時了,但內功心法卻深深地紮在你的腦袋裡。

為團隊選擇技術棧所考慮的因素與人不一樣。就目前來看,各大主流框架所提供的能力與社群的繁榮程度並沒有明顯的差距,所以框架是否靠譜等問題基本上不需要考慮,更多要考慮的因素反而是:

  1. 團隊大部分成員的口味更傾向於哪種。
  2. 技術棧是否容易招人。
  3. 團隊內是否存在該技術棧的專家。
  4. 其他因素。

當團隊確定好了技術棧之後,最重要的是統一。一個團隊內部只存在一種技術棧並打磨出成熟的架構與工作流之後,會大幅提升團隊內的生產效率。

2. 自己動手實現框架特性

在學會了框架的特性之後,若想達到“無劍”的境界,那就需要具備實現這些特性的能力。只有具備了這樣的能力,你才能完全理解一種“特性”,從而達到人劍合一的境界。否則這些特性對你來說是一個黑盒,你永遠不知道它內部發生了什麼,你就只是這把劍的使用者,無法真正的駕馭它們。你會被框架的設計者牽著鼻子走,然後無奈地說一句:求別更新,老子學不動了。

注意,前面提到的是實現這些“特性”的能力,當然如果能實現一個完整的框架更好。但一個框架通常會有很多很繁瑣的東西會消耗掉很多精力,而那些東西其實並不是很關鍵,就像我們平時寫程式碼一樣,總是有很多沒什麼技術含量的體力活。

舉例來說,真正能讓我們完全理解“宣告式 & 資料驅動渲染”這個特性的方式就是親自動手去實現它。當然,不同框架或者同一個框架的不同版本對這個特性的實現方式都不太一樣。但這都沒關係,當我們親自動手用某一種方式實現它之後,我們就能真正理解不同的實現方式之間各自有什麼取捨,只有親自動手實現了某個特性之後我們才能知道不同的實現方式有哪些優勢,為了得到它而付出的代價(捨棄的)是什麼。

對“宣告式 & 資料驅動渲染”這個特性的實現方式感興趣的同學可以看我的另一篇文章《聊聊我對現代前端框架的認知》,在這篇文章中,有一個小節“現代前端框架對渲染的處理”對這個問題進行了相關的介紹。

3. 總結

本文說了這麼多,但其實只講了一個道理,就是要重視『特性』,而不是語法與API。

還有就是本文開頭的那句話,如果想達到登峰造極的境界,就不要過於專注手裡的劍。框架既是神兵利器,也是枷鎖。既賦予我們力量,也束縛著我們。

若想掙脫這個枷鎖,就要達到“手中無劍,心中有劍”的境界。

初學者最開始學武往往急於求成,學了一招出手就想傷人。但殊不知真正的高手很少殺人。

中前期學發,中後期學收,收發自如,神功乃成。

相關文章