淺談了不起的前端
前言
喜歡聊一些新奇的技術(shù),也喜歡學(xué)習(xí)新的東西,在這個(gè)日益繁榮的時(shí)代,有幸見證技術(shù)的發(fā)展是多么美好的一件事。
前端簡(jiǎn)史
技術(shù)的發(fā)展總是遇到問(wèn)題,去解決問(wèn)題,然后不斷遇到問(wèn)題,不斷解決問(wèn)題。前端最初被稱為Front-end。主要是用來(lái)采集輸入信息,呈現(xiàn)界面效果。
關(guān)于前端的發(fā)展得從Tim在1990年發(fā)明了最原始的瀏覽器開始,隨著Tim推廣,美國(guó)國(guó)家超算應(yīng)用中心開發(fā)了名為Mosaic 的瀏覽器,并于93年4月發(fā)布;第二年第一屆萬(wàn)維網(wǎng)大會(huì)在日內(nèi)瓦召開,同年7月,Html2.0規(guī)范發(fā)布,11月網(wǎng)景成立并發(fā)布第一代瀏覽器,改名為Navigator。94年底,W3C成立。此時(shí),進(jìn)入靜態(tài)網(wǎng)頁(yè)時(shí)代。也就是web1.0時(shí)代。
95年網(wǎng)景工程師 Brendan Eich 花了10天時(shí)間設(shè)計(jì)了 JavaScript 語(yǔ)言。與此相對(duì)的是,1996 年,微軟發(fā)布了 VBScript 和 JScript。第一次瀏覽器之爭(zhēng)開始了,同年11月,網(wǎng)景把javascript推向國(guó)際化,并在97年6月ECMA 以 JavaScript 語(yǔ)言為基礎(chǔ)制定了 ECMAScript 1.0 標(biāo)準(zhǔn)規(guī)范。第一次瀏覽器戰(zhàn)爭(zhēng)以 IE 瀏覽器完勝 Netscape 而結(jié)束,IE 開始統(tǒng)領(lǐng)瀏覽器市場(chǎng),份額的最高峰達(dá)到 2002 年的 96%。隨著第一輪大戰(zhàn)的結(jié)束,瀏覽器的創(chuàng)新也隨之減少。作為獨(dú)裁者,IE 并不遵循 W3C 的標(biāo)準(zhǔn),IE 成了事實(shí)標(biāo)準(zhǔn)。
js的誕生,可以說(shuō)是開啟了動(dòng)態(tài)網(wǎng)頁(yè)的時(shí)代,為了使得 Web 更加充滿活力,以 PHP、JSP、ASP.NET 為代表的動(dòng)態(tài)頁(yè)面技術(shù)相繼誕生。
直到Google 分別在 2004 年和 2005 年先后發(fā)布了兩款重量級(jí)的 Web 產(chǎn)品:Gmail 和 Google Map。這兩款 Web 產(chǎn)品都大量使用了 AJAX 技術(shù),不需要刷新頁(yè)面就可以使得前端與服務(wù)器進(jìn)行網(wǎng)絡(luò)通信,顛覆了用戶體驗(yàn),這也體現(xiàn)了Ajax的較大的特性就是局部刷新。Ajax的流行,是我們進(jìn)入了Web2.0時(shí)代,也就是客戶端更方便的向服務(wù)端發(fā)送信息。
隨著Firefox的出現(xiàn),直接引發(fā)第二次瀏覽器大戰(zhàn)。第二次瀏覽器戰(zhàn)爭(zhēng)中,隨著以 Firefox 和 Opera 為首的 W3C 陣營(yíng)與 IE 對(duì)抗程度的加劇,瀏覽器碎片化問(wèn)題越來(lái)越嚴(yán)重,不同的瀏覽器執(zhí)行不同的標(biāo)準(zhǔn),對(duì)于開發(fā)人員來(lái)說(shuō)這是一個(gè)惡夢(mèng)。為了解決這個(gè)問(wèn)題,眾多兼容性js框架誕生,JQ在眾多同類中脫穎而出,獨(dú)領(lǐng)風(fēng)騷,幾乎成了業(yè)界的標(biāo)配。
但是隨著Web應(yīng)用的增多,舊的標(biāo)準(zhǔn)難以滿足需求,在2008 年 1 月 22 日,H5草案發(fā)布。同年12月,Chrome 發(fā)布JavaScript 引擎 V8,并加入瀏覽器之爭(zhēng)中。H5的真正興起是由于它與Flash的差異,在2010年4月,喬布斯發(fā)表一篇題為“對(duì) Flash 的思考”的文章,指出隨著 HTML5 的發(fā)展,觀看視頻或其它內(nèi)容時(shí),Adobe Flash 將不再是必須的,同時(shí)H5的WebWorker 可以讓 JavaScript 運(yùn)行在多線程中,WebSocket 可以實(shí)現(xiàn)前端與后臺(tái)的雙工通信,WebGL 可以創(chuàng)建 Web3D 網(wǎng)頁(yè)游戲……
在第二次瀏覽器大戰(zhàn)中,各個(gè)瀏覽器廠商都以提升 JavaScript 運(yùn)行效率和支持 HTML5 各種新特性為主要目標(biāo),促進(jìn)了瀏覽器的良性競(jìng)爭(zhēng)。直到2016年,Chrome 占據(jù)了瀏覽器市場(chǎng)的半壁江山。
一個(gè)小插曲的就是TypeScript的誕生,TypeScript 是一種由微軟開發(fā)的自由和開源的編程語(yǔ)言。它是 JavaScript 的一個(gè)超集,而且本質(zhì)上向這個(gè)語(yǔ)言添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊獭2⒂?012.10 微軟發(fā)布 TypeScript 公開版。
2009 年,Ryan 利用 Chrome 的 V8 引擎打造了基于事件循環(huán)的異步 I/O 框架 —— Node.js 誕生。Node的出現(xiàn)使前端的職能進(jìn)一步擴(kuò)大,前端正式進(jìn)入服務(wù)端。由于語(yǔ)言的特性,我們很難用一種語(yǔ)言去實(shí)現(xiàn)前后端的開發(fā)。Node的出現(xiàn),擴(kuò)展了js語(yǔ)言的特性,它更重要的是構(gòu)建了一個(gè)龐大的生態(tài)體系。使得js大有一統(tǒng)天下之勢(shì)。
2010 年 1 月,NPM 作為 Node.js 的包管理系統(tǒng)首次發(fā)布。我們可以按照 CommonJS 的規(guī)范編寫 Node.js 模塊,然后將其發(fā)布到 NPM 上面供其他開發(fā)人員使用。Npm是世界上較大的包模塊管理系統(tǒng)。
關(guān)于Node的框架有很多,有Express、koa、Sails、egg。推薦egg,因?yàn)閑gg是阿里出的,有完整詳細(xì)的文檔,它是為企業(yè)級(jí)應(yīng)用程序設(shè)計(jì)的。

談到模塊化,簡(jiǎn)單說(shuō)一下模塊化的歷程。模塊化體現(xiàn)的兩個(gè)特性就是獨(dú)立性和依賴性。早期,我們用script來(lái)引入js模塊,但是它的缺點(diǎn)也很明顯就是它會(huì)污染全局變量,同時(shí)有一個(gè)常見的問(wèn)題就是它的加載是有順序的,而且模塊太多,不美觀,資源難以管理。
為了解決這個(gè)問(wèn)題,commonJs規(guī)范誕生了,該規(guī)范的核心思想是允許模塊通過(guò)require方法來(lái)同步加載所要依賴的其他模塊,然后通過(guò) exports 或module.exports 來(lái)導(dǎo)出需要暴露的接口,同樣它的缺點(diǎn)是不能并行加載模塊,會(huì)阻塞瀏覽器加載。
AMD的誕生就是為了解決瀏覽器不能并行加載,代表工具就是requirejs,但是代碼閱讀性低。
同時(shí)CMD的出現(xiàn),使開發(fā)者多了一種選擇,代表工具是sea.js。與AMD相比,AMD推崇依賴前置;CMD推崇依賴就近,只有在用到某個(gè)模塊的時(shí)候再去require。AMD 的 API 默認(rèn)是一個(gè)當(dāng)多個(gè)用,CMD 的 API 嚴(yán)格區(qū)分,推崇職責(zé)單一。對(duì)于依賴的模塊,AMD是提前執(zhí)行,CMD是延遲執(zhí)行。
現(xiàn)在我們大多數(shù)用的是ES6模塊,EcmaScript6標(biāo)準(zhǔn)增加了JavaScript語(yǔ)言層面的模塊體系定義。ES6 模塊的設(shè)計(jì)思想,是盡量的靜態(tài)化,使得編譯時(shí)就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量。CommonJS和AMD模塊,都只能在運(yùn)行時(shí)確定這些東西。在 ES6 中,我們使用export關(guān)鍵字來(lái)導(dǎo)出模塊,使用import關(guān)鍵字引用模塊。但是瀏覽器還沒(méi)有完全兼容,需要使用babel轉(zhuǎn)化。

接著上面的講,隨著H5的流行,以前只適用于后端的思想,逐漸也被前端采用,MV*框架的興起,將前端從DOM操作直接推向了數(shù)據(jù)操作,這將是前端的又一次革命,如果把Ajax當(dāng)作前端的第一次革命,Node的出現(xiàn)當(dāng)作是前端的第二次革命,這將是前端的第三次革命。Ajax將靜態(tài)網(wǎng)頁(yè)變成了真正的“動(dòng)態(tài)”,并引領(lǐng)了瀏覽器生態(tài)的紛繁。Node將前端延伸到了后端,使js充滿了無(wú)限的想象力。MV*框架的誕生,更是改寫了前端的書寫方式。現(xiàn)在前端面試,問(wèn)的都是什么,你可以百度看看,現(xiàn)在的前端還是前端嗎?還是那個(gè)Front-end嗎?
隨著技術(shù)的興起,我們進(jìn)入了移動(dòng)應(yīng)用的時(shí)代,網(wǎng)頁(yè)逐漸由 Web Site 演變成了 Web App。涌現(xiàn)的Web App、Hybrid App、Native App。現(xiàn)在大多數(shù)App都是混合App,既有原生的功能,也有Web的頁(yè)面。前端逐漸開始涉及App應(yīng)用的開發(fā)。React Native可以用js來(lái)構(gòu)建原生應(yīng)用,極大的節(jié)約的開發(fā)成本,也加劇來(lái)前端的學(xué)習(xí)成本。不久前的谷歌開發(fā)大會(huì),講了Flutter開發(fā)原生應(yīng)用,F(xiàn)lutter是谷歌的移動(dòng)UI框架,可以快速在iOS和Android上構(gòu)建高質(zhì)量的原生用戶界面。
小程序的橫空出世,也是對(duì)前端的一個(gè)挑戰(zhàn),不論微信小程序還是支付寶小程序,都依托于一個(gè)巨大的流量池(平臺(tái))。前端的多樣性也導(dǎo)致前端的復(fù)雜性,那么問(wèn)題來(lái)了,我們?cè)趺床拍芏喽耸褂靡惶状a呢?
Taro 是一套遵循 React 語(yǔ)法規(guī)范的 多端開發(fā) 解決方案。現(xiàn)如今市面上端的形態(tài)多種多樣,Web、ReactNative、微信小程序等各種端大行其道,當(dāng)業(yè)務(wù)要求同時(shí)在不同的端都要求有所表現(xiàn)的時(shí)候,針對(duì)不同的端去編寫多套代碼的成本顯然非常高,這時(shí)候只編寫一套代碼就能夠適配到多端的能力就顯得極為需要。Taro是由京東凹凸實(shí)驗(yàn)室開發(fā)的。
前端也可以開發(fā)桌面應(yīng)用, Electron 是基于 Chromium 和 Node.js, 是一個(gè)使用 JavaScript, HTML 和 CSS 等 Web 技術(shù)創(chuàng)建桌面原生應(yīng)用程序的框架。Electron 兼容 Mac, Windows 和 Linux, 它構(gòu)建的應(yīng)用可在這三個(gè)操作系統(tǒng)上面運(yùn)行。
2015 年 6 月,ECMAScript 6.0 發(fā)布。該版本增加了許多新的語(yǔ)法。ECMAScript 以后每年將會(huì)發(fā)布一個(gè)新版本,這無(wú)疑將持續(xù)促使瀏覽器廠商不斷為 JavaScript 注入新的功能與特性,JavaScript走上了快速發(fā)展的正軌。
現(xiàn)在的前端還是前端嗎?隨著技術(shù)的發(fā)展,前端開始涉及各個(gè)端,js也可以在各端自由暢行,并不斷發(fā)掘潛力。一位朋友預(yù)測(cè),未來(lái)只會(huì)存在兩種開發(fā)人員,一個(gè)是端開發(fā)工程師,一個(gè)是云開發(fā)工程師。技術(shù)的界限越來(lái)越模糊,“全棧工程師”、“架構(gòu)師”等等新的職業(yè)詞匯不斷涌現(xiàn)。作為一個(gè)前端開發(fā)人員,要學(xué)的東西很多,而且不僅僅局限于前端。
最后一個(gè)問(wèn)題,你真的學(xué)不動(dòng)了嗎?