天天看點

前端(JS)開發者的新起點:2015

大約三年前,我寫了一篇《前端開發者的基本技能》,嗯,那大概是我最出名的一篇文章。三年後,仍然有人在 Twitter 上@我詢問如何開始學習前端知識。

在某種程度上,我曾經寫下的文字曆經了時間的考驗:令我感到震驚的是,2012 年我寫的那篇文章并沒給我帶來難堪的問題。盡管如此,3 年之久,很多事情都變得與衆不同。2012 年我鼓勵人們學習浏覽器開發工具,緊跟子產品化開發大潮;那時候人們還不太接受 CSS 預處理和用戶端模闆這類新事物,它們仍然值得一提;相比于 JSLint 锱铢必較的精确(甚至讓人感到厭煩),JSHint 非常受歡迎,它使我們徹底解放。

現在時間來到了2015年,我想寫一個更新版的前端指南,但是當我坐下動筆開始寫的時候,我突然意識到兩件事情:

  1. 相對來說,稱這篇文章為基本技能是不公平的,如果你回憶起以前的文章,你會發現這篇文章仿佛偏離了基礎。人們可能會争辯說,我們應該考慮那些能讓我們找到工作的技能來作為基本技能。但是事實上,市場上有很多前端的工作可以選擇,為了得到一份工作你并不需要太多的基礎。于我而言,我并不想簡單找一份工作了事,我希望參與到一份絕妙的工作中去;我不想簡單工作就度過一整天,我希望能夠與有才能的人一起工作;我不想從事那些已經被大衆所熟知的,坐在這裡稍作思考,預計差不多明天之前就可以完成的那種工作,我希望從事那些,因為我知道如何去工作,我能在明天之前鑽研出一個成果,是以我明天可以順利完成任務的工作,對,就是有挑戰的那種!
  2. 我的世界正在變得徹底以 JavaScript 為中心:除了一些必要的性能優化,我的日常工作接觸到的 CSS 知識越來越少。我知道有許多非常聰明的前端開發者,他們的 JS 和 CSS 技能都很厲害,但是根據我的觀察,專注研究 JavaScript 和專注研究 CSS 的人們正在逐漸分離。我大概可以寫另外一篇博文來闡述這個話題,但在這裡我隻想說:我沒有做過多有關 CSS 的準備,是以不要對這一點抱有過多的期許。

簡而言之:當你以你的前端世界的視角來閱讀這篇文章,不一定能找到你需要的内容。但請謹記,我們都是很棒的開發者!

JavaScript

記憶回到 2009 年,如果你在文章裡讀到類似 “HTML5 将會在 2014 年定稿使用” 的預言,是否看起來那一天還很遙遠?如果當時你這樣想,你将要準備好迎接緩慢更新但是穩步向前的 ES6(現在被稱為 ES2015,這個名稱已經随處可見),也就是下一個版本的 JavaScript。準備與 ES6 – 啊不對,ES2015 – 接軌吧,毫無疑問,這是接下來在 JavaScript 領域中最重要的事情。ES6 classes、真正的隐私、更好的函數和參數、可引入(

import

)的子產品以及許多其它特性,一定會徹底改變遊戲規則。那些能力十足并且十分高産的新文法無疑将會徹底從 JS 社群中孕育出來。為此,你需要閱讀:

  • 了解ES6,一本 Nicholas Zakas 正在撰寫的書籍,目前已開源(譯注:新坑已開,歡迎一起填坑)。
  • BabelJS,一個允許你編寫 ES6 代碼并将其編譯為可以在市面浏覽器中運作的 ES5 的工具。他們還有一個非常棒的 學習章節(譯注:中文版請參考 這裡)。
  • ES6 Rocks,有很多探索 ES6 特性、語義和坑的文章。 你是否需要成為一位 ES6/ES2015 專家?或許現在不需要,但你至少應該了解足夠多或者更多有關 ES6 的知識才能不落後于你的同行。你在開發下一款新項目的時候,嘗試一下 ES6 吧,未來近在眼前,隻待你去撥開它的面紗。

新的語言特性先暫且不談,你應該能夠流利地說出 JavaScript 的異步模式,并且使用回調和 promise 來管理它。關于在浏覽器中加載應用并在每個應用之間通信的政策,你應該擁有足夠完備的見解。你也許應該掌握一個你非常喜歡的應用開發架構,同時也應該對其它的架構是如何運作的有一個概覽,你需要稍作權衡選擇你喜歡的那一個。

子產品和建構工具

毫無疑問,子產品應當是用戶端 web 應用的建構元素。回到 2012 年,關于使用什麼類型的子產品來建構浏覽器應用的讨論此起彼伏,不過基本圍繞着 AMD 和 CommonJS 展開。還有一個略顯粗俗的 UMD 包裝器嘗試融合二者來友善大家重用代碼 – 他們認為,既然長得差不多,不如多寫點兒代碼來同時支援二者。

我認為這場争論沒有一個統一的結論,但是我感覺這是自 2012 年我寫文章之後,這個領域中最大的轉變,當然這也可能隻是我個人的心路曆程。我沒有徹底搞定 AMD,但是我被它的實用性征服了,你可以使用 CommonJS 開發并部署 web 應用,使用 

npm

 引入子產品。

RequireJS 為子產品通信做了很大的貢獻,出于對它的厚愛,我現在有點兒迷戀 webpack 了。webpack 的功能 – 例如容易了解的建構參數(譯者注:build flag,指令行中形如 -p 的參數) – 相比于 RequireJS 來說更容易了解。通過它的内建開發伺服器實作的熱交換建構打造了一個快速且令人愉悅的開發傳奇。它并不強制你使用 AMD 或者 CommonJS,因為它同時支援兩者。還有非常多的加載器,使得完成許多相同工作對它來說簡直是小意思。你也可以去了解一下 Browserify ,但在我看來,一定要在熟悉了 Webpack 之後再去搞它,我信任的聰明人兒告訴我,systemjs 在這個領域也是一個的認真的競争者,但是我還沒用它呢,它的文檔讓我很想拜讀。 它的包管理器 jspm 很迷人,允許你從包括 npm 在内的不同的源拉取所需的子產品,但是我有點兒擔心這倆貨結合起來會有些問題。我不得不重複,我從沒想過我會與 AMD 分開,但是看起來我不得不放棄它了,我們終将會看到這事情的發生。

我仍然渴望有一天我可以停止喋喋不休地争論有關子產品和建構工具的話題,那時候全世界隻有一個子產品系統,這樣就可以在所有項目裡共享使用代碼,同時還能免去使用 UMD 的開銷。理想情況下,那一天将會因為 ES6 子產品而變為現實 - 在這一天到來前你可以使用轉譯器(Transpiler)來填補空缺-但我發現很有可能我們會持續不斷地找一些方法讓它變得愈發複雜。

與此同時,前端開發者需要了解至少一對建構工具和相關的子產品系統,這需要在實踐中不斷積累經驗。不管怎樣,就目前 JavaScript 的發展情況來說,你仍然需要選擇一個子產品系統,它将支撐你的每一個項目。

測試

一些新的測試架構,例如 Karma 和 Intern,已經讓用戶端代碼的測試變的輕而易舉。我發現 Intern 基于 promise 來進行異步測試的方法特别(作者拼錯了particulary)爽,我不得不承認,大多數時候我依然用 Mocha 來寫測試 – 有時我還真就是屈于習慣的生物啊。

測試過程中的主要阻礙是前端開發者傾向于寫的代碼,關于這個問題,我在 2012 年末公開談論了有關 編寫可測試的 JavaScript 的話題,幾個月後随即寫了一篇有關這個話題的 文章。

測試過程中第二個大的阻礙是工具化,Web 驅動仍然是你需要處理的巨大傷痛。一個複雜UI在所有支援平台上的持續自動化測試依然不可行,即使可行開銷也非常巨大,以緻于那看起來根本不可能實作-更别提移動端了。很大程度上我們仍然局限于在浏覽器、裝置、作業系統結合的支援平台的很小的一個子集上做一些輕量級自動化功能測試,并且越來越難以依賴可以快速、便宜地運作的底層測試。有時候想想這個問題就覺得自己弱爆了。

如果你對改進未經檢驗(不可測試)的代碼問題感興趣,有一本書非常值得一讀:Working Effectively with Legacy Code,作者 Michael Feathers 将 “遺留代碼” 定義為任何沒有測試的代碼,在測試的話題上,唯一的底線是接受這一說法的真實性,即使其它限制會阻止你解決它。

過程自動化

你很有可能認為 Grunt 是任務自動化工具的不二選擇,Gulp 和 Broccoli 提供了一個不同的方法來進行自動建構。我沒用過 Broccoli,并且我隻淺嘗了一下 Gulp,即使 Grunt 有一定的局限性,但我絕對要感謝它依靠其它服務幫助我把複雜任務自動化 – 尤其每天要運作上千次任務的時候。

Yeoman 在我 2012 年寫文章之後的 45 天就釋出了。我承認它剛一出來時我并沒有用它,但最近我 a) 用不熟悉的技術從紙上草稿開始一個項目 b) 嘗試找出如何标準化我們在 Bazaarvoice 平台上開發第三方 JS 應用的方法,Yeoman 的确在這些案例中閃閃發光。在指令行中輸入一個簡單的 

yo react-webpack

 就可以為你建立一整個新項目,項目裡的你想要的應有盡有 – 測試、開發伺服器、一個 hello world 應用,以及更多。如果 React 和 Webpack 不是你的菜,可能一個生成器就可以滿足你的需求,同樣,你也可以很輕松地打造自己的生成器。

考慮到 Yeoman 是一個你通常隻在項目開始的時候使用的工具。并且考慮到你不總會開始新的項目,它隻是一個值得了解的工具。當然了,如果你正在跨越項目嘗試标準化實踐,那麼它或許還有那麼一些價值的。

Broccoli 作為 ember-cli 的核心被委以重任,我信任的人們說這一對兒将來會有大作為,還會改一個新的名字,在未來會逐漸替代 Grunt/Yeoman 組合。使用 Grunt 和 Yeoman 組合進行開發的确會漸漸淡出人們的視野,是以我們一起看看未來能帶來什麼有趣的東西。

代碼品質

如果你像我一樣,當你隻要看到代碼違反了項目良好的文檔風格指南時就情不自禁開始抽搐,那麼像 JSCS 和 ESLint 這樣的工具簡直是天賜之物。2012 年的時候他們都還沒有出現呢,他們都提供了一個格式化你的樣式指導規則的方法,然後在你建立一個 pull request 之前自動地按照規則校驗你的代碼,說到這兒我們就不得不提 Git 了。

Git

我認為自從2012年以來,世界範圍内的 Git 工作流沒有太大的變化,話說回來, Github pull request 頁面上仍然沒有給分支名加上連結,誰知道是因為什麼天殺的原因。

很顯然,在特性分支下工作你應該感到非常舒适,将你與他人的工作成果進行衍合(rebase),借助互動式衍合工具來改寫(squash)送出,而且在小的單元裡工作不太可能導緻随時可能産生的沖突。另一個必備的Git工具的是鈎子(hooks)– 你尤其需要預推送和預送出鈎子來運作你的測試案例并執行所有代碼的品質檢查。你可以自己寫這些鈎子,但類似于 ghooks 這樣的工具可以幫你完成這些繁雜的過程,你沒有理由不将他們內建到你的工作流中去。

用戶端模闆

對于一些“錯誤”的定義可能是我在以前的文章中犯下的最大的錯誤。用戶端模闆仍然很有價值,毫無疑問 – 它的價值高到它将會内建到 ES2015 中去 – 但過度濫用依然會有不好的後果。許多團隊将所有的渲染工作轉移到浏覽器中,極大的性能開銷使得這種 “用戶端生成所有 HTML” 的方法逐漸失寵,這是來之不易的教訓。成熟的項目現在都在伺服器端生成 HTML – 甚至還預生成它,将它存儲為靜态檔案可以快速響應提供服務 – 然後在用戶端逐漸補充這個 HTML,當事件觸發的時候用用戶端模闆更新它。

我希望無論對于你還是我自己,在考慮到自己的決策對于性能的影響時,不僅局限于浏覽器領域,這也就是我接下來要談到的 …

Node

你說你很了解 JavaScript,是以接下來的時間我期待你能夠深入研究 Node,如果你知之甚少,那你起碼需要投入一點精力去了解它。的确,Node 世界裡有一些有關檔案系統、流、伺服器的知識,甚至還有一些完全與前端開發不一樣的範式,但作為前端開發者,如果你把這些寶貴的财富拒之門外将會極大地限制你的潛力。

即使你實際開發的産品沒有使用 Node 作為項目的後端,你仍然可以利用它來模拟後端服務的狀态來盡快完成前端開發。最起碼的,你應該熟悉如何 初始化一個Node項目,如何配置一個 Express 伺服器和路由,以及如何使用 request 子產品來代理請求。

繼續閱讀