如果你正在籌劃新的前端項目或者重構現有項目,那麼你需要認識到現在的前端開發環境已經今非昔比,這其中有太多的選擇了:react、flux、angular、aurelia、mocha、jasmine、babel、typescript、flow…… 它們的本意是将開發簡單化,卻無形中提高了學習成本,也給未來項目的維護帶來了不确定性。
好在這一現象正在退熱,優勝劣汰,優秀的項目慢慢沉澱下來,開發方式也越來越清晰。有些開發者正在嘗試使用基于上述技術的架構進行開發,也在一定程度上減少了學習成本。
本文中主要介紹了一些我在 web 應用開發中所涉及和推崇的技術,其中有一些技術上存在争議,是以我對于每一技術都隻做簡單的介紹和分析。所有的這些觀點都是基于我個人的經驗和對社群的接觸總結而來的,是以各位還請按需各取所用。

<a></a>
react 可謂風頭正盛一時無兩:
元件化使應用程式更易于開發和維護
學習曲線平緩,核心 api 簡潔清晰,易于學習
jsx 文法不落俗套,充分發揮了 javascript 的能量
天生适配 flux 和 redux
社群活躍且具有創造力,奉獻了諸多優秀的開發工具
單向資料流比雙向資料綁定的方式更适合複雜應用程式,品質更高
支援服務端渲染
雖然比起 ember、aurelia 和 angular 這些功能豐富的架構,react 不是全能手,但 react 的開發環境更加健壯。就目前而言,使用 react 已經不是一個技術選擇,而是一個商業行為,它能提供更高效和更有效的生産力。
當你想開發移動應用時,因為已經學習了 react 文法,是以可以直接上手 react native 開發跨平台應用。
現在,我們已經具有了開發視圖層的能力,接下來,我們需要使用其他工具管理應用程式中的狀态和生命周期,在這裡推薦的工具就是:redux。
為了配合 react,facebook 開發了管理單向資料流的工具 flux,雖然 flux 基本上實作了對單項資料流的支援,但是同時也帶了其他問題,比如如何儲存狀态、何處發起 ajax 請求等等。
為了解決這些問題,又衍生了一系列效仿 flux 模式的架構:fluxible、reflux、alt、flummox、lux、nuclear、fluxxor……
目前來說被開發社群廣泛支援的一個實作就是 redux。
在 redux 中,大多數的元件都是純函數式的元件,也隻有一個集中的存儲和資源中心。redux 的執行個體方法負責整個資料的操作和維護。相比 flux 來說,redux 的思路更加清晰。
更重要的是,redux 非常易于學習。redux 的作者 dan abramov 是一個優秀的教師,他制作了一系列深入淺出的 redux 視訊教程。通過觀看這些視訊,即可成為一個 redux 方面的專家。我曾經見識到一個零基礎的 react 團隊在短短幾周内迅速開發出了測試版産品,且代碼非常穩健和老練。
開發者可能會本能地去嘗試抽象出一個 redux 模闆,這麼做有諸多好處,但請在認清需求的基礎上來封裝模闆,而不要盲目的去嘗試。
是時候抛棄 coffeescript 了,這是因為它的諸多特性已在 es6 中出現類似的文法,而 es6 是實施标準,代表了 javascript 未來的發展方向。
目前最新的浏覽器已經支援了 es6 的大部分特性。babel 是一個強大的轉換工具,用于将 es6 轉換為 es5。此外,根據目标浏覽器可以調整代碼轉換的程度。
那麼是否有類型系統呢?typescript 和 flow 都為 javascript 提供了靜态類型系統,使用靜态類型檢查,可以有效捕獲錯誤,減少測試量。目前來說,我建議對此持觀望态度。
typescript 在盡力讓 javascript 向 c# 或 java 的方向發展,但缺少了許多進階的類型系統特性,比如代數資料類型(algebraic data types)。此外,它不能像 flow 一樣有效地處理 null。
相比而言,flow 更加強大,捕獲的錯誤類型也更多,但難于配置。此外,它對 javascript 新特性的支援弱于 babel,也不支援 windows 系統。
就我個人的角度而言,在前端開發中類型系統并不是至關重要的一環(此處可能有争議)。在類型系統更加健壯且對 babel 更友好之前,還是讓我們靜觀其變吧。
另一個無可争議的工具是 eslint。eslint 支援 es6 文法,還提供了 react 插件,已經不單單是一個代碼審查工具了。目前來說,jslint 已經過時了,eslint 可以替代 jshint 和 jscs 獨樹一幟了。
當你熟悉了 eslint 之後,建議開發者深入地嘗試其中的規則。eslint 捕獲的錯誤越多,産品的穩定性越高。
忘記 bower 吧,用 npm 接管一切。類似 browserify 和 webpack 的建構工具間接提高了 npm 在 web 開發中的地位。使用 npm,版本管理将會更加簡單,也将更多地與 node.js 生态系統接觸。目前對于 css 的處理尚不足夠完善。
除非你樂意在頁面添加數百個腳本标簽,否則的話你應該嘗試用建構工具來打包頁面的資源了。此外,你還需要某些工具讓浏覽器支援 npm 第三方包。在這裡,我推薦你使用 webpack。
一年之前對于上述工作,開發者還有諸多工具可以選擇,比如基于 javascript 的 requirejs、browserify 和 webpack 解決方案,此外還有号稱能對 es6 的子產品進行最佳優化的 rollupjs.
在嘗試了所有的工具之後,我強烈建議開發者選擇 webpack:
通過配置可以應對各種情況
支援主流的子產品加載方式(amd,commonjs,globals)
内部機制可以修複破損的子產品
可以處理 css
全面的緩存系統
支援熱重載
可以加載大多數的資源
webpack 也非常善于處理大型的單頁應用,支援代碼分割和惰性加載。
但是值得注意的是,webpack 的學習曲線異常陡峭。不過一旦你學會了它,那麼你就掌握了最強大的建構系統。
在 javascript 中,有大量可選的單元測試工具,每一個都很穩定和健壯。如果你隻是用于單元測試,那麼現有工具完全可以勝任你的需求。
常見的測試工具有 jasmine、mocha、tape、ava、jest 等,它們各有所長。
我對一個測試架構的要求有如下幾條:
可以在浏覽器運作,便于調試
執行速度快
便于處理異步測試
便于在指令行中使用
可以相容任意斷言和資料模拟的第三方庫
第一條标準就排除了 ava 和 jest。
javascript 并沒有一個類似 java 或 .net 的核心工具庫,是以開發者大都會從外部引用一個外部工具庫。
許多基于 react 的應用程式都不再使用 jquery 了。除非你正在維護一個陳舊的項目或者用到的第三方庫依賴了 jquery,否則已經沒有必要使用它了。
當然也可以其他優秀的第三方庫異步擷取資料,但我覺得 fetch 已經夠用了。
同構 javascript 是指同時運作在用戶端和服務端的 javascript,常用于在服務端預先渲染頁面,提高性能,便于 seo。使用 react 可以實作同構 javascript,但是并不簡單,它提高了程式的複雜度,限制了開發者可選的工具和第三方庫。
如果你正在建構一個 b2c 的站點,比如電商網站,那麼你可能就需要使用同構 javascript。不過,對于内部站點或者 b2b 程式,性能就不是最重要的了,則同構 javascript 也就不是太重要了。
所有已知的規範都各有缺陷,有些過于複雜,有些隻能處理資料讀取而不嗯那個更新,有些和 rest 差異顯著。許多開發者選擇自己開發,但是還會遇到上述的問題。
我不認為上述有一個完美的解決方案,但我對 api 有一個自己的認知:
可預測,遵循一緻性協定
支援在一次查詢中擷取多個實體
支援更新操作
易于調試
易于使用
到目前為止,我還沒有發現滿足上述所有條件的解決方案。
這是建立跨平台軟體最簡單的方式,而且還可以利用上述的所有工具。此外,electron 有完整的文檔和活躍的開發社群。
下面是一些我在 twitter 上關注的對象:
<a href="https://twitter.com/floydophone" target="_blank">pete hunt</a>
<a href="https://twitter.com/reactjs" target="_blank">react</a>
javascript 的生态環境發展迅速,正日益強大起來。react 的最佳實踐正在固化,周邊工具的職責和能力也日益清晰。
最重要的事情就是要牢記:保持簡潔,按需使用。
如果你的應用程式隻有兩三屏,那麼就無需使用路由系統;如果你正在建立一個單頁應用,那麼甚至不需要 redux,隻需要 react 自己的 state 屬性即可;如果你正在建立一個簡單的 crud 程式,那麼你就不需要使用 relay;如果你正在學習 es6,并不需要深入地了解 async/await 或裝飾器;如果你剛剛開始學習 react,并不需要使用熱重載和服務端渲染;如果你剛剛接觸 webpack,你就不需要分離代碼和合并多個資源;如果你剛剛學習 redux,你不需要了解使用 redux-form 和 redux-sagas。
保持簡潔,每次隻做一件事!
本文來自雲栖社群合作夥伴“linux中國”
原文釋出時間為:2013-04-02.