前端開發(fā)從未像現(xiàn)在這樣復(fù)雜和令人興奮?;旧厦扛粢惶炀蜁?huì)出現(xiàn)新的工具、庫、框架和插件。要學(xué)習(xí)的東西越來越多。
好在我們的 Grab web 團(tuán)隊(duì)(譯者注:Grab 是東南亞的一家打車平臺(tái))一直遵循著最新、最佳的方法,并將現(xiàn)代 JavaScript 生態(tài)系統(tǒng)納入了我們的 web 應(yīng)用。
這樣也導(dǎo)致,我們的新員工或后端工程師,他們可能會(huì)不熟悉這些現(xiàn)代 JavaScript 生態(tài)系統(tǒng),為了在 web app 中完成某項(xiàng)功能或修復(fù)某些 bug , 他們不得不去學(xué)習(xí),最終被不斷涌現(xiàn)的新事物所“淹沒”。
為了指導(dǎo)他們快速接受前沿技術(shù)的演進(jìn),輕松熟悉生態(tài)系統(tǒng),并盡可能快地輸出代碼。我們發(fā)布了這樣一本學(xué)習(xí)指南,介紹我們做了什么和為什么要這樣做。
本指南的靈感來源于“治療 JavaScript 疲勞的學(xué)習(xí)計(jì)劃”(A Study Plan to Cure JavaScript Fatigue),并在基于目前最適合 Grab 發(fā)展的基礎(chǔ)上,對(duì)下面這些適用于前端開發(fā)的庫和框架進(jìn)行推薦。
文中還會(huì)解釋選擇某某庫和某某框架的原因,并提供學(xué)習(xí)資源鏈接,以便讀者能夠自由選擇。以及在某些情況下可能效果更好的替代選擇,以供參考和進(jìn)一步自我探索。
如果您非常熟悉前端開發(fā),并且一直有跟進(jìn)最新的技術(shù),本指南可能對(duì)您用處不大。它偏向針對(duì)前端新手。如果您的公司正在探索現(xiàn)代 JavaScript 堆棧,您會(huì)發(fā)現(xiàn)本指南可能對(duì)您的公司也有用!
請(qǐng)注意,本指南也有在 GitHub 上發(fā)布,我們將定期更新。
對(duì)核心編程概念有一定理解。
可使用基本的命令行操作并熟悉源碼版本控制系統(tǒng)(如 Git )。
有 Web 開發(fā)經(jīng)驗(yàn)。 使用 Ruby on Rails、Django、Express 等框架構(gòu)建過 Web 應(yīng)用。
了解 Web 工作原理。 熟悉 Web 協(xié)議和約定,如 HTTP 和 RESTful API 。
單頁應(yīng)用(Single-page Apps)
現(xiàn)代 JavaScript( New-age JavaScript)
用戶界面(User Interface)
狀態(tài)管理(State Management)
規(guī)則編碼(Coding with Style)
測(cè)試(Testing)
JavaScript 檢測(cè)(Linting JavaScript)
CSS 檢測(cè)(Linting CSS)
類型(Types)
系統(tǒng)構(gòu)建(Build System)
包管理(Package Management)
持續(xù)集成(Continuous Integration)
托管(Hosting)
部署(Deployment)
如果您已有相關(guān)經(jīng)驗(yàn),可選擇跳過部分內(nèi)容。
Web 開發(fā)人員現(xiàn)在將其構(gòu)建的產(chǎn)品稱為 Web 應(yīng)用,而不是網(wǎng)站。雖然這兩個(gè)術(shù)語之間沒有嚴(yán)格的區(qū)別,但 Web 應(yīng)用往往是高度互動(dòng)和動(dòng)態(tài)的,允許用戶執(zhí)行操作并接收響應(yīng)。
傳統(tǒng)上,瀏覽器從服務(wù)器接收 HTML 并呈現(xiàn)。當(dāng)用戶定位到另一個(gè) URL 時(shí),需要進(jìn)行全頁刷新,并且服務(wù)器為新頁面發(fā)送新的新 HTML 。這被稱為服務(wù)器端渲染。
然而,在現(xiàn)代的 SPAs 中,已被客戶端渲染取代。瀏覽器從服務(wù)器加載初始頁面,以及整個(gè)應(yīng)用所需的腳本(框架、庫、應(yīng)用代碼)和樣式表。當(dāng)用戶定位到其他頁面時(shí),不會(huì)觸發(fā)頁面刷新。通過 HTML5 History API 更新頁面的 URL 。瀏覽器通過 AJAX 請(qǐng)求檢索新頁面(通常以 JSON 格式)所需的新數(shù)據(jù)。然后, SPA 通過 JavaScript 動(dòng)態(tài)更新已經(jīng)在初始頁面加載中已經(jīng)下載好的新頁面。這種模式類似于原生手機(jī)應(yīng)用的工作原理。
優(yōu)勢(shì):
應(yīng)用感更強(qiáng),用戶不會(huì)看到由于全頁刷新導(dǎo)致頁面之間的閃爍。
對(duì)服務(wù)器進(jìn)行的 HTTP 請(qǐng)求較少,因?yàn)椴槐貫槊總€(gè)頁面加載重復(fù)下載相同的資料。
明確分離客戶端與服務(wù)器之間的關(guān)系;可以輕松地為不同的平臺(tái)構(gòu)建新的客戶端而無需修改服務(wù)器代碼。只要 API contract 不被破壞,還可以獨(dú)立地修改客戶機(jī)和服務(wù)器上的技術(shù)棧。
劣勢(shì):
需加載多個(gè)頁面所需的框架、應(yīng)用代碼和初始頁面加載需要的成本。
在服務(wù)器上會(huì)有一個(gè)額外的步驟,即將其配置為將所有請(qǐng)求被路由到單個(gè)入口點(diǎn),并允許客戶端路由從那里接管。
SPAs 依賴于 JavaScript 來呈現(xiàn)內(nèi)容,但并不是所有的搜索引擎在爬行期間都會(huì)執(zhí)行 JavaScript ,而且可能會(huì)在您的頁面上看到空的內(nèi)容。這在無意中會(huì)影響應(yīng)用的 SEO 。
雖然傳統(tǒng)的服務(wù)器端呈現(xiàn)的應(yīng)用仍然是可行的選擇,但是由于客戶端和服務(wù)器代碼可以獨(dú)立開發(fā)和發(fā)布,因此清晰明了的客戶端和服務(wù)器分離可以更好地?cái)U(kuò)展到較大的工程團(tuán)隊(duì)。
由于 Web 開發(fā)人員構(gòu)建的是應(yīng)用而不是頁面,因此客戶端 JavaScript 架構(gòu)變得越來越重要。在服務(wù)器端呈現(xiàn)的頁面中,通常使用 jQuery 的代碼片段將用戶交互性添加到每個(gè)頁面。但是,當(dāng)構(gòu)建大型應(yīng)用程序時(shí),光有 jQuery 還不夠。畢竟,jQuery 主要是一個(gè)用于 DOM 操作的庫,它不是框架;無法為應(yīng)用定義清晰的結(jié)構(gòu)和組織。
JavaScript 框架往往被構(gòu)建以便在 DOM 上提供更高級(jí)別的抽象,從而允許將內(nèi)存中的狀態(tài)保留在 DOM 之外。使用框架還帶來了一些適合應(yīng)用的重用建議的推薦和最佳做法的好處。團(tuán)隊(duì)中不熟悉代碼基礎(chǔ)但具有框架經(jīng)驗(yàn)的新工程師將會(huì)更容易理解代碼,因?yàn)樗且砸环N他們熟悉的結(jié)構(gòu)組織起來的。流行框架通常會(huì)有很多教程和指南,利用同事和社區(qū)的知識(shí)和經(jīng)驗(yàn),可幫助新工程師快速上手。
在深入了解構(gòu)建 JavaScript Web 應(yīng)用的各個(gè)方面之前,熟悉 Web-JavaScript 或 ECMAScript 的語言非常重要。 JavaScript 是一種非常通用的語言,可以用它來構(gòu)建 Web 服務(wù)器,也可以構(gòu)建原生移動(dòng)應(yīng)用和桌面應(yīng)用。
在 2015 年之前,最后一次重大更新是 2011 年發(fā)布的 ECMAScript 5.1 。然而,近年來,JavaScript 在短時(shí)間內(nèi)突然出現(xiàn)大幅度改善。2015 年,ECMAScript 2015(以前稱為 ECMAScript 6 )發(fā)布,引入大量的語法結(jié)構(gòu),使得編寫代碼不再那么笨重。如果你對(duì)這段歷史感興趣,Auth0 有寫一篇關(guān)于 history of JavaScript 的文章。直到現(xiàn)在,也并非所有的瀏覽器都完全實(shí)現(xiàn)了 ES2015 規(guī)范。類似 Babel 這類的工具使開發(fā)人員能夠在其應(yīng)用中編寫 ES2015 ,隨后 Babel 將其轉(zhuǎn)換為 ES5 以兼容瀏覽器。
熟悉 ES5 和 ES2015 都至關(guān)重要。 ES2015 現(xiàn)在依然很新,很多開源代碼和 Node.js 應(yīng)用仍然是使用 ES5 編寫。如果您是在瀏覽器控制臺(tái)中進(jìn)行調(diào)試,可能無法使用 ES2015 語法。另一方面,稍后將介紹的許多現(xiàn)代庫的文檔和示例代碼都是用 ES2015 寫的。在 Grab ,我們使用 babel-preset-env 來享受 JavaScript 的不斷改進(jìn)的語法來提升生產(chǎn)力。 babel-preset-env 能智能地確定哪些 Babel 插件是必需的(哪些新的語言特性不被支持,需被翻譯),以讓瀏覽器更好地對(duì) ES 的各種語言特性提供原生支持。如果您喜歡使用已經(jīng)穩(wěn)定的語言特性,那么 babel-preset-stage-3(一個(gè)完全可以在瀏覽器中實(shí)現(xiàn)的規(guī)范)可能會(huì)更適合您。
花一兩天的實(shí)際去修正 ES5 并摸索 ES2015 。 ES2015 中使用最多的特性包括“箭頭函數(shù)”、“Classes”(語法糖)、“字符串模板”、“解構(gòu)”,“Default/Rest/Spread 操作符”以及“導(dǎo)入和導(dǎo)出模塊”。
預(yù)估時(shí)間: 3–4 天. 可在學(xué)習(xí)其他庫并嘗試構(gòu)建應(yīng)用時(shí)學(xué)習(xí)/查找語法。
你不知道的 JS (高階內(nèi)容,初學(xué)者可選)
如果要說近年來給前端生態(tài)帶來風(fēng)暴式影響的 JavaScript 項(xiàng)目,當(dāng)屬 React 。 React 是一個(gè)由 Facebook 開發(fā)的庫。 在 React 中,開發(fā)人員為其 Web 界面編寫組件并將其組合在一起。
React 帶來了許多激進(jìn)的想法,并鼓勵(lì)開發(fā)人員重新思考最佳實(shí)踐。 多年來,Web 開發(fā)人員被灌輸分開編寫 HTML、JavaScript 和 CSS 的理念 ,但 React 恰恰相反,鼓勵(lì)在 JavaScript 中編寫 CSS 。這聽起來很瘋狂,但在嘗試之后,會(huì)發(fā)現(xiàn)其實(shí)并不奇怪。作為影響前端發(fā)展正轉(zhuǎn)向基于組件的發(fā)展模式的關(guān)鍵,React 的特點(diǎn)如下:
聲明式?—?描述想在 View 中看到的,而不是如何實(shí)現(xiàn)它。在 jQuery 時(shí)代,開發(fā)人員必須提出一系列的步驟來操縱 DOM ,從一個(gè)應(yīng)用狀態(tài)到下一個(gè)應(yīng)用狀態(tài)。在 React 中,只需更改組件中的狀態(tài),View 將根據(jù)狀態(tài)進(jìn)行更新。也可通過查看 render()方法中的標(biāo)記來確定組件的外觀。
函數(shù)式—?View 是基于 state 和 props 的純函數(shù)。多數(shù)情況下,React 組件由 props(外部參數(shù))和 state(內(nèi)部數(shù)據(jù))定義。相同的 props 和 state ,會(huì)構(gòu)成相同的視圖。純函數(shù)易于測(cè)試,功能組件也大多相同。由于組件的界面定義良好,可通過提供不同的 props 和 state 來對(duì)組件進(jìn)行測(cè)試并比較,從而輕松完成測(cè)試。
可重用性?—?以基于組件的方式編寫 View 就是鼓勵(lì)重用性。我們發(fā)現(xiàn)定義一個(gè)組件的 propTypes 能讓 React 代碼自我記錄,以讓用戶可以清楚地知道使用該組件需要什么。此外,您的視圖和邏輯在組件中是獨(dú)立的,不會(huì)受到影響也不影響其他組件。只需向組件提供相同的 props ,就可輕松地在大規(guī)模重構(gòu)過程中 shift 組件。
高性能—?您可能已經(jīng)聽說 React 使用的是 virtual DOM(請(qǐng)勿與 shadow DOM 混淆),并且在狀態(tài)發(fā)生變化時(shí)重新呈現(xiàn)所有內(nèi)容,那你知道為什么需要 virtual DOM 嗎?雖然現(xiàn)代 JavaScript 引擎很快,但從 DOM 讀取和寫入速度很慢。 React 在內(nèi)存中保持 DOM 的輕量級(jí)虛擬渲染。重新渲染一切本身就是一句有誤導(dǎo)性的術(shù)語。在 React 中它實(shí)際上是指重新渲染 DOM 的內(nèi)存中呈現(xiàn),而不是實(shí)際的 DOM 本身。當(dāng)組件的底層數(shù)據(jù)發(fā)生變化時(shí),將創(chuàng)建一個(gè)新的虛擬呈現(xiàn),并與先前的進(jìn)行比較。然后將差異(所需的最小變化集)修補(bǔ)到真正的 browser DOM 。
易于學(xué)習(xí)?—?學(xué)習(xí) React 非常簡(jiǎn)單。與 this 相比,React API surface 相對(duì)較小; 只有很少的幾個(gè) API 可以學(xué)習(xí),并且不會(huì)經(jīng)常變化。React 社區(qū)是最大的社區(qū)之一,同時(shí)也是一個(gè)充滿活力的工具生態(tài)系統(tǒng),有開放的 UI 組件,以及一大批在線資源可供學(xué)習(xí)。
優(yōu)秀的開發(fā)體驗(yàn)?—有許多工具可以改善 React 的開發(fā)體驗(yàn)。React Developer Tools 是一個(gè)瀏覽器擴(kuò)展,可檢查組件,查看和操作其 props 和 state 。使用 webpack 進(jìn)行熱更新可讓您在瀏覽器中查看代碼的更改,而無需刷新瀏覽器。Facebook 還提供了一個(gè) codemod 腳本,以幫助您在有庫更新時(shí)將代碼遷移到新的 API ,使升級(jí)過程相對(duì)無痛。
經(jīng)過多年發(fā)展,其實(shí)也出現(xiàn)了比 React 更出色的新視圖庫。React 可能不是最快的庫,但在生態(tài)系統(tǒng)、整體使用體驗(yàn)和效率方面,它仍然是最強(qiáng)大的庫之一。 Facebook 正在通過重寫基礎(chǔ)協(xié)調(diào)算法,力圖使 React 更快。 React 讓我們知道如何編寫更好的代碼和更好維護(hù)的 Web 應(yīng)用,并讓我們成長(zhǎng)為更好的工程師。
我們建議您在 React 主頁上瀏覽一個(gè)關(guān)于建立 tic-tac-toe 游戲的教程,以先了解 React 是什么及能做什么。想要進(jìn)一步深入學(xué)習(xí),可查看 React Router 的創(chuàng)始人、React 社區(qū)專家發(fā)布的高級(jí)免費(fèi)課程“ React Fundamentals ”,里面還涵蓋了 React 官方文檔未寫入的更高級(jí)的概念。Facebook 的 Create React App 是以最小配置支持 React 項(xiàng)目的工具,也強(qiáng)烈建議在您新的 React 項(xiàng)目中啟用。
React 是一個(gè)庫,而不是一個(gè)框架,并不處理視圖層以下的層次 - 應(yīng)用狀態(tài)。后面會(huì)說到。
估計(jì)時(shí)間: 3–4 天. 嘗試構(gòu)建類似待辦事項(xiàng)列表這種簡(jiǎn)單的項(xiàng)目,去 Hacker News 克隆一些純 React 經(jīng)驗(yàn)。 你會(huì)慢慢收獲和成長(zhǎng),期間可能會(huì)面臨一些也許無法用 React 解決的問題,下面的主題會(huì)講到…
隨著您的應(yīng)用越來越大,可能會(huì)發(fā)現(xiàn)應(yīng)用結(jié)構(gòu)變得有點(diǎn)混亂。應(yīng)用中的組件可能要共享和顯示常見數(shù)據(jù),但 React 中卻沒有很優(yōu)雅的方式來處理這些情況。 畢竟,React 只是視圖層,它并沒有明確規(guī)范如何在傳統(tǒng)的 MVC 范例中構(gòu)建應(yīng)用的其他層,如 model 和 controller 。為了解決這個(gè)問題,F(xiàn)acebook 發(fā)明了 Flux ,一款應(yīng)用架構(gòu),通過使用單向數(shù)據(jù)流來補(bǔ)充 React 的可組合視圖組件。點(diǎn)此可閱讀關(guān)于 Flux 如何運(yùn)作的介紹。 總而言之,F(xiàn)lux 范式(Flux pattern)具有以下特點(diǎn):
單向數(shù)據(jù)流?—?使應(yīng)用更可預(yù)測(cè),以輕松跟蹤更新。
關(guān)注點(diǎn)分離?—?Flux 架構(gòu)中的各個(gè)部分都有明確的職責(zé),并且高度分離。
適用于聲明式編程?—? store 可將更新發(fā)送到 view ,而無需指定如何在狀態(tài)之間轉(zhuǎn)換視圖。
由于 Flux 本身不是一個(gè)框架,開發(fā)人員嘗試提出各種 Flux 范式的實(shí)現(xiàn)。最后,出現(xiàn)了一個(gè)最亮眼的贏家,那就是 Redux 。 Redux 將來自 Flux、Command pattern 和 Elm 架構(gòu)的想法融合在一起,已然成為目前 React 開發(fā)者最常使用的狀態(tài)管理庫。其核心概念是:
應(yīng)用狀態(tài)(state)是由單個(gè)普通的 JavaScript 對(duì)象(POJO)描述。
調(diào)度一個(gè) action (也是 POJO) 來修改狀態(tài)。
Reducer 是一種純函數(shù),它利用當(dāng)前狀態(tài)和動(dòng)作來產(chǎn)生新的狀態(tài)。
這些概念聽起來很簡(jiǎn)單,但功能強(qiáng)大,因?yàn)樗鼈兪箲?yīng)用能夠:
在服務(wù)端呈現(xiàn)狀態(tài),在客戶端啟動(dòng)
跟蹤、記錄和回溯整個(gè)應(yīng)用的更改
輕松執(zhí)行撤消和重做
Redux 創(chuàng)始人 Dan Abramov 非常仔細(xì)地為 Redux 撰寫了詳細(xì)的文檔,同時(shí)為初階和高階的 Redux 使用者創(chuàng)建了全面的視頻教程。這些是學(xué)習(xí) Redux 非常有用的資源。
View 和 State 相結(jié)合
雖然 Redux 并不是一定要和 React 一起使用,但我們強(qiáng)烈推薦。 React 和 Redux 有很多相似的理念和特點(diǎn):
函數(shù)式組合范式?—?React 由 views (純函數(shù)) 構(gòu)成,而 Redux 由 pure reducers (也是純函數(shù)) 構(gòu)成。在指定輸入組合時(shí),輸出都是可預(yù)見的。
易于 Reason About?—?這個(gè)詞您可能聽過很多次,但實(shí)際上是什么意思?我們將其解釋為對(duì)代碼的控制和理解 - 代碼以我們期望的方式行事,當(dāng)有問題時(shí),可以輕松發(fā)現(xiàn)問題。據(jù)已有的經(jīng)驗(yàn),React 和 Redux 會(huì)使調(diào)試更簡(jiǎn)單。由于數(shù)據(jù)流是單向的,因此跟蹤數(shù)據(jù)流(服務(wù)器響應(yīng)、用戶輸入事件)更容易,并且可以直接定位問題發(fā)生在哪一層。
結(jié)構(gòu)分層?—?應(yīng)用/ Flux 架構(gòu)中的每一層都是一個(gè)純函數(shù),具有明確的職責(zé)。為純函數(shù)編寫測(cè)試相對(duì)容易。
開發(fā)體驗(yàn)?—?在開發(fā)過程中,諸如 Redux DevTools 之類的開發(fā)工具,可幫助調(diào)試和檢查應(yīng)用。
此外,您的應(yīng)用可能需要處理異步調(diào)用,例如進(jìn)行遠(yuǎn)程 API 請(qǐng)求。redux-thunk 和 redux-saga 就是用來解決這些問題的。理解他們可能需要一些時(shí)間,因?yàn)樾枰斫夂瘮?shù)編程和生成器。建議只在有需要的時(shí)候處理它。
react-redux 是一個(gè)官方的封裝庫,非常簡(jiǎn)單易學(xué)。
預(yù)估時(shí)間: 4 days. 下面的 Egghead 課程可能有點(diǎn)耗時(shí),但值得花時(shí)間。 學(xué)完 Redux 后,您可以嘗試將其納入已構(gòu)建好的 React 項(xiàng)目中。 Redux 是否解決了您在純 React 中遇到的一些狀態(tài)管理問題?
CSS(層疊樣式表)是描述 HTML 元素布局的規(guī)則。寫好 CSS 很難。編寫可維護(hù)和可擴(kuò)展的 CSS ,通常需要多年的經(jīng)驗(yàn)和積累。具有全局命名空間的 CSS 基本上是為 Web 文檔而設(shè)計(jì)的,并不是真正用于支持組件架構(gòu)的 Web 應(yīng)用。因此,經(jīng)驗(yàn)豐富的前端開發(fā)人員總結(jié)了設(shè)計(jì)方法學(xué),指導(dǎo)人們?nèi)绾螢閺?fù)雜項(xiàng)目編寫合理的 CSS ,例如使用 SMACSS、BEM、SUIT CSS 等。
CSS 方法學(xué)所帶來的樣式封裝是由公約和綱要強(qiáng)制執(zhí)行的,打破了開發(fā)者不遵守約定的時(shí)代。
正如您可能已經(jīng)意識(shí)到的那樣,前端生態(tài)系統(tǒng)的工具十分豐富,甚至趨于飽和,因此當(dāng)發(fā)現(xiàn)已經(jīng)有一些工具來分塊解決大規(guī)模編寫 CSS 問題時(shí),應(yīng)該也不會(huì)感到奇怪。 “At scale” 意味著有大量開發(fā)人員正在開展同一個(gè)大型項(xiàng)目,并觸及相同的樣式表。目前在 JS 中編寫 CSS 還沒有社區(qū)認(rèn)可的最佳方式 ,我們希望有一天,能像 Redux 一樣,在所有的 Flux 實(shí)現(xiàn)中出現(xiàn)贏家。目前,我們?cè)谑褂玫氖?CSS Modules 。 CSS modules 是對(duì)現(xiàn)有 CSS 的改進(jìn),旨在解決 CSS 中全局命名空間的問題;它允許編寫默認(rèn)情況下的局部樣式并封裝到組件中。使用 CSS modules ,大型團(tuán)隊(duì)可以編寫模塊化和可重用的 CSS ,而不用擔(dān)心沖突或覆蓋應(yīng)用的其他部分。不過,CSS modules 最終仍然需要編譯成瀏覽器可識(shí)別的正常全局命名空間的 CSS ,因此學(xué)習(xí)和理解原始 CSS 仍然很重要。
如果您是一個(gè) CSS 初學(xué)者,Codecademy 的 HTML & CSS 課程將是不錯(cuò)的開始。然后,攻讀 Sass preprocessor ,這是 CSS 語言的擴(kuò)展,在基礎(chǔ)上增加了語法改進(jìn),并鼓勵(lì)樣式可重用性。再去研究上面提到的 CSS 方法學(xué),CSS modules 放到最后去學(xué)。
預(yù)估時(shí)間: 3–4 days. 嘗試使用 SMACSS / BEM 理論 和/或 CSS modules 來設(shè)計(jì)應(yīng)用。
聯(lián)系客服