前端 2017: 舉要刪蕪

guoyang134340發表於2019-02-28

前端 2017: 舉要刪蕪

2017 年發生了很多事,想起來,嗯,確實有點多。我們都喜歡拿前端開發領域的變化之快開玩笑,而在過去幾年中事實也確實如此。

儘管聽起來可能會有些陳詞濫調,今天我想說事情不一樣了。

前端趨於穩定 —— 流行的庫基本上已經得到了大眾化而不是被競爭者搶去風頭 —— 同時 web 開發變的很棒了。

這篇文章,我將著眼於大的趨勢來總結今年前端生態中發生的一些重要事件。

統計資料

很難說什麼是下一件大事什麼時候到來,特別是你還在上一件大事之中時。獲取開源工具正確的資料很難,通常情況下我們看下面幾個地方:

  • GitHub star 數量 跟流行庫趨勢有一丟丟關聯,但人們通常只是給那些有趣的專案 star 然後再也不會來了。
  • Google 趨勢 可以幫助我們粗糙的看到流行趨勢,但是不能提供足夠的資料來與一些特定的工具集做對比。
  • Stack Overflow 問題數量 更多的只是可以看出人們對這一項技術的問題而不是這個東西的流行度。
  • NPM 下載量 是人們下載這些庫最精確的統計資料,即使這些也不是 100% 準確的,因為包括了一些可能的持續整合的自動下載資料。
  • 一些調查 比如 2017 年 JavaScript 的發展 是基於大量樣本( 20,000 個開發者)的調查,這對看出趨勢很有用。

框架

React

React 16 在 9 月釋出,帶來一個完全重寫的核心架構,同時沒有任何重大 API 的變化。這個新版本提供了改進的錯誤處理機制 error boundaries,以及支援將渲染樹的一個子部分渲染到另一個 DOM 節點上。

React 團隊重寫核心庫是為了將來更好的支援非同步,這是現在的版本做不到的。非同步渲染下,React 在渲染大型應用時將不會阻塞主執行緒。這一計劃是為了在未來的 React 16 的小版本提供這一可選功能,所以你可以在 2018 前期待一下這個功能。

React 在前段時間關於 BSD 協議的爭論後 切換到了 MIT 協議。由於先前條款的太多限制,導致了很多團隊考慮切換一個備選的 JavaScript 檢視框架。然而,一直有爭論這個是 無依據的, 同時新的專利協議讓 React 的使用者受到了更少的保護。

Angular

在各種 beta 版本釋出之後和候選版本中,Angular 4 於三月釋出了。這個版本的關鍵特性是預編譯 —— 在 build 時編譯而不是 render 時編譯。這意味著 Angular 應用程式不再需要為應用程式檢視提供編譯器 ,從而大大減少了包的大小。此版本還改進了對伺服器端渲染的支援,併為 Angular 模板語言增加了許多小的“生活質量”改進。

在 2017 年,相對 React 來說,Angular 持續丟失份額。雖然 Angular 4 是一個流行的版本,它還是離年初時的高點很遠。

前端 2017: 舉要刪蕪

Angular、React 和 Vue 的 NPM 下載量

來源: npmtrends.com

Vue.js

對 Vue 來說,2017年是偉大的一年,使得它作為一個前端檢視層的框架與 React 和 Angular 並列。它因為簡單的 API 和全套的企業解決方案而流行。由於採取類似 Angular 的模版語言和類似 React 的元件化思想,它常作為這兩者之間的折中方案。

Vue 在過去一年裡爆炸式的增長。同時產生了數量相當多的 流行元件庫 和模版專案。

大量的公司也開始採用 Vue —— Vue—Expedia, Nintendo, GitLab 包括很多其他專案

在年初,Vue 有 37k GitHub star 和 npm 上每週 52k 的下載量。到 12 月中旬時,它已經有了 76k 的 star 和每週 266k 的下載量,分別是以前的兩倍和五倍。

這對比 React 仍然很蒼白,根據 NPM 的資料 React 有每週 1600k 的下載量。可以期待 Vue 的繼續高速成長,2018 也許它會成為最頂級的兩個框架之一。

總結: React 目前領先,但是 Angular 仍在追趕。同時,Vue 可以感受到人氣的飆升。

ECMAScript

在全面的提議流程完成之後,JavaScript 的 2017 ECMAScript 標準在 6 月釋出,包含一些開創性的特性,比如說非同步函式,共享記憶體和原子操作。

非同步函式可以讓我們寫簡潔清晰的非同步程式碼,它們現在被所有瀏覽器支援,在升級到 V8 5.5 之後,NodeJS 在 v7.6.0 中增加了對它們的支援,在 2016 年末釋出同時帶來了重要的效能和記憶體優化。

共享記憶體和原子操作是一個非常重要的特性,但還沒有引起足夠的重視。共享記憶體由 SharedArrayBuffer 構造實現,允許 web workers 在記憶體中訪問陣列中相同的 bytes。 Workers (和主執行緒) 使用 Atomics 提供的原子操作方法在不同執行上下文中安全的訪問記憶體。SharedArrayBuffer 提供相比較 message 一種相對於物件的傳遞更快的通訊方法。

採用共享記憶體在將來將非常重要,對 JavaScript 應用和遊戲貼近原生的效能意味著 web 平臺將變得及其有競爭力。應用在瀏覽器中可以變的更加複雜和做更多昂貴的操作,同時不需要犧牲效能或者把任務放在後端。一個真實的共享記憶體的並行架構對用 WebGL 和 web workers 來開發遊戲的人是非常棒的優勢。

截至2017年12月,所有主流瀏覽器都支援這一特性,同時 Edge 在 v16 之後開始支援,Node 不支援 web workers,所以沒有計劃支援共享記憶體。但是,它們在重新考慮對 worker 的支援,所以還是有可能在將來找到把這一特性放在 Node 中的方式。

總結: 共享記憶體讓 JavaScript 的平行計算更加簡單和高效。

WebAssembly

WebAssembly (或者 WASM) 提供一種用其他語言編寫然後編譯成可以在瀏覽器中執行的方法。這種偏底層的類彙編的語言設計出來用來獲取接近原生的效能。JavaScript 現在可以通過新的 API 載入 WebAssembly 的模組。

這個 API 還提供一個可以讓 JavaScript 用 WebAssembly 模組例項,直接讀取和操作記憶體的記憶體建構函式, 可以和 JavaScript 應用高度整合。

所有主流瀏覽器現在都支援 WebAssembly,Chrome 在五月,Firefox 在三月,Edge 在十月。Safari 在第 11 個版本,和 MacOS High Sierra 一同釋出,使用原版本的現在可以獲取更新。Chrome 安卓版以及 Safari 移動端現在都支援 WebAssembly。

你可以使用 emscripten 編譯器將 C/C++ 程式碼編譯成 WebAssembly,RustOCaml 也可以。同時還有很多種方法將 JavaScript(或者其他類似的)編譯成 WebAssembly。比如說,Speedy.jsAssemblyScript使用 TypeScript 來檢測型別,但是新增了低階的型別和基礎的記憶體管理。

這些專案暫時都還沒有在生產環境,同時他們的 API 經常變化。有了把 JS 編譯成 WebAssembly 的願望,人們可以預知這些專案可以 在 WebAssembly 的流行中獲取動力。

同時已經有很多有趣的 WebAssembly 專案。有一個針對 C++ 的 虛擬 DOM 實現,允許用 C++ 建立整個前端應用。如果你的專案使用 Webpack,有一個 wasm-loader 就不需要手動的操作 fetch,直接解釋 .wasm 型別的檔案。WABT 提供了一堆將二進位制和 WASM 二進位制的文字格式,列印資訊之間轉換的工具,以及 merge .wasm 檔案。

預計 WebAssembly 將在未來一年變得更加流行,因為更多的工具已經開發出來,JavaScript社群也在意識到它的可能性。它現在還在 “試驗” 階段,瀏覽器也剛開始支援。它將成為優化 CPU 密集型任務和影象及 3D 處理的好工具。最終,隨著它的成熟,我推測會在日常應用中獲得更多的使用案例。

總結: WebAssembly 最終會改變一切,但它現在還很新。

包管理工具

2017 年 JavaScript 包管理工具也發生了鉅變,Bower 持續衰落,被 NPM 替代。它最後的版本是 2016 年 9 月,它的管理者現在官方建議使用者在前端專案裡使用 NPM。

Yarn 在 2016 年 10 月釋出給 JavaScript 包管理帶來革新。雖然它使用 NPM 相同的包倉庫,Yarn 提供了更快的依賴下載,安裝速度和更友好的 API。

Yarn 的 lock 檔案可以確保每次重新 build 後的檔案在不同機器上總是一致的,同時離線模式即在使用者不聯網情況下重新安裝包。因為它的受歡迎程度大大增加,成千上萬的專案開始使用它。

前端 2017: 舉要刪蕪

GitHub Yarn (紫) 和 NPM (棕). 來源: GitHub Star 歷史

NPM 作為反擊,帶來了巨大效能改變和 API 徹底調整的 v5 版本。同時 Yarn 宣佈了 Yarn Workspaces, 允許跟 Lerna 類似的高階 monorepo 支援。

還有更多除 Yarn 和 NPM 之外的 NPM 客戶端,比如另一個流行的 PNPM,宣稱它是 “更快,更節省儲存的包管理工具”,不同於 Yarn 和 NPM,它保留對所有安裝包的全域性快取,同時向你的軟體包的 node_modules 檔案中新增這些符號連結。

總結: NPM 針對 Yarn 的流行迅速的調整自己,他們都很棒。

樣式表

最近的更新

在過去的幾年裡 CSS 前處理器比如 SASS, Less 和 Stylus 變得很流行,在 2014 年釋出的 [PostCSS] (https://github.com/postcss/postcss) 在 2017 真正的爆發,成為最流行的 CSS 前處理器。不同於其它前處理器,PostCSS 採用與 Babel 類似的外掛模組的方法。在轉換樣式表之外它還提供 linter 和其他工具。

前端 2017: 舉要刪蕪

2017 NPM PostCSS, SASS, Stylus, 和 Less 下載量

來源: NPM 統計資料,2017 年 12 月 15 日

還有一些基於元件開發時使用 CSS 的底層問題需要解決。特別是,全域性名稱空間讓單個元件的分離樣式開發很困難。讓 CSS 檔案在另一個檔案而不是在元件程式碼裡意味著佔用更多空間同時在開發中需要引用兩個檔案。

CSS 模組化 通過新增元件單獨的名稱空間來分離元件和通用的樣式,這可以用不同的類名來為每個類來實現。在類似 Webpack 的構造系統中,這已經成為普遍採用的可行的方法,用css-loader 來支援模組化。PostCSS 有一個支援同樣功能的 外掛。但是這種方法還是把 CSS 檔案放在元件程式碼之外。

其他解決辦法

“CSS in JS” 是一個在 2014 年末由一個 Facebook 的 React 開發團隊者 Christopher 在 一個著名的演講 提出,同時衍生出一些更易建立元件化樣式的有影響的庫。目前最流行的解決方法是使用 ES6 tagged template literals 來從 CSS 字串中建立元件的 styled-components 庫。

另一個流行的方法是 Aphrodite,使用 JavaScript 物件字面量建立與框架無關的內聯樣式。在 [JavaScript 2017] 調查中,34% 的開發者聲稱他們使用過 CSS-in-JS。

總結: PostCSS 是首選的 CSS 前處理器,但是很多人轉向 CSS-in-JS 的方法

打包工具

Webpack

2017年 Webpack 鞏固其領先於前一代 JavaScript 打包工具的地位:

前端 2017: 舉要刪蕪

NPM 上 Webpack, Gulp, Browserify, Grunt 的下載量

來源: npmtrends.com

Webpack 2 在今年二月釋出,它帶來比如 ES6 模組化(不在需要 Babel 轉換 import 語句了)和 tree shaking(刪除無用的程式碼)這樣的重要特性,V3 不久後也釋出了,帶來一個 “scope hoisting” 的特性,可以把所有的 webpack 模組打包成一個檔案,極大的減少了檔案體積。

在 6 月,webpack 團隊接到 Mozilla 開源組的授權去開發 WebAssembly 的高階支援。這一計劃最終目的是讓 WebAssembly 和 JavaScript 打包工具可以深度整合。

在打包領域還有一些與 Webpack 無關的的創新空間,它在流行的同時,開發者也在抱怨配置使用它的困難和對於大型專案優化所需要的一堆外掛。

Parcel

Parcel 是一個有趣的專案,在 12 月上旬引起關注(只用 10 天收穫 10000 star)。宣稱自己速度極快,同時零配置。它通過利用 CPU 的多核心和高效的檔案快取達到目的。它操作抽象語法樹而不是像 Webpack 的字串。像 Webpack 一樣,Parcel 也打包非 JavaScript 的資原始檔,像圖片和樣式表檔案。

這個模組工具展示了一個 JavaScript 社群通常的模式:不停的在開箱即用(集中)與配置一切(分散)之間切換。

我們從 Angular 到 React/Redux,SASS 到 PostCSS 的轉變中可以看出這一點。Webpack 與在它之前出現的各種打包及任務處理工具一樣,都是使用許多外掛來進行分散配置的解決方案。

事實上,Webpack 和 React 在 2017 因為幾乎一樣的原因受到抱怨,人們期待開箱即用的解決方案,這很重要。

Rollup

在 2016 年釋出 Webpack 2 之前,Rollup 引起了大家廣泛的關注,引入了一個叫做 tree shaking 的流行功能,這是一種移除不用的程式碼的有趣方法。 Webpack 在第二個版本中為 Rollup 的簽名功能提供了支援這個來回應 Rollup 的簽名特性。Rollup 跟 Webpack 相比不同的打包方式,讓總的打包體積更小,同時也不能支援程式碼分割這一重要的特性了。

在 4 月 React 的團隊從 Gulp 切換 到 Rollup, 很多人問為什麼選擇 Rollup 而不是 Webpack。Webpack 迴應稱推薦 Rollup 作為庫的開發工具而 Webpack 作為應用的開發方式這篇文章來解決大家的疑惑。

總結: Webpack 仍是最流行的打包工具,但也許不會永遠是這樣。

TypeScript

在 2017 Flow 相對於 TypeScript 來說丟失了大量的份額:

前端 2017: 舉要刪蕪

Flow 對比 TypeScript NPM 2017 下載量 2017 來源: NPM 趨勢

雖然這一趨勢在持續了幾年,但在 2017 年加快了步伐,TypeScript 現在是 2017 Stack Overflow 開發者調查中第三受喜歡的語言(Flow 並沒有在這裡提及)。

TypeScript 勝利的原因包括:更好的工具(特別是 Visual Studio Code 編輯器),lint 工具(tslint 變的超級流行),更大的社群,更多第三方型別庫,更好的文件,和更簡單的配置。最早 TypeScript 做為 Angular 專案的可選語言而逐漸流行,現在已經鞏固了在整個社群的使用度。根據 Google 趨勢,TypeScript 今年流行度上升了一倍。

TypeScript 採取快速開發的方式,這使得它可以不斷微調型別系統來跟上 JavaScript 語言。它現在支援 ECMAScript 的 iterators, generators, 非同步 generators,以及動態 import 特性。你現在可以根據 TypeScript 的型別介面和 JSDoc 註釋來 檢查 JavaScript 的型別。 如果你使用 Visual Studio Code,TypeScript 現在在編輯器中支援出色的轉換工具,允許重新命名變數和自動匯入包。

總結: TypeScript 贏了 Flow。

狀態管理

Redux 仍然是 React 專案的首選狀態管理解決方案,在 2017 年整個 NPM 下載量增長了 5 倍:

前端 2017: 舉要刪蕪

2017 Redux 在 NPM 的下載量

來源: NPM 趨勢

Mobx 是 Redux 在客戶端狀態管理上有趣的競爭者,不像 Redux, MobX 使用可觀察的狀態物件和一個受 響應式函數語言程式設計 概念啟發的 API。Redux 的不同之處在於被傳統函數語言程式設計影響和純函式的支援, Redux 可以看作通過 action 和 reducer 手動管理狀態的解決方案。Mobx 與之相反,是自動化的狀態管理方案因為觀察者模式在背後做了所有你需要做的。

MobX 對你的資料結構,儲存的資料型別,或者是不是可以序列化成 JSON 做了一些預設。這些因素使初學者非常容易使用 MobX。

不像 Redux, MobX 不是事務型和確定型的,這意味著 Mobx 不會自動獲得 Redux 在除錯和日誌記錄方面的所有優點。。你不能對整個 MobX 的狀態做快照,意味著一些除錯工具像 LogRocket 需要手動監測你的每個可觀察物件。

像美國銀行、IBM 和 Lyft 這些知名公司已經在使用 Mobx 了。同時也有社群中逐步發展的 的外掛,工具和教程。它增長迅速:從年初 50k 的 NPM 下載量到十月份 250k 的下載量。

因為上述的限制,MobX 的團隊將一直努力將 Redux 和 Mobx 在一個叫 mobx-state-tree (或者 MST) 的專案中把它們結合起來。它本質上是一個狀態容器,在後臺使用 MobX 來提供一種方式來處理不可變資料,就像使用可變資料一樣簡單。根本上來說,你的狀態還是可變的,但是你通過 snapshot 同不可變的狀態複本一起工作。

已經由很多的開發者工具可以幫助你除錯檢查你的狀態樹——Wiretapmobx-devtools 是很好的選擇。因為他們大致採取相同的方式工作,你甚至可以對 mobx-state-tree 使用 Redux 開發工具。

總結: Redux 仍是王者,但是請看一下 MobX 和 mobx-state-tree

GraphQL

GraphQL 是一個可以實時查詢介面語言,因為資料來源的原因提供更清晰簡潔的語法。不像 REST, GraphQL 提供型別語法,允許 JavaScript 客戶端只查詢他們需要的資料,它可能是近些年來介面開發中最大的革新。

雖然 GraphQL 語言標準從 2016 年十月 就沒有改變,但人們對它的興趣與日俱增。在過去的幾年裡,Google 趨勢發現對於 GraphQL 的搜尋量 [4 倍的增長],對 JavaScript GraphQL 客戶端 NPM 下載量有 [13 倍的增長]。

當前有很多客戶端和服務端實現可以選擇,Apollo 是流行的選擇之一,它新增全面的快取控制和與 React 和 Vue 流行庫的整合。MEAN 是也是一個使用 GraphQL 作為 API 層流行的全棧開發框架。

在過去的幾年 GraphQL 背後的社群 也是極速發展。它創造了 20 多種語言的服務端實現方式,以及數以千計的教程和啟動專案。有一個很好的 awesome list

React-starter-kit——最流行的使用 GraphQL 的 React 生態環境中的專案。

總結: GraphQL 正在獲得增長動力

其他值得關注的

NapaJS·

微軟新的基於 V8 之上的多執行緒 JavaScript 執行時庫。NapaJS 提供了一種在 Node 環境執行多執行緒的方式,在現有 Node 架構下更好的支援 CPU 密集型任務的執行。它提供了一種 Node 多工模型的備選方案,用一個模組來實現。現在可以在 NPM 上像其他庫那樣下載了。

Napa使用 node-webworker-threads 庫來利用 Node 中的執行緒與底層語言結合,通過使用新增從工作執行緒內部使用 Node 模組系統的能力來無縫的融合 Node 生態鏈。它還提供了不同 workers 間通訊的全面的介面,與新發布的共享記憶體標準非常類似。

這個專案是微軟為 Node 生態系統應用高效能架構所做的努力。它目前正在被 Bing 搜尋引擎作為後端棧的一部分所使用。

有了微軟這樣的大公司的支援,你可以對 Node 的長期穩定放心了。看 Node 社群跟隨多執行緒可以走多遠將會非常有趣。

Prettier

近些年來構建工具的重要性日益增長。隨著 Prettier 的首次亮相,程式碼格式成為前端構建過程中常見的一環。它自稱是一個嚴格程式碼的格式化工具,旨在通過解析和重寫來增強始終如一的程式碼風格。

當像 lint 工具比如 ESLint 長時間成為 自動化檢測規則,Prettier 是最富特色的解決方案。不像 ESLint, Prettier 還支援 supports JSON, CSS, SASS, 甚至 GraphQL 和 Markdown。它還提供了與 ESLint常見的編輯器 深度結合的能力。如果我們對分號意見一致,我們會很棒。


外掛: LogRocket, web 應用的除錯工具

前端 2017: 舉要刪蕪

LogRocket 是一個前端的記錄工具,允許你回放發生在自己瀏覽器上的問題。而不是猜測錯誤發生的原因,或者問使用者要截圖和日誌檔案, LogRocket 讓你重現任務可以迅速的瞭解哪裡出了問題。它和所有的應用都結合的很好,無論什麼框架,同時有記錄額外的 Redux, Vuex, 和 @ngrx/store 上下文工具。

在記錄 Redux 事件和狀態之外,LogRocket 記錄控制皮膚,JavaScript 錯誤,堆疊,網路請求/答覆的頭和主體,瀏覽器元資訊和自定義日誌。它還操作 DOM 來記錄頁面中的 HTML 和 CSS,即使對最複雜的單頁應用也可以再現非常精確的錄製畫面。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章