Node.js一發(fā)布,立刻在前端工程師中引起了軒然大波,前端網(wǎng)站制作工程師們幾乎立刻對(duì)這一項(xiàng)技術(shù)表露出了相當(dāng)大的熱情和期待。上一次一種技術(shù)能被整個(gè)前端界如此關(guān)注那還是在幾年之前,那時(shí)候Ajax這個(gè)概念剛剛被提出來(lái)。讓JavaScript跑在server端,這個(gè)想法簡(jiǎn)直太棒了。這下我們不用再去學(xué)那些什么PHP啦、Ruby啦、Java啦、Scala啦或者其他什么對(duì)前端來(lái)說(shuō)奇怪的語(yǔ)言,也可以輕松地將我們的領(lǐng)域擴(kuò)展到server端,多么美好的前景!
一、前端網(wǎng)站制作的兩次新生
Brendan Eich[2]可能也沒(méi)有想到JavaScript這門(mén)第1版只用了10天便完成設(shè)計(jì)的腳本語(yǔ)言在今天會(huì)如此流行。JavaScript目前不僅可以開(kāi)發(fā)傳統(tǒng)的Web站點(diǎn),而且還跨足了手機(jī)App、小程序、物聯(lián)網(wǎng)等開(kāi)發(fā)領(lǐng)域。JavaScript經(jīng)歷過(guò)兩次革命性的突破,這兩次突破也帶給了前端兩次新生。
1.第一次新生:AJAX
AJAX技術(shù)起步于微軟0utlook的XMLHTTP組件,微軟將其作為ActiveX組件的一部分加入Internet Explorer5。隨后,其他瀏覽器廠商,包括Mozi1la、Safari、Opera等,實(shí)現(xiàn)了一個(gè)同樣功能的JavaScript對(duì)象一—XMLHttpRequest。微軟是AJAX技術(shù)的布道者,Google的進(jìn)一步推廣將其帶到了普通民眾眼前。人們驚嘆于Google地圖、Gmail等Web應(yīng)用程序絕佳的用戶(hù)體驗(yàn)。Jesse JamesGarrett[3]在2005年2月“Ajax:A New Approach to Web Applications”一文中正式提出了“AJAX”一詞,并一直沿用至今。隨后,W3C在2006年正式發(fā)布了XMLHttpRequest規(guī)范草案。
AJAX技術(shù)可以實(shí)現(xiàn)異步請(qǐng)求和局部刷新,徹底改變了傳統(tǒng)Web站點(diǎn)的交互模式。Web不僅是供靜態(tài)展示的網(wǎng)站,而且是一種由瀏覽器展現(xiàn)、資源寄存于Internet的應(yīng)用程序。以此為契機(jī),Web開(kāi)發(fā)者開(kāi)始在AJAX技術(shù)的基礎(chǔ)之上探索和開(kāi)發(fā)更加豐富的功能和優(yōu)雅的用戶(hù)體驗(yàn)。與此同時(shí),用戶(hù)對(duì)Web應(yīng)用的需求也不斷提高,這間接推動(dòng)了Web技術(shù)的發(fā)展。
這是AJAX技術(shù)帶給前端的第一次新生。
2.第二次新生:Node.js
2009年第1版Node.js(只支持Linux和Mac0SX系統(tǒng))的發(fā)布是值得銘記的里程碑。Node.js的作者Ryan Dahl設(shè)計(jì)Node.js的靈感來(lái)自Flickr(一個(gè)提供網(wǎng)絡(luò)圖片服務(wù)的平臺(tái))上的一個(gè)上傳進(jìn)度條,瀏覽器為了能夠獲取上傳文件的進(jìn)度而不得不頻繁地向服務(wù)器發(fā)起查詢(xún)請(qǐng)求。與這種方式相比,如果服務(wù)器能夠在文件上傳完畢之后主動(dòng)推送一條消息給瀏覽器的話,會(huì)節(jié)省很多瀏覽器和網(wǎng)絡(luò)資源消耗。這種理念便是Node.js實(shí)現(xiàn)異步操作的核心Event Loop(事件驅(qū)動(dòng))的雛形,如圖1所示。
圖1
2011年,Node.js發(fā)布了支持Windows系統(tǒng)的版本,Node.js在Web開(kāi)發(fā)界進(jìn)一步流行起來(lái)。在此之前的十幾年內(nèi),JavaScript直被認(rèn)為只能在瀏覽器里耍點(diǎn)小把戲。即便AJAX技術(shù)徹底改變了網(wǎng)站的交互模式,JavaScript也仍然未脫離瀏覽器這個(gè)“宿主”。Node.js帶來(lái)的改革不僅僅是讓JavaScript進(jìn)入了服務(wù)器端開(kāi)發(fā)領(lǐng)域,更重要的意義是豐富了JavaScript的生態(tài)。JavaScript能做的事情越來(lái)越多,業(yè)內(nèi)泛起了JavaScript學(xué)習(xí)潮,這在一定程度上加速了ECMAScript規(guī)范的迭代。
這是Node.js帶給前端的第二次新生。
隨著用戶(hù)對(duì)Web應(yīng)用的期待越來(lái)越高,承載Web應(yīng)用的瀏覽器也“被迫”加速了發(fā)展,尤其是JavaScript引擎。在AJAX技術(shù)問(wèn)世之前,JavaScript引擎只要能夠穩(wěn)定運(yùn)行幾十行JavaScript代碼即可,但是如今Web應(yīng)用的JavaScript代碼已經(jīng)遠(yuǎn)遠(yuǎn)超過(guò)這個(gè)量級(jí),動(dòng)輒幾百上千行。2008年,Google推出了全新的瀏覽器Chrome,搭載代號(hào)為V8的JavaScript引擎。V8引擎采用實(shí)時(shí)編譯(JIT)技術(shù)將JavaScript代碼編譯為機(jī)器碼執(zhí)行,大大提高了JavaScript代碼的運(yùn)行效率。Node.js便是使用V8引擎執(zhí)行JavaScript代碼的。
二、Node.js帶來(lái)的網(wǎng)站制作改革
Node.js并非一個(gè)JavaScript框架,而是一個(gè)集成了Google V8 JavaScript引擎、事件驅(qū)動(dòng)和底層I/0API,并且可使用JavaScript語(yǔ)言開(kāi)發(fā)服務(wù)器端應(yīng)用的運(yùn)行環(huán)境。與PHP不同的是,Node.js可以直接提供網(wǎng)絡(luò)服務(wù),不需要借助Apache、Nginx等專(zhuān)業(yè)的服務(wù)器軟件。雖然并不建議在生產(chǎn)環(huán)境下直接將Node.js服務(wù)暴露給用戶(hù),但是Node.js這種特性可以讓我們更方便地開(kāi)發(fā)各種工具,比如將在后續(xù)章節(jié)中講解的前端工程化方案中本地服務(wù)器的搭建。
1.服務(wù)器端開(kāi)發(fā)
Node.js作為服務(wù)器端平臺(tái)已經(jīng)逐步被國(guó)內(nèi)外公司和團(tuán)隊(duì)接納。2015年10月,著名的開(kāi)源博客系統(tǒng)WordPress發(fā)布了使用Node.js重寫(xiě)的4.3版本。許多企業(yè)(國(guó)內(nèi)的,比如阿里巴巴、美團(tuán)等;國(guó)外的,比如IBM、LinkedIn、GoDaddy等)對(duì)Node.js也均有不同程度的使用。雖然Node.js尚未威脅到PHP、Java等傳統(tǒng)Web服務(wù)器端語(yǔ)言的地位,但Node.js的事件驅(qū)動(dòng)和異步I/0機(jī)制,以及其易學(xué)習(xí)、易部署和對(duì)前端網(wǎng)站制作天然的語(yǔ)言共通性,讓其成為實(shí)時(shí)應(yīng)用、微服務(wù)以及前端工程化等應(yīng)用場(chǎng)景的最佳技術(shù)選型之一。
2.同構(gòu)JavaScript
Node.js在使用JavaScript 語(yǔ)言開(kāi)發(fā)Web服務(wù)器端平臺(tái)的同時(shí),還提高了同構(gòu)JavaScript開(kāi)發(fā)的可行性。
同構(gòu)(isomorphism)一詞是數(shù)學(xué)領(lǐng)域的專(zhuān)業(yè)術(shù)語(yǔ),指的是數(shù)學(xué)對(duì)象之間屬性或者操作關(guān)系的一類(lèi)映射。數(shù)學(xué)中研究同構(gòu)的主要目的是為了把數(shù)學(xué)知識(shí)應(yīng)用于更多不同的領(lǐng)域,同理,在JavaScript開(kāi)發(fā)領(lǐng)域研究同構(gòu)的主要目的也是為了將這門(mén)編程語(yǔ)言應(yīng)用于不同的開(kāi)發(fā)領(lǐng)域。同構(gòu)JavaScript的概念最早由Airbnb工程師Spike Brehm提出,簡(jiǎn)單講就是令JavaScript編寫(xiě)的代碼既可以在瀏覽器端工作,也可以在服務(wù)器端工作,如圖1所示。這意味著服務(wù)器端和瀏覽器端都可以承載網(wǎng)頁(yè)的渲染工作。
圖2
傳統(tǒng)網(wǎng)站的渲染流程是由瀏覽器主動(dòng)發(fā)起請(qǐng)求,然后服務(wù)器端生成HIL文檔后發(fā)送響應(yīng)給瀏覽器,瀏覽器接到響應(yīng)后將HTL文檔渲染為可視網(wǎng)頁(yè)。這是自瀏覽器發(fā)明以來(lái)就沿用至今的渲染流程。這種工作模式的優(yōu)點(diǎn)是節(jié)省客戶(hù)端資源,在客戶(hù)終端設(shè)備以及瀏覽器性能普遍比較落后的情況下能夠保證良好的渲染效果,并且服務(wù)器端渲染的網(wǎng)頁(yè)更利于SEO(Search Engine Optimization,搜索引擎優(yōu)化)。而其缺點(diǎn)是每訪問(wèn)一個(gè)頁(yè)面都要發(fā)起請(qǐng)求,每個(gè)請(qǐng)求都需要服務(wù)器進(jìn)行路由匹配、數(shù)據(jù)庫(kù)查詢(xún)、生成HTML文檔后再發(fā)送響應(yīng)給瀏覽器,這個(gè)過(guò)程會(huì)消耗服務(wù)器的大量計(jì)算資源,如圖3所示。
圖3
隨著個(gè)人終端設(shè)備和瀏覽器性能的不斷提升,Web開(kāi)發(fā)者嘗試將渲染以及路由工作交給客戶(hù)端,服務(wù)器端RESTFulAPI只提供渲染HTML所需的JSON數(shù)據(jù)。這種形態(tài)的Web應(yīng)用被稱(chēng)為SPA(Single Page Application,單頁(yè)應(yīng)用)。SPA有以下優(yōu)點(diǎn)。
·減輕了服務(wù)器的資源消耗。
·與HTL文檔比起來(lái),JSON數(shù)據(jù)的體積小很多,減少了網(wǎng)絡(luò)請(qǐng)求的時(shí)間消耗。
·頁(yè)面路由控制更快速靈活。
·可以離線使用。
同時(shí)SPA也帶來(lái)了新問(wèn)題。首先,瀏覽器需要等待JavaScript文件加載完成之后才可以渲染后續(xù)的HIML文檔內(nèi)容,用戶(hù)在等待的過(guò)程中頁(yè)面是空白的,這就是我們?cè)谶M(jìn)行Web產(chǎn)品性能評(píng)估時(shí)經(jīng)常談到的“白屏?xí)r間”;其次,由于客戶(hù)端和服務(wù)器端編程語(yǔ)言不同,可能會(huì)存在一些諸如數(shù)據(jù)格式的差異,甚至路由邏輯沖突,比如vue-router history模式的路由,這些問(wèn)題增加了維護(hù)難度;最后,SPA不利于常規(guī)的SEO(搜索引擎優(yōu)化)爬蟲(chóng)(之所以說(shuō)常規(guī)是因?yàn)镚oogle已經(jīng)針對(duì)SPA進(jìn)行了SEO優(yōu)化,但是目前國(guó)內(nèi)的搜索引擎對(duì)SPA的支持并不理想)。
與傳統(tǒng)的服務(wù)器端渲染模式和客戶(hù)端渲染的單頁(yè)應(yīng)用相比,同構(gòu)JavaScript擁有更好的性能、可維護(hù)性以及對(duì)SE0更好的支持。同構(gòu)JavaScript的理念類(lèi)似于Java秉承的“Write once,run anywhere”,JavaScript除命名以外終于又跟Java扯上了關(guān)系。Node.js是實(shí)現(xiàn)同構(gòu)JavaScript開(kāi)發(fā)的關(guān)鍵。一方面,JavaScript在瀏覽器環(huán)境下可以執(zhí)行渲染工作;另一方面,Node.js運(yùn)行環(huán)境下同樣可以使用JavaScript創(chuàng)建HTL字符串。在這個(gè)前提下,JavaScript開(kāi)發(fā)生態(tài)中浮現(xiàn)了一大批支持同構(gòu)開(kāi)發(fā)的框架和庫(kù),比如Facebook推出的React.js和國(guó)內(nèi)的Vue.js。
3.前端工具
除了服務(wù)器端開(kāi)發(fā)外,Node.js對(duì)前端最大的貢獻(xiàn)是豐富了前端工具生態(tài)。在Node.js出現(xiàn)以前,沒(méi)有Grunt、Gulp、webpack
等便捷且強(qiáng)大的工具,壓縮合并JavaScript、CSS代碼對(duì)于前端工程師來(lái)說(shuō)是一項(xiàng)非常艱難的任務(wù)。前端工程師不得不使用不熟悉的語(yǔ)言、工具來(lái)處理靜態(tài)文件的壓縮合并。而這些工具往往并不是為了處理靜態(tài)文件的,比如ApacheAnt。使用Ant處理靜態(tài)文件可以說(shuō)是殺雞用了牛刀,而且這把牛刀用來(lái)殺雞還并不好使。除此之外,也可以使用she11腳本完成這項(xiàng)工作,但對(duì)于并不擅長(zhǎng)編寫(xiě)she11腳本的前端工程師來(lái)說(shuō)學(xué)習(xí)成本和時(shí)間成本太高,往往要麻煩團(tuán)隊(duì)中的服務(wù)器端工程師代寫(xiě)。不論哪種選擇,都會(huì)對(duì)項(xiàng)目的開(kāi)發(fā)進(jìn)度產(chǎn)生影響。
Node.js的出現(xiàn)徹底解決了這些問(wèn)題。目前耳熟能詳?shù)那岸?strong>網(wǎng)站制作工具,比如Grunt、Gulp、webpack,無(wú)一不是由Node.js承載的。結(jié)合JavaScript的靈活性與Node.js提供的API,前端工程師可以編寫(xiě)各種工具滿(mǎn)足項(xiàng)目的開(kāi)發(fā)需求。
今天的網(wǎng)頁(yè)制作分享就到這了,如果您喜歡這篇文章,您可以分享給你的朋友!深圳網(wǎng)站建設(shè)-博納網(wǎng)絡(luò)編輯整理。