從2012年(nian)到現在(zai),一(yi)篇文(wen)章都(dou)沒(mei)發過讓我(wo)覺得有(you)點羞羞噠。三(san)年(nian)是(shi)一(yi)段很長的(de)時間,很多(duo)(duo)東西都(dou)發生了改變。2012年(nian),我(wo)鼓勵同學(xue)們(men)去學(xue)習(xi)瀏覽器開發者工具(ju)和模塊化;雖然有(you)很多(duo)(duo)同學(xue)會覺得CSS預編(bian)譯和客戶端(duan)模板引擎并不靠(kao)譜(pu),但我(wo)仍然想要說一(yi)說它們(men);還有(you)JSHint,雖然有(you)#getoffmylawn(滾出我(wo)的(de)地盤)的(de)警告,但依然無法阻止(zhi)JSHint成為(wei)一(yi)個受(shou)歡迎(ying)的(de)理念(準確的(de)說,JSLint真的(de)(只(zhi)是(shi))存在(zai)過)。
已經是(shi)2015年(nian)了,我(wo)想(xiang)(xiang)寫一篇(pian)新的(de)(de)(de)(de)(de),但是(shi)當(dang)我(wo)坐下來(lai)(lai)開始動筆(bi)的(de)(de)(de)(de)(de)時候,想(xiang)(xiang)到(dao)了兩個(ge)事(shi)情。一,這(zhe)些東西被稱作(zuo)(zuo)“必知(zhi)必會”可能(neng)有(you)人會覺(jue)得不(bu)太公平——如果(guo)你(ni)已經覺(jue)得2012年(nian)的(de)(de)(de)(de)(de)那篇(pian)文章如此,那本文也是(shi)一樣的(de)(de)(de)(de)(de)了。也許有(you)同學會說(shuo),我(wo)們應該把(ba) “足夠(gou)應付業(ye)(ye)務需求的(de)(de)(de)(de)(de)技能(neng)” 作(zuo)(zuo)為 “前端必須掌(zhang)握的(de)(de)(de)(de)(de)知(zhi)識(shi)(shi)”,但考慮到(dao)前端行業(ye)(ye)里(li)也有(you)各(ge)(ge)種各(ge)(ge)樣的(de)(de)(de)(de)(de)工(gong)作(zuo)(zuo)可供選擇(ze),這(zhe)么做(zuo)也只能(neng)得到(dao)一個(ge)并(bing)不(bu)適合(he)所有(you)人的(de)(de)(de)(de)(de) “前端基礎知(zhi)識(shi)(shi)”。對于(yu)我(wo)來(lai)(lai)說(shuo),我(wo)需要的(de)(de)(de)(de)(de)不(bu)是(shi)工(gong)作(zuo)(zuo),我(wo)想(xiang)(xiang)要的(de)(de)(de)(de)(de)是(shi)被邀請去(qu)做(zuo)一份(fen)牛(niu)逼(bi)的(de)(de)(de)(de)(de)工(gong)作(zuo)(zuo)。我(wo)想(xiang)(xiang)要的(de)(de)(de)(de)(de)不(bu)只是(shi)去(qu)干(gan)活(huo)而已,而是(shi)想(xiang)(xiang)和一群牛(niu)逼(bi)的(de)(de)(de)(de)(de)人一起(qi)做(zuo)牛(niu)逼(bi)的(de)(de)(de)(de)(de)事(shi)。我(wo)不(bu)想(xiang)(xiang)僅(jin)僅(jin)滿足于(yu)用已有(you)的(de)(de)(de)(de)(de)知(zhi)識(shi)(shi)來(lai)(lai)完成(cheng)現在(zai)的(de)(de)(de)(de)(de)工(gong)作(zuo)(zuo),而是(shi)希望掌(zhang)握更多(duo)的(de)(de)(de)(de)(de)知(zhi)識(shi)(shi)來(lai)(lai)解決未(wei)來(lai)(lai)將會面對的(de)(de)(de)(de)(de)問題。
第二(er),我(wo)現在(zai)已(yi)經完全把Javascript作(zuo)為我(wo)的(de)(de)核心(xin)了:CSS知識(shi)(shi)只有(you)(you)在(zai)必須關注性(xing)能問題時(shi)才會(hui)用到,其他場景(jing)已(yi)經用的(de)(de)越來越少。我(wo)知道有(you)(you)很多牛逼(bi)的(de)(de)前端(duan)同(tong)學并不是(shi)這樣的(de)(de),但(dan)我(wo)也(ye)意識(shi)(shi)到,關注JS的(de)(de)同(tong)學和關注CSS的(de)(de)同(tong)學之(zhi)間的(de)(de)距(ju)離也(ye)越來越遠。這可能需要在(zai)另起一(yi)篇文章來討論,不過我(wo)想說(shuo)的(de)(de)是(shi),這篇文章中不會(hui)有(you)(you)介紹CSS技能標準的(de)(de)內容(rong),因為我(wo)還遠遠沒(mei)有(you)(you)達到能那(nei)么做的(de)(de)水平。
總之,就(jiu)算這個技(ji)能列(lie)表并不(bu)適(shi)合(he)你的前端(duan)工作,沒關系,不(bu)要有(you)壓力(li),地球(qiu)也不(bu)會爆炸。
JavaScript
回(hui)想2009年(nian)(nian),那(nei)時(shi)候當你(ni)知道 HTML5 在(zai)(zai)2014年(nian)(nian)才(cai)能(neng)用(yong)的(de)(de)時(shi)候,你(ni)是(shi)不(bu)是(shi)覺得這輩子基本上都(dou)用(yong)不(bu)到它(ta)了(le)(le)?如果(guo)是(shi),那(nei)么(me)你(ni)需要準備(bei)好接受進展緩慢但是(shi)已(yi)經趨于(yu)穩(wen)定的(de)(de)ES6了(le)(le),它(ta)也(ye)是(shi)下一代的(de)(de)Javascript(現(xian)在(zai)(zai)叫 ES2015 了(le)(le),嗯,這名字至少表(biao)示今年(nian)(nian)就能(neng)用(yong)了(le)(le))。就我(wo)而言,ES6,額,ES2015 無疑是(shi)我(wo)個人(ren)現(xian)在(zai)(zai)最關注的(de)(de) Javascript 內(nei)容。在(zai)(zai) ES6 中(zhong)將會出現(xian)一些比較(jiao)大的(de)(de)變化:類,真正的(de)(de)私有,經過改進更易用(yong)的(de)(de)函數和(he)參數設定,可導入的(de)(de)模塊,等等等等。那(nei)些掌握和(he)理解新的(de)(de)語法的(de)(de)同(tong)學(xue)以后將會在(zai)(zai) JS 社區牛逼閃閃。相關閱讀:
,Nicholas Zakas 正在寫的書(shu)。
BabelJS,一個(ge)可以把(ba)你寫的 ES6 的代(dai)碼編(bian)譯成 ES5 并在現代(dai)瀏覽(lan)器中運行(xing)的工具。他們也有一個(ge)不錯(cuo)的。
,里(li)面有大量(liang)的(de)文章探索 ES6 的(de)特性,語(yu)義和缺陷。
你也許會問:那(nei)我需(xu)要(yao)成為(wei)一(yi)(yi)個(ge) ES6 專(zhuan)家么?也許現在(zai)不(bu)需(xu)要(yao),但至少你得(de)和你的(de)同(tong)事懂的(de)一(yi)(yi)樣(yang)多(duo)吧?或者比他們稍微多(duo)一(yi)(yi)點?當(dang)然,如果(guo)能在(zai)你的(de)下一(yi)(yi)個(ge)新(xin)項目中作為(wei)一(yi)(yi)個(ge)娛樂性的(de)技(ji)術嘗試也是不(bu)錯(cuo)的(de),做(zuo)好準備(bei)肯定沒錯(cuo)的(de),因為(wei)我們永遠不(bu)知道下一(yi)(yi)刻會發(fa)生什么。
先不(bu)說新的語言特(te)性,使用(yong)回(hui)調和(he) promises 管理(li)異步 Javascript 至少得背的滾瓜爛熟吧。瀏覽器端應(ying)(ying)用(yong)加載(zai),以(yi)及應(ying)(ying)用(yong)間(jian)通信(xin)策略得形成一套自己的觀點吧。而(er)且你(ni)應(ying)(ying)該知道哪(na)種(zhong)框架(jia)最適合你(ni),而(er)不(bu)是(shi)現在還把時間(jian)花(hua)在理(li)解各(ge)種(zhong)框架(jia)的實現原理(li)和(he)該選擇哪(na)種(zhong)框架(jia)上。
模塊化和構建工具
毫無(wu)疑問,模(mo)塊化是構建 Web 客戶端應用的(de)基石(shi)。回到2012年,關于使用哪種模(mo)塊化(/)方(fang)案構建瀏(liu)覽器端應用還存在很多爭(zheng)論(lun)。而最近慢慢火起來的則在保證代碼可(ke)復用的(de)(de)前(qian)提下嘗試避免(mian)這(zhe)樣的(de)(de)問題。 其(qi)實(shi)也(ye)沒(mei)什么好(hao)爭得,畢竟這(zhe)倆玩意兒之間也(ye)就差幾個(ge)字符吧?
我覺(jue)得(de)類似這(zhe)樣(yang)的(de)爭(zheng)論其實并不(bu)(bu)都需要有一(yi)個答(da)案,這(zhe)也是我覺(jue)得(de)從2012年到(dao)現(xian)在我們發生的(de)最大的(de)轉變,當然(ran),也許只是我自己這(zhe)么認(ren)為(wei)。因為(wei)我覺(jue)得(de)與(yu)其說“我再也不(bu)(bu)用 AMD 了”之類的(de)話,倒(dao)不(bu)(bu)如多去(qu)討論 “在開發和打包(bao)過程中使(shi)用 CommonJS 和 npm 遇到(dao)的(de)各種(zhong)難題” 來的(de)更有價值。
雖(sui)然很感激(ji)曾(ceng)經對(dui)模塊化做出的貢(gong)獻,不過現在我開始有點迷戀了。 webpack 的構建配置比 RequireJS 更(geng)加易于理(li)解(jie),也更(geng)具(ju)訪問性。通過(guo)它(ta)的熱插拔特性和內置的本地靜(jing)態服務器(qi)可以讓發布更(geng)加便捷。它(ta)并不強(qiang)制(zhi)要求使用(yong) AMD 或者 CommonJS – 兩個它(ta)都支持。它(ta)還實現了一大堆(dui)加載器(qi),用(yong)來完(wan)成常(chang)見的繁瑣工作。也值(zhi)得去(qu)了(le)解一(yi)下,不過我個人認為它(ta)比 Webpack 落后很多。一(yi)些靠譜的朋友告訴我說(shuo)也是這個領域的(de)競爭者,不(bu)過我還沒(mei)有(you)用(yong)過,而且它的(de)文檔爛的(de)我連看都不(bu)想(xiang)看。不(bu)過我覺得它的(de)好基友 (包管理器)比較有(you)趣,jspm 可以讓你(ni)從(cong)各種(zhong)包管理服務器加載(zai)你(ni)需要的各種(zhong)組(zu)件(jian),(組(zu)件(jian)必須是(shi)符合(he) ES6, AMD, CommonJS and globals 規范(fan)的),包括 npm, github 等,但是(shi)我對于這兩個玩意的合(he)體還是(shi)有(you)點不太理解。啊,還有(you),雖然(ran)我說(shuo)了這么多關于模(mo)塊化之外(wai)的內(nei)容,但我從(cong)來沒想過放棄(qi) AMD,我們邊走邊看吧。
我覺得(de)如果要(yao)停止對模塊化和(he)構(gou)建工具的(de)(de)爭論,形成統一(yi)的(de)(de)模塊化系(xi)統,并且(qie)在(zai)這(zhe)個系(xi)統里(li)面(mian),任何項目的(de)(de)代(dai)碼都可以共(gong)享,而且(qie)還不(bu)需(xu)要(yao) UMD 這(zhe)樣(yang)額外的(de)(de)補丁工具,我們(men)還有(you)很長(chang)的(de)(de)路要(yao)走。理想狀況下,ES6 modules 的(de)(de)到(dao)(dao)來(lai)(lai)會(hui)解決這(zhe)些(xie)(xie)問題,不(bu)過(guo)在(zai)這(zhe)一(yi)天到(dao)(dao)來(lai)(lai)之前,類似 UMD 之類的(de)(de)轉換器會(hui)填補這(zhe)些(xie)(xie)空缺,不(bu)過(guo)貌似這(zhe)樣(yang)做我們(men)又(you)把事情(qing)變得(de)復雜了(le),好(hao)像(xiang)我們(men)也(ye)總喜歡把事情(qing)弄得(de)復雜。
與(yu)此同(tong)時,前端開(kai)發人員也需要對(dui)構建工具,各種模塊(kuai)化(hua)系統(tong)有自己(ji)的(de)(de)見解和知(zhi)識儲備。不管是(shi)好是(shi)壞,根據(ju) Javascript 現在的(de)(de)進度,你的(de)(de)模塊(kuai)化(hua)策略會對(dui)你的(de)(de)項目(mu)有比較大(da)的(de)(de)影(ying)響。
測試
客戶端的(de)代碼(ma)測(ce)試(shi)變得越來(lai)越普(pu)遍,最近(jin)也誕生了一些新的(de)測(ce)試(shi)框架:,。我發現基于 promise 的(de) Intern 的(de)異步(bu)測(ce)試方(fang)法相(xiang)當優雅。不過可能是因(yin)為習慣,我大多數情況下還是用 Mocha 寫測(ce)試用例。
測試(shi)的(de)主要(yao)障礙其實是前端開發(fa)者(zhe)的(de)代碼編(bian)寫方式。我(wo)在2012年發(fa)表過一個(ge)關于《編(bian)寫可測試(shi)的(de)Javascript》的演講,緊接著(zhu)幾(ji)個月后又發表了(le)一篇相關的文章。
測試(shi)的(de)第二大(da)障礙(ai)是(shi)工(gong)具(ju)。Webdriver 是(shi)一(yi)(yi)個(ge)艱難而巨大(da)的(de)工(gong)作。目前在(zai)各個(ge)瀏(liu)覽器端做持續集成(cheng)的(de) UI 自動化測試(shi)基本上是(shi)不可(ke)能(neng)的(de),更(geng)不用說(shuo)移(yi)動端了。我(wo)們仍然停留在(zai)局限(xian)于某一(yi)(yi)小(xiao)部(bu)分瀏(liu)覽器和設備上做輕量級的(de)自動化功能(neng)測試(shi),盡(jin)我(wo)們所能(neng)去(qu)研(yan)究怎樣(yang)快速,低(di)成(cheng)本的(de)進行這種測試(shi)的(de)階段(duan)。
如果你對如何改進代碼的可測試性感(gan)興趣的話,那(nei)么(me)唯一一本最值得(de)看(kan)的書是 Working Effectively with Legacy Code (。作(zuo)者Michael Feathers定義了“遺留(liu)代(dai)碼”的(de)概念:任何未經(jing)測試的(de)代(dai)碼都是(shi)遺留(liu)代(dai)碼。在測試領域,最基(ji)本的(de)要素就(jiu)是(shi)上面這(zhe)句話,盡管你可能不這(zhe)么認為。
流程自動化
你(ni)首先(xian)會(hui)想到,這也是理所(suo)當然(ran)的。而 和的(de)自動化(hua)構(gou)建方式也(ye)別具匠心。我沒用過Broccoli,只玩過Gulp,我也(ye)開始意識到(dao)Grunt對于依賴(lai)其他(ta)服(fu)務(wu)的(de)復(fu)雜(za)任(ren)務(wu)的(de)自動化(hua)工作存在局限性,尤(you)其是當這種(zhong)任(ren)務(wu)每天需要運行(xing)上(shang)千(qian)次的(de)時候。
是在我(wo)寫(xie)完2012年的(de)那(nei)篇文章僅僅45天之后(hou)發布的(de),我(wo)承(cheng)認當時我(wo)并沒(mei)有(you)及時去(qu)嘗試一(yi)下。不(bu)過最(zui)近我(wo)開(kai)始啟動一(yi)些新(xin)項目(mu),這些新(xin)項目(mu)有(you)兩個特點
a) 這些項目都(dou)是從零開始(shi)
b) 嘗試(shi)用(yong)一些不同的技術方(fang)(fang)案,試(shi)圖(tu)通過這種方(fang)(fang)式找到 Bazaarvoice(提供(gong)第三(san)方(fang)(fang)點評服(fu)務)上(shang)第三(san)方(fang)(fang) JS 應用(yong)的規范化的開(kai)發方(fang)(fang)式。
Yeoman 在這兩方面做的(de)(de)都(dou)很(hen)好(hao)。一個簡單的(de)(de) yo react-webpack 命令就可(ke)以為你(ni)初始化好(hao)你(ni)的(de)(de)項目,然(ran)后(hou)各種你(ni)想要的(de)(de)玩(wan)具也(ye)都(dou)應(ying)有盡有:生成(cheng)測(ce)試用例,本地靜態服務(wu)器,hello world 入門程序,等(deng)等(deng)等(deng)等(deng)。如果 React 和 webpack 不是你(ni)想要的(de)(de),也(ye)許你(ni)會(hui)在 Yeoman 的(de)(de) generators(項目生成(cheng)器)里(li)面找(zhao)到一個你(ni)想要的(de)(de),當然(ran),自(zi)己(ji)自(zi)定義一個這樣的(de)(de)構建包也(ye)是比較容易的(de)(de)。
鑒于(yu)Yeoman只是(shi)一(yi)個(ge)在項(xiang)目(mu)開始(shi)時才(cai)會用到的構建工(gong)具,并(bing)且(qie)鑒于(yu)我們并(bing)不(bu)是(shi)總(zong)是(shi)做新項(xiang)目(mu),所以大多(duo)情(qing)況(kuang)下了解一(yi)下就夠了。除(chu)非,你也想去規范整個(ge)項(xiang)目(mu)開發過程,那么它(ta)可(ke)能會更有(you)價值一(yi)點。
Broccoli已(yi)經得到了 ember-cli 的(de)采納,我覺得他們的(de)配(pei)對可(ke)能會(hui)有一個新名字(zi),這樣在(zai)未來才比較方便和 Grunt /Yeoman 對抗。而 Grunt 和 Yeoman 的(de)開發進度也放緩了,所(suo)以未來會(hui)發生什么(me),我們還(huan)是靜(jing)觀其變吧(ba)。
代碼質量
如果你像我一樣,一看見違(wei)反代碼規范的代碼時就開始(shi)抓狂,那么 JSCS 和
ESLint 就是老天(tian)賜(si)給你(ni)的(de)禮物,而2012壓根就沒這些玩意(yi)。他們都(dou)提供了自(zi)(zi)定義代碼(ma)規范(fan)的(de)方(fang)式,并且(qie)可以在代碼(ma)提交前對你(ni)的(de)代碼(ma)做自(zi)(zi)動化校驗。這讓我(wo)想起了…
Git
從2012年到現在,github 的(de)使(shi)用流程并沒(mei)有發生(sheng)很大的(de)變化,比如(ru)在 pull request 頁面連(lian)個分支名都(dou)沒(mei)有(只是惡搞一下)。
你(ni)(ni)(ni)應該(gai)非常清楚和(he)(he)流暢(chang)地使(shi)用(yong)(yong)(yong)功(gong)能分支(feature branches), 使(shi)用(yong)(yong)(yong) rebase 合并別人的(de)(de)代碼(ma)干活,使(shi)用(yong)(yong)(yong)交互(hu)式 rebase 命(ming)令和(he)(he) squash 合并提交記錄,或者盡(jin)可(ke)能細顆粒度的(de)(de)劃分項目內容,避免(mian)引起代碼(ma)沖(chong)突(tu)。另(ling)一個可(ke)用(yong)(yong)(yong)的(de)(de) Git 工具是鉤(gou)子,具體而言,就是你(ni)(ni)(ni)可(ke)以在 push 前,commit 前,執行(xing)你(ni)(ni)(ni)的(de)(de)各(ge)種測試(shi)用(yong)(yong)(yong)例(li),檢查(cha)代碼(ma)質量(liang)。你(ni)(ni)(ni)可(ke)以自己寫鉤(gou)子,也可(ke)以使(shi)用(yong)(yong)(yong) ghooks ,由(you)于 ghooks 使(shi)鉤(gou)子工作(zuo)變(bian)得非常簡單(dan),所以你(ni)(ni)(ni)簡直沒有理由(you)不用(yong)(yong)(yong)它。
客戶端模板
這(zhe)可能(neng)是我在(zai)(zai)2012年(nian)的(de)那篇文章中(zhong)寫的(de)最爛(lan)的(de)內(nei)容了,某種意義上的(de)“爛(lan)”。客(ke)戶端(duan)(duan)模板(ban)還是很有價(jia)值的(de),而且它已經被(bei)(bei)內(nei)置到(dao) ES2015 里面(mian)了,這(zhe)不(bu)僅(jin)僅(jin)只是一件好(hao)事而已。這(zhe)些年(nian)也有一些慘(can)重的(de)教訓,不(bu)少(shao)團隊把所(suo)有的(de)渲染(ran)工作全(quan)部丟(diu)到(dao)瀏(liu)覽(lan)器端(duan)(duan)去做(zuo)(zuo),結果產生了嚴(yan)重的(de)性(xing)能(neng)問(wen)題(ti),所(suo)以(yi) “在(zai)(zai)瀏(liu)覽(lan)器端(duan)(duan)渲染(ran)生成所(suo)有 HTML” 的(de)做(zuo)(zuo)法理所(suo)當然的(de)被(bei)(bei)摒棄了。 而更(geng)為聰明的(de)做(zuo)(zuo)法則(ze)是,把 HTML 生成放在(zai)(zai)服務(wu)器端(duan)(duan),或者(zhe)通過(guo)預編譯的(de)方式,先將(jiang)模板(ban)做(zuo)(zuo)為靜態資源儲(chu)存(cun)起來,在(zai)(zai)需要時快速的(de)編譯成 HTML,需要更(geng)新時也可以(yi)直接在(zai)(zai)客(ke)戶端(duan)(duan)更(geng)新模板(ban)。
這(zhe)里會有一些新的展望,不僅是對我自己(ji),也是對所有人,當你在考慮性能問(wen)題(ti)時,也許沒必要把自己(ji)完全(quan)限(xian)定在瀏覽器(qi)范圍內。所以(yi),這(zhe)又讓我想起了……
原文鏈接:
譯文來自: