iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 3
1

本篇目的

這篇雖然不免俗的介紹到一些眾所皆知的工具,但嘗試用一些比較不死板的方式,寫出基本概念、筆者的看法與一些值得參考的資源,相信可以帶給大家一些啟發。

Babel

babel

Babel 是一種把程式碼編譯成程式碼的 Compiler,由安裝各式各樣的 Plugin 來讓 Compiler 了解特定的語法,並能在語法之間做出轉換。

作者 Sebastian McKenzie 創造 Babel 的前身 6to5 時才 17 歲。當初只是想做出可以把 ES6 程式碼編譯成看得懂的 ES5 程式碼的工具,沒想到最後能做到這種程度,尤其是 v6 的大幅度調整,讓一切變得相當模組化,而且 Preset 真的是一個很棒的東西。這部分也要多感謝 Babel 時下的 Maintainer - Henry Zhu

才沒過多久,它已經成為前端專案的基本配備了,成為瀏覽器相容性與新語法、延伸語法之間的橋樑,帶動 JavaScript 快速向前發展。並衍伸出諸如 babel-preset-envbabili 等等相當有未來性的專案。

The Super Tiny Compiler 這個 Repo 可以了解基本的 Code To Code 的 Compiler 要怎麼用 Tokenizer 把程式碼切成一個個的 Token,接著用 Parser 把 Token 轉換成 AST (Abstract Syntax Tree),經過 Transformer 做 AST 的調整,最後再透過 Generator 產生出程式碼,很推薦大家看看。

Webpack

webpack

在軟體管理的領域裡存在著被稱作「相依性地獄」的死亡之谷,系統規模越大,加入的套件越多,你就越有可能在未來的某一天發現自己已深陷絕望之中。 <出自,http://semver.org/lang/zh-TW/>

所以套件的依賴關係,怎能不謹慎處理,尤其是在程式碼大小關乎網站載入速度的前端領域。

Webpack 是一個 Module Bundler,負責 Resolve Module 間的依賴關係並產生 Bundle。

它變成主流,僅僅是這一年間發生的事,在 React 開發圈已經蠻少看到 Gulp + Browserify 的專案 (Task Runner 的部分也大部分被 NPM Scripts 取代)。確實現在看起來 Webpack 的功能比較容易實現,寫設定檔也比起處理 Stream 來得容易許多而且能重用 Config,也有眾多完善的 Loader 跟 Plugin 可以處理各式複雜問題,但當初被 Webpack 吸引,主要是因為它能在 React 做 HMR 保留 Component 的 State,大幅加快開發速度。

如果想了解 Hot Module Replace (HMR) 的機制原理可以參考這篇 What exactly is Hot Module Replacement in Webpack? (有趣的是,這是 Dan Abramov 在做出 React Hot Loader 之前在 Stackoverflow 所問的一個問題,而回答他的正是 Webpack 的作者 Tobias Koppers)。

React Native 的 Packager 則是在 v0.22.0也實作了HMR

FlowType

flow

靜態型別檢查,更容易寫出高質量的程式碼。例如下面這樣的程式:

function foo(person) {
  if (!person) throw new Error();
  if (typeof person.name !== 'string') throw new Error();
  // ...
}

動態型別的不確定性,會容易出現處理上的瑕疵。而下面這樣處理則清楚許多:

/* @flow */
type Person = {
  name: string;
};
function foo(person: Person): void {
  // ...
}

除了減少錯誤,還能減少執行期的檢查與程式碼的數量。

相對於 TypeScript 是一種語言,FlowType 則是型別註記,對已經熟知 JavaScript 的開發者來說應該很好上手。而現在 React、GraphQL、Relay 這些 Facebook 重要的 JavaScript 開源專案都是使用 FlowType 來撰寫,熟悉它也能比較正確地閱讀這些專案的原始碼。

跟 TypeScript 類似,也會遇到第三方 Library 的 Type 不好處理的問題,不是每個專案都會想用 TypeScript 以及 FlowType,如此一來它們的 Type 要放哪邊就會是個難題,TypeScript 有 typings/typings ,FlowType 則有 flowtype/flow-typed,但這樣專門放 Type 的專案仍然有很多版本、跟專案同步的麻煩。

Jest

jest

筆者早在 Jest v0.6.0 就有在一些自己的 Library 專案開始試用,雖然當時 Jest 藉著 Auto Mock 的名號,號稱要帶給各位 Plainless JavaScript Testing,結果帶給各位 Plainful JavaScript Testing,除了速度相當的慢外,跟很多的套件相處得很不愉快..。

於是今年初,主要是用著 Mocha,搭配著一點點的 Ava。

但沒想到最近試了,捲土重來的 Jest,它現在已經是 v18.0.0 (這是個一年間從 v0.6v18 的轉移),驚為天人,就把 Mocha 跟 Ava 都拋在一邊了,更別說要測試 React Native 的話,Jest 一定是第一選擇,2016 實在是 Jest 奇幻之旅的一年

明顯的優點如下:

  • 速度不錯,能平行在多個 Process 跑測試
  • 在 Sandbox 中執行測試
  • Snapshot Testing
  • 強大好用的 Mock 機制 (個人覺得比 Sinon 好用的多)
  • 功能完善的 Watch Mode,如下圖

watch

Redux

redux

搭配著 React 的單向資料流概念 Flux 曾經群雄割據,每一二個月就會有一個新的霸主 (例如當時的 Fluxible、Alt,都已成為時代眼淚...),最後在 Redux 出現之後幾乎一統江湖。

Redux 當時帶著強大的 Time Traveling Devtools,並完成了簡單明瞭的 Flux 概念,社群也發展出像是 redux-saga 這樣特別的非同步處理方式。

如今 Redux 同時也是 React Hot Loader 的作者 Dan Abramov 已經加入 Facebook 位在倫敦的 JavaScript Tool Team,而 Redux 轉手社群經營的狀況也相當不錯。

整個專案已經相當穩定,鮮少有太大的變更。值得一提的是,最近才剛釋出的 react-redux v5 有著相當大的效能提升

另外,我有做了繁中的文件翻譯,有興趣的人歡迎當 Contributor!

Relay

relay

最初 Facebook 為了改善遇到比較差的網路時在 Mobile 上的狀況,要求極致的 API 查詢效能,而開發出了 Relay,是 GraphQL 的好搭檔,被使用在許多的 Facebook 的 React Native 專案中。

其中可以把眾多的查詢拼裝起來一次送出,還有把資料需求跟 Component 定義在一起的做法,可以減少資料不一致的狀況,並完善的利用 GraphQL 的特性。而且接手了所有的 API 呼叫跟 Cache 操作,既 React 之後把除了 DOM 操作以外另一個複雜的地方也處理掉。

我想 Relay 的原罪之一就是不太好上手,因為它遠大的抱負、以及有別於以往的思維模式,再加上集所有困難的問題於一身:Query Composition、Flatten Cache、Error Handling、Optimistic Updates、Pagination。

不過宣稱「simpler, faster, more predictable」的 Relay 2 已經在產品測試以及寫文件階段,我想明年初應該就會發布了!

國內接觸 Relay 的人不多,不過有漸漸在增加的趨勢。前一陣子在 React 讀書會講了一個 GraphQL + Relay 的主題,也歡迎參考看看。

Relay 也一樣有繁中的文件翻譯,有興趣的人歡迎當 Contributor,尤其是很多中文不順的地方會需要幫忙。

結語

React 的資源跟 Ecosystem 已經十足的強大 (JavaScript、Node 本身也是),Instagram、Airbnb、Uber 等重度使用 React 的公司也帶來一些穩定的力量,也有 FormidableLabsExponent 這樣才華洋溢的公司在 React 圈子大放異彩。

而 Facebook 的動作很快,每年都能帶給大家一些驚喜,緊鑼密鼓在進行的新 React 核心 Reconciliation 演算法 Fiber、以及正在產品測試階段的 Relay 2,都會是很令人期待的。


上一篇
Day 02:快速學會 React 基礎
下一篇
Day 04:Learn Once, Write Anywhere 平台的狂想
系列文
使用 Modern Web 技術來打造 Native App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言