Sam Xiao, Feb.18, 2019
約在 2015 年,主流的 Web 開發架構仍以後端 MVC 為主:
- PHP / Laravel
- Ruby / Ruby on Rails
- C# / .NET MVC
- Python / Django
這類都是 後端
以 MVC 為主,前端
以 jQuery / Ajax 為輔的架構。
這種架構有幾個挑戰:
- 有於重點在後端,時常必須換頁到後端去,使用者會明顯感受到網頁重新載入,視覺與使用感受較差
- 若想減少換頁到後端,就必須大量使用 jQuery / Ajax,則前端就會有大量 JavaScript
- 由於 JavaScript 缺乏 module 概念,實務上常常會看到上千行的 jQuery / JavaScript,導致維護困難
- 由於 jQuery / JavaScript 是躲在後端網頁內,因此大部分的 jQuery / JavaScript 都是由後端工程師撰寫,但由於 JavaScript 語言特性與後端語言明顯的差異,大部分後端工程師選擇逃避原生 JavaScript,而改用較容易的 jQuery,此時都是 Web 工程師都是
全端工程師
- 也由於使用 jQuery,導致大部分
全端工程師
並沒有深入研究 JavaScript,而是認為前端只是控制 HTML / DOM 而已,jQuery 足以,因此沒必要深入研究 JavaScript,導致一些 JavaScript 很重要的語言特性被忽略 (Higher Order Function、Closure、IIFE、Function Composition ...),其實這些 Functional 的語言特性,才是 JavaScript 的精華所在
2015 年開始有一些前端 framework 展露頭角,如 AngularJS、React:
- 後端只寫到 API,以 JSON 與前端溝通
顯示邏輯
寫在前端,而不是以 Presenter Pattern 寫在後端,因此沒有網頁重新載入,視覺與使用感受佳- 前端開始有 Component 概念,也開始使用 ES6 (ECMAScript 2015) 的 module 概念,因此不再出現上千行 JavaScript,容易維護
- 由於使用 ECMAScript 2015,與原本 JavaScript 相比幾乎是全新語言,有學習門檻
- 前端技術發展迅速,開始有
- Node.js 生態圈 (NPM、Yarn)
- ECMAScript 每年會更新一版 (2015 ~2019)
- Babel / Webpack 編譯打包技術 + ESLint (即使 JavaScript 不編譯,亦可享有編譯的優點)
- 層出不窮的 library (RxJS、Ramda ...)
- 層出不窮的 framework (Angular、React、Vue)
- 由於前端技術爆炸,已經不再只有 jQuery,後端也要精通前端已經有難度,因此前後端開始分家,開始有所謂
前端工程師
相較於 jQuery、前端開始有了新的概念:
- Data Binding:傳統 jQuery 直接控制 DOM;現在前端改為控制 data,現在由 framework 處理 data 與 DOM 的改變
- Reactive Programming:傳統 jQuery 是根據 event 去做相對應的處理;現在將 event 視為 stream 處理 (RxJS)
- Functional Programming:由於 JavaScript 深具 Functional 語言特性 (以 Scheme 為原型),原本 OOP 的 MVC 架構蛻變為 FP 的 Pipeline (單向資料流) 架構 ( React 的 Redux、Vue 的 Vuex)
- Webpack Tree-shaking:由於 OOP 大量使用 field,導致 Tree-shaking 無法有效發揮,前端開始使用 FP 方式,以 function 取代 class,並使用 FP 的 Function Composition 取代 OOP 的 DI (Ramda)
可以發現前端的改變:
- 從控制 DOM 轉為控制 data,回歸程式設計的本質
- 由 Object Oriented Programming 改為 Functional Programming
Vue 吸取 React 與 Angular 的優點:
- 從 Angular 學到學習門檻較低的 HTML Template,而非 React 的 JSX
- 從 Angular 學到 directive 控制 HTML,而非 React 直接以 JavaScript 夾雜 HTML
- 從 React 學到 Component 概念,使得
顯示邏輯
得以模組化 - 從 React 學到
狀態管理
概念 (Redux) ,讓跨 component 的溝通更加簡單 (Vuex) - Vue 前期學 Angular 較多,後期則明顯向 React 靠攏
儘管如此,Vue 也有自己的缺點:
-
Vue 的
data
、computed
、props
、method
... 都必須靠this
存取,這是一種具有 Side Effect 的寫法,且有於this
的可變性,導致 Vue 重構的困難 -
Vue 寫法多元,最原始寫法是一種依賴
this
,很像 OOP 又不是 OOP 寫法,後來又開發出 class-component,這是正統 OOP 寫法,風格很像 Angular,但也由於太偏 OOP,導致大部分人寫 Vue 都使用 OOP 思維,而忘記 JavaScript 最重要的 Functional 特性 (Higher Order Function、Closure、IIFE、Function Composition ...)
-
Vue 的
data
、computed
、props
、method
這些本質都是 function,不要將這些寫在 Option Object 內,而將所有的 function 拉出來,也由於看到的是一條條 function,不是 OOP 的 method,有助於發現重複的部分以 Higher Order Function 重構 -
除了 HTML Data Binding 的資料放在
data
外,不要把data
當成 OOP 的 field 使用,如此可避免使用 Side Effect 寫法,而改用 Pure Function 風格 -
將資料從 data 搬到 Vuex 的 state,由於
state
、getter
、mutation
與action
不使用this
,Vue 可徹底從 ES5 的 function 寫法解放,全面改用 ES6 的 Arrow Function -
也由於
state
、getter
、mutation
與action
本質上都是 function,可以很容易抽成 Higher Order Function,也可以使用 Ramda / RxJS 這類 Functional Library,透過 Function Composition 產生state
、getter
、mutation
與action
-
也由於所有的 function 都沒有
this
,都是 Pure Function 沒有 Side Effect,因此很容易重構到適當 module,不必被 Vue 的component
或mixin
所綁架