文 大漠窮秋 2015-11-06
0x0000 第一大坑:瀏覽器兼容性
第一次瀏覽器大戰(zhàn)
桌面端瀏覽器大戰(zhàn)的硝煙尚未散盡可缚,移動端紛爭又起展哭。大廠神仙打架色乾,碼農(nóng)苦不堪言姑食。各種CSS纱耻、JS不兼容芭梯,坑得碼農(nóng)盡白頭。在兼容性這個問題上弄喘,M$的IE瀏覽器最是臭名昭著玖喘。
在各路神仙妖怪的持續(xù)吐槽之下,微軟終于臉上掛不住了蘑志,最近宣布在Windows10上徹底拋棄IE這個品牌累奈,強勢推廣全新的“斯巴達”瀏覽器。
http://www.expreview.com/39604.html
早期出現(xiàn)的各種“JS庫”急但,例如遠古的prototype澎媒、中古的mootools,到近代的jQuery波桩,再到大規(guī)模戒努、緊封裝的YUI、Extjs镐躲,很大的一個目標(biāo)就是為了填“兼容性”這個大坑储玫。
0x0001 第二大坑:沒有完善的開發(fā)侍筛、調(diào)試、測試撒穷、部署工具鏈
各種后端語言都有自己完善的IDE支持匣椰,有的還不止一種IDE,以Java開發(fā)為例端礼,市面上常見的就有來自IBM的Eclipse窝爪、開源免費的NetBeans、以及來自JetBrains的IntelliJ這些齐媒。整個的開發(fā)蒲每、調(diào)試、測試全部在IDE環(huán)境里面完成喻括,擼碼過程還是相當(dāng)酸爽的邀杏。
Eclipse的調(diào)試界面
相比之下,對于前端開發(fā)來說唬血,在FireBug望蜡、chrome出現(xiàn)之前,前端調(diào)試基本上都是靠alert來支持拷恨。
還記得只能用alert來進行調(diào)試的那段歲月嗎脖律?
更加坑的是,整個前端的代碼壓縮腕侄、自動化測試小泉、線上部署等等,根本沒有神馬特別好的工具支持冕杠。直到2009年微姊,終于出現(xiàn)了NodeJS這個神器。
終于等到冤大頭來填第二個巨坑了分预,好欣慰熬そ弧!
圍繞著NodeJS笼痹,出現(xiàn)了大量的前端開發(fā)腳手架配喳,例如用來編譯CSS的LESS和SASS,用來壓縮和混淆的grunt凳干、gulp晴裹、webpack,用來把ES6編譯成ES5的Babel等等纺座。
grunt編譯界面
因此息拜,從3大坑的角度看溉潭,NodeJS的出現(xiàn)净响,標(biāo)志著前端開發(fā)正式進入工業(yè)化時代少欺,刀耕火種的日子一去不復(fù)返了!
你司是不是還在這么玩兒馋贤?
資本主義國家已經(jīng)這么玩兒了
0x0002 第三大坑:JavaScript缺乏語言級的模塊化和組件化機制
類之間的依賴關(guān)系以Java為例赞别,各個類之間的依賴關(guān)系最終會形成以上這個“圖”數(shù)據(jù)結(jié)構(gòu)(有向有環(huán))。
對于前端開發(fā)來說配乓,各個業(yè)務(wù)模塊之間的依賴關(guān)系同樣會形成這樣一副“圖”仿滔。然而很可惜的是,JS這門語言本身并沒有對模塊化提供有力的支持犹芹。JS(ECMA5之前)并沒有import機制崎页,對于大規(guī)模的application來說,處理模塊之間的依賴關(guān)系絕對無比蛋疼腰埂。直到出現(xiàn)了CMD和AMD這樣的理論和思想飒焦,這種動態(tài)依賴加載的問題才有了比較好的解決方案。
RequireJS:用來填沒有動態(tài)import機制的坑
目前市面上比較成熟一點的前端框架屿笼,都會實現(xiàn)自己的“模塊化”機制牺荠。
RequireJS的模塊化寫起來是這樣一種風(fēng)格:
PS:這里不詳細解釋RequireJS的用法,如果你很感興趣驴一,請仔細閱讀阮老師的系列文章《Javascript模塊化編程》休雌。
ExtJS的模塊化是這樣用的:
AngularJS的模塊化是這樣用的:
這里也不詳細解釋AngularJS的各種概念,對AngularJS有興趣的肝断,請仔細看我在慕課網(wǎng)發(fā)布的免費視頻教程《AngularJS實戰(zhàn)》杈曲。
無論是哪一個框架,模塊化最底層的機制都是一樣的:用JS腳本動態(tài)創(chuàng)建script標(biāo)簽胸懈,從而誘使瀏覽器動態(tài)加載一段內(nèi)容(動態(tài)加載的內(nèi)容可以是JS腳本鱼蝉,也可以是普通的字符串,也可以是CSS)箫荡。這種機制的核心代碼示意如下:
以上代碼摘自RequireJS
- 用JS腳本動態(tài)創(chuàng)建一個script節(jié)點魁亦;
- 綁定事件回調(diào)函數(shù);
- 設(shè)置script節(jié)點的url屬性并插入到head中羔挡,從而誘使瀏覽器加載指定url的內(nèi)容洁奈;
在以上核心機制的基礎(chǔ)上,可以附加一些更加高級的功能绞灼,比如RequireJS加上了緩存機制(以完整的url為key)利术,避免多次加載相同的內(nèi)容,同時還加上了依賴檢測等功能低矮。
0x0003 單獨說說組件化
先來看兩種典型的前端界面:
電商或者門戶型的前端界面
后臺管理型或者叫ERP衍生型的界面
對于門戶和管理后臺這兩種截然不同的場景印叁,對前端組件的潛在需求是不同的。
對于門戶型界面來說,組件的數(shù)量會比較多轮蜕,組件的外觀比較靈活昨悼,但是每個組件的功能都比較簡單。因此跃洛,騰訊的張鑫旭提出“半封裝組件”的概念率触,比較適合用在門戶、互聯(lián)網(wǎng)這種業(yè)務(wù)場景下汇竭。
對于管理后臺型的界面來說葱蝗,情況恰好相反,組件的數(shù)量不多细燎,整體布局和外觀相對比較固定两曼,但是每個組件的功能都非常復(fù)雜。因為管理后臺型的系統(tǒng)實際上是一種變型的C/S結(jié)構(gòu)玻驻,它更靠近application(應(yīng)用)這種概念合愈,而不是page(頁面)。
有一些專門做管理系統(tǒng)(或者叫運營支撐系統(tǒng))的企業(yè)击狮,里面的設(shè)計師居然也出來炒作“半封裝”的概念佛析,很明顯對公司的業(yè)務(wù)場景缺乏認(rèn)識,對前端開發(fā)的大背景也缺乏感知彪蓬。
典型的管理后臺型系統(tǒng)會出現(xiàn)(或者說客戶會要求)Tree寸莫、Grid這樣的重量級組件:
后臺管理型系統(tǒng)里面常見的Tree組件
這種重量組件的功能非常復(fù)雜,例如表格的列頭需要能拖動档冬,表格內(nèi)部的單元格需要能動態(tài)編輯膘茎。因此,這種組件的代碼量非常龐大酷誓,以大家最常用的一個基于jQuery的FlexGrid控件為例披坏,光JS代碼有兩萬多行。
再看幾個典型的后臺管理型的組件庫:
國產(chǎn)的MiniUI(基于jQuery)
ExtJS4.1盐数,大約200個組件
以上這些用來開發(fā)管理后臺的組件庫帚屉,組件的功能基本類似,整體數(shù)量都在200個左右漾峡。
由于門戶和管理后臺這兩種場景對組件的功能和外觀的要求完全不同攻旦,加上SEO、頁面靜態(tài)化生逸、后端渲染等眾多因素的影響牢屋,因此在做技術(shù)選型時要仔細考慮且预。比如,拿ExtJS或者Flex去做一個門戶網(wǎng)站烙无,或者拿AngularJS去做管理后臺锋谐,都是典型的不理智行為。
用ExtJS開發(fā)門戶網(wǎng)站就是這種效果
總結(jié):組件化只是整個前端開發(fā)過程中需要考慮的一部分,而不是全部狮鸭。有一些人沉迷于“組件化”的思維無法自拔合搅,忘記了3大坑的存在。對于管理后臺型的系統(tǒng)歧蕉,更多要考慮模塊化灾部、大規(guī)模團隊協(xié)作等工程問題!
0x0004 這是亂入的一個小節(jié):JS并不是一門面向?qū)ο蟮恼Z言
大家都知道惯退,“面向?qū)ο蟆钡娜筇卣魇牵悍庋b赌髓、繼承和多態(tài)。而JS在語言層面上并沒有提供有力的支持催跪,因此锁蠕,從這個角度說,JS并不是一門“面向?qū)ο蟆钡恼Z言懊蒸。說到這兒,來看一下JS之父是怎么評價這門語言的,其中一段最經(jīng)典的話是這么說的:
"與其說我愛Javascript照激,不如說我恨它恭取。它是C語言和Self語言一夜情的產(chǎn)物。十八世紀(jì)英國文學(xué)家約翰遜博士說得好:'它的優(yōu)秀之處并非原創(chuàng)通危,它的原創(chuàng)之處并不優(yōu)秀铸豁。'(the part that is good is not original, and the part that is original is not good.)"
關(guān)于JavaScript的更多趣聞軼事,請參見阮老師的博文《Javascript誕生記》菊碟。
JS(ECMA5之前)并沒有語言級的class/extends/import機制节芥。這對前端的“組件化”、MVC來說造成了巨大的障礙逆害。因此藏古,才出現(xiàn)了大量的庫和框架來填這個坑。
由于沒有語言級的class和extends忍燥,開發(fā)者不得不使用蛋疼無比的“原型繼承”機制拧晕。最簡化的一段實現(xiàn)代碼看起來是這樣的:
原型繼承示意代碼
以上是最簡單的一種實現(xiàn),沒有考慮“靜態(tài)方法”梅垄、“多級繼承”等問題厂捞,各種框架在模擬實現(xiàn)extends機制上各有千秋输玷,其中以ExtJS的實現(xiàn)最經(jīng)典,基本上完全模擬出了類似Java里面extends的全部行為模式靡馁。
最近的一個好消息是欲鹏,ECMA在2015年9月已經(jīng)發(fā)布了ES6標(biāo)準(zhǔn),其中已經(jīng)加上了大家期待已久的class/extends/import這些機制臭墨,代碼寫起來是這么一種尿性:
關(guān)于ES6的完整特性介紹赔嚎,請看阮老師的系列文章:《ECMAScript 6入門》
0xFFFFFF 終章
3大坑對前端開發(fā)的影響示意圖(使用百度echarts制作)
解釋幾個關(guān)鍵的時間點:
- 2003年:以淘寶為首的電子商務(wù)企業(yè)開始出現(xiàn),前端代碼規(guī)模開始大膨脹胧弛,此時瀏覽器的兼容性是最大的問題尤误;
- 2005年前后:Ajax興起,WebApplication结缚、WEB2.0等概念開始被瘋狂炒作损晤,前端代碼規(guī)模進一步膨脹,繼續(xù)完善的開發(fā)工具鏈红竭,但是瀏覽器兼容性問題造成的影響開始降低尤勋;
- 2009年:NodeJS興起,各種前端開發(fā)工具大爆發(fā)茵宪,由于ExtJS最冰、Flex等框架的興起,以及對WEBOS這個概念的炒作稀火,前端組件化的呼聲日益高漲锌奴;
總結(jié):市面上絕大多數(shù)前端框架都是在填這3大坑,牛逼一點的同時填幾個坑憾股,例如ExtJS(大規(guī)模封裝鹿蜀,提供各種開發(fā)工具);規(guī)模小一點的只填其中一個坑服球,例如AngularJS(不管瀏覽器兼容性)茴恰、React(只做View層)。因此斩熊,站在3大坑的角度往枣,你就獲得了一個廣闊的視角,無論出現(xiàn)什么新框架粉渠,都是在填坑而已分冈!