前端科普系列(2):Node.js 换个角度看世界,
【前端科普系列】往期精彩內(nèi)容:
前端科普系列(1):很有趣的一篇前端簡(jiǎn)史,作者有心了~主要介紹 web 前端發(fā)展的歷史、大事件。
本文為系列文章(2),主要介紹 Node.js 的前世今生、核心科技以及背后的故事。
必須提一下作者:vivo?孔垂亮
一、關(guān)于 Node.js
?
1.Node.js 是什么
?
Node.js? is a JavaScript runtime built on Chrome's V8 JavaScript engine.
?
按照?Node.js官網(wǎng)的解釋非常簡(jiǎn)單:
Node.js? 是一個(gè)基于 Chrome V8 引擎 的 JavaScript 運(yùn)行時(shí)。
?
那我們?cè)撛趺蠢斫膺@句話呢?
-
Node.js 不是 JavaScript 的應(yīng)用、也不是一種框架、更不是一門語言。它是一個(gè) JavaScript 的運(yùn)行環(huán)境,就和瀏覽器是一個(gè) JavaScript 運(yùn)行環(huán)境一樣。
-
它是構(gòu)建在 Chrome’s V8 這個(gè)著名的 JavaScript 引擎之上的。
?
這里不得不聊聊 Chrome & V8。
?
2.Node.js 誕生的背景
?
2008年,Google開發(fā)了Google地圖,但Google地圖那時(shí)是安卓的原生應(yīng)用。為了進(jìn)一步擴(kuò)展Google?地圖的服務(wù)范圍,Google?針對(duì)瀏覽器開發(fā)了瀏覽器版本的Google?地圖。而這對(duì)瀏覽器的處理能力提出來更高的要求,于是當(dāng)時(shí)的產(chǎn)品經(jīng)理?Sundar Pichai?極力說服當(dāng)時(shí)的董事會(huì),要求開發(fā)一款瀏覽器(也就是現(xiàn)在的Chrome)。
?
當(dāng)時(shí)的瀏覽器市場(chǎng)還是微軟的,因?yàn)椴僮飨到y(tǒng)內(nèi)置IE,讓IE幾乎占據(jù)整個(gè)江山,并且IE是免費(fèi)的,所以當(dāng)時(shí)要開發(fā)一款瀏覽器遭到了董事會(huì)極力反對(duì)。
?
Sundar Pichai 強(qiáng)調(diào)價(jià)值不在瀏覽器本身,而在于它能訪問的內(nèi)容:也就是網(wǎng)絡(luò)應(yīng)用程序。當(dāng)時(shí)最賣錢的產(chǎn)品,像 Google 文檔。Google 地圖 如果想吸引更多的用戶使用,并從其中的廣告銷售牟利,就必須徹底地提高瀏覽器的性能,最終他說服了董事會(huì),把開發(fā)瀏覽器立了項(xiàng)。
?
隨之而來的就是如何提高瀏覽器性能的問題?當(dāng)時(shí)項(xiàng)目組認(rèn)識(shí)到,開發(fā)者不太愿意使用 JavaScript 是因?yàn)樗跒g覽器中運(yùn)行得太慢了,和傳統(tǒng)語言不是一個(gè)量級(jí)的。
?
恰在此時(shí),Lars Bak 出現(xiàn)了。這位 Google Chrome 背后的天才,早在1991年就在硅谷引起了人們的注意,后來成為業(yè)界最優(yōu)秀的程序員之一。可是在2000年初,他選擇離開硅谷,回到他的祖國(guó)丹麥過幸福的生活,他覺得硅谷的開發(fā)者工作太緊張,生活方式不健康。Lars Bak 回到丹麥后,賺了足夠的錢養(yǎng)家糊口,就租了一大片農(nóng)場(chǎng),開始粉刷農(nóng)舍。
?
然后就接到了 Sundar Pichai 的電話。Lars Bak 說 他并不在乎當(dāng)什么高級(jí)經(jīng)理,他想要做的就是打破技術(shù)的邊界,于是他接受了 Google 的 offer,但并沒有回到硅谷,而是在他自己的農(nóng)場(chǎng)里就開始了工作。
?
2008年9月2日,V8 與 Chrome 在同一天宣布開源。世界以非同尋常的方式發(fā)現(xiàn)了 Chrome。Chrome 是通過Google?早前發(fā)布的漫畫冊(cè)傳出去的。公關(guān)忙成一團(tuán)來回應(yīng)這個(gè)消息,匆匆忙忙地舉行了電話會(huì)議,發(fā)表博客日志解釋到底發(fā)生了什么,隨后決定開新聞發(fā)布會(huì),最后在Googleplex舉辦產(chǎn)品展示。
?
看過發(fā)布會(huì)的同學(xué)可能會(huì)留意到,當(dāng)時(shí)非常倉促,連一個(gè)精美的PPT都沒有。
?
(圖片來源于網(wǎng)絡(luò))
?
漫畫中明確提到了將 V8 嵌入到非瀏覽器項(xiàng)目中的可能性。
?
3.Node.js 的誕生
?
談到 Node.js 的誕生,不可避免的要聊到它的創(chuàng)始人 —— Node.js 之父 Ryan Dahl。Ryan Dahl 在開發(fā) Node.js 之前是高性能Web服務(wù)的開發(fā)專家,在幫客戶解決性能問題的同時(shí),碰到了Web服務(wù)的高并發(fā)帶來的性能問題,他嘗試過很多語言,都失敗了。經(jīng)過多年的研究,Ryan Dahl 大致的感覺到了解決問題的關(guān)鍵是通過事件驅(qū)動(dòng)和異步I/O來達(dá)成目的。
?
就在他快要絕望的時(shí)候,V8 隨著 Chrome 瀏覽器的問世而出現(xiàn),JavaScript 腳本語言的執(zhí)行效率得到質(zhì)的提升,這給 Ryan Dahl 帶來新的啟示:JavaScript 本身就是單線程的,而且瀏覽器發(fā)起的 AJAX 請(qǐng)求就是非阻塞的。如果將 JavaScript 和異步 IO 以及一個(gè)簡(jiǎn)單的 HTTP 服務(wù)器集合在一起,就會(huì)變成一個(gè)很酷的東西。他原本的研究就這樣與 V8 之間碰撞出火花,V8 滿足他關(guān)于高性能 Web 服務(wù)的所有想象:
?
沒有歷史包袱,沒有同步 I/O。不會(huì)出現(xiàn)一個(gè)同步 I/O 導(dǎo)致事件循環(huán)性能急劇降低的情況。
V8 性能足夠好,遠(yuǎn)遠(yuǎn)比 Python、Ruby 等其他腳本語言的引擎要快。
JavaScript 語言的閉包特性非常方便,比 C 中的回調(diào)函數(shù)好用。
?
于是在 2009 年的 2 月,按新的想法他提交了項(xiàng)目的第一行代碼,這個(gè)項(xiàng)目的名字最終被定名為"node"。
?
2009 年 5 月,Ryan Dahl 正式向外界宣布他做的這個(gè)項(xiàng)目。
?
2009 年底,Ryan Dahl 在柏林舉行的 JSConf EU 會(huì)議上發(fā)表關(guān)于 Node.js 的演講,之后 Node.js 逐漸流行于世。
?
總得來說,Node.js 并不是憑空誕生的,它的出現(xiàn)要?dú)w功于 Ryan Dahl 歷時(shí)多年的研究,以及一個(gè)恰到好處的節(jié)點(diǎn)。
?
二、Node.js 現(xiàn)狀
?
2018 年 5 月 31 日,Node.js 基金會(huì)發(fā)布的用戶調(diào)查報(bào)告,顯示學(xué)習(xí) Node.js 看起來更容易了,少于 2 年 node 經(jīng)驗(yàn)的用戶中,有 43% 的覺得“容易”。絕大多數(shù)(85%)Node.js 用戶用于網(wǎng)頁開發(fā),43% 參與一些企業(yè)級(jí)開發(fā),13% 用于大數(shù)據(jù)分析,8% 用于嵌入式系統(tǒng)。
?
用戶調(diào)查報(bào)告中還顯示,受訪的使用者會(huì)用如下的詞語來描述 Node.js。
?
?
(圖片來源于網(wǎng)絡(luò))
?
更為重要的是,報(bào)告顯示 Node.js 社區(qū)仍然在快速成長(zhǎng)。而這得益于 Node.js 的應(yīng)用場(chǎng)景非常廣泛.
?
?
越來越多的開發(fā)者開始轉(zhuǎn)向 Node.js ,幾乎每個(gè)公司/小組都會(huì)有自己的命令行工具、腳手架。使用 Node.js 能夠快速開發(fā)各式各樣的能極大提高開發(fā)效率的神器。
?
三、Node.js 核心科技
?
Node.js 采用事件驅(qū)動(dòng)、異步編程,為網(wǎng)絡(luò)服務(wù)而設(shè)計(jì)。
?
在前面我們聊 Node.js 誕生的時(shí)候,就提過 Node.js 之父 Ryan Dahl 在設(shè)計(jì) Node.js 時(shí)就是為了解決 web 服務(wù)高并發(fā)帶來的性能問題,而這個(gè)問題隨著 V8 的出現(xiàn)而迎刃而解。
?
如下圖,當(dāng)網(wǎng)絡(luò)請(qǐng)求發(fā)生時(shí),如果有文件或者數(shù)據(jù)庫操作,Node.js 會(huì)注冊(cè)一個(gè)回調(diào)函數(shù),然后就去處理下一個(gè)請(qǐng)求了。當(dāng)之前文件或者數(shù)據(jù)庫操作完成后,觸發(fā)之前注冊(cè)的事件回調(diào),進(jìn)而響應(yīng)之前的網(wǎng)絡(luò)請(qǐng)求。
?
?
由于整個(gè)設(shè)計(jì)都是以事件驅(qū)動(dòng)為核心的,它的重要優(yōu)勢(shì)在于,充分利用了系統(tǒng)資源,執(zhí)行代碼無須阻塞等待某種操作完成,有限的資源可以用于其他的任務(wù)。
?
之后的很長(zhǎng)一段時(shí)間,Ryan Dahl 四處發(fā)表演講,試圖說服人們相信阻塞式 IO 是錯(cuò)誤的方式,如果使用非阻塞的方式來處理所有的事情,那么就可以解決很多難點(diǎn)。
?
關(guān)于事件驅(qū)動(dòng)編程,可以參考我的一篇知乎文章:《JavaScript運(yùn)行機(jī)制:事件驅(qū)動(dòng)編程詳解》
?
Node.js 的性能不錯(cuò)。
?
前面提到的用戶調(diào)查報(bào)告中顯示,用戶評(píng)價(jià) Node.js 最多的就是 Fast ,對(duì),就是快!
?
按照 Ryan Dahl 的說法,性能是 Node.js 考慮的重要因素,選擇 C++ 和 V8 而不是別的也是基于性能的考慮。
?
Node.js 在設(shè)計(jì)上比較大膽,它以單進(jìn)程、單線程模式運(yùn)行(和 Javascript 的運(yùn)行方式一致),事件驅(qū)動(dòng)機(jī)制是 Node.js 通過內(nèi)部單線程高效地維護(hù)事件循環(huán)隊(duì)列來實(shí)現(xiàn)的,沒有多線程的資源占用和上下文切換,這意味著面對(duì)大規(guī)模的 http 請(qǐng)求,Node.js 憑借事件驅(qū)動(dòng)搞定一切。由此我們可以知道這樣的設(shè)計(jì)會(huì)導(dǎo)致負(fù)載的壓力集中在 CPU 而不是內(nèi)存。所以 Node.js 特別適合 IO 密集型的應(yīng)用,能夠充分發(fā)揮 CPU 的威力。
?
Node.js 支持 JavaScript。
?
這是 Node.js 能夠發(fā)展壯大的一個(gè)非常重要的間接原因。
-
首先,Javascript 作為前端工程師的主力語言,在技術(shù)社區(qū)中有相當(dāng)?shù)奶?hào)召力。而且,隨著 Web 技術(shù)的不斷發(fā)展,特別是前端的重要性增加,不少前端工程師開始試水”后臺(tái)應(yīng)用“,在許多采用 Node.js 的企業(yè)中,工程師都表示因?yàn)榱?xí)慣了 Javascript,所以選擇 Node.js。
-
其次,Javascript 的匿名函數(shù)和閉包特性非常適合事件驅(qū)動(dòng)、異步編程。
-
有 Google V8 引擎的加持,Node.js 的性能也是受益其中。
?
當(dāng)然事件驅(qū)動(dòng)、異步編程也不是沒有它的弊端,當(dāng)都寫成回調(diào)函數(shù)的形勢(shì)后,會(huì)有違正常人的思維,剛開始會(huì)特別不習(xí)慣,并且回調(diào)太多,容易產(chǎn)生回調(diào)地獄,當(dāng)然后面的 Promise、Async、Await 都致力于解決這個(gè)問題。
?
四、Node.js 背后的那些人那些事
?
Node.js 誕生后,就吸引了一群有趣的人參與 Node.js 早期的開發(fā),他們一開始就發(fā)現(xiàn)軟件包管理在 Node.js 里將會(huì)非常有用武之地,于是他們開始各自開發(fā)包管理工具。其中有一個(gè)癡迷于 Node.js 的 Yahoo 員工 Isaac Schlueter,他辭掉工作,開始專心開發(fā)包管理工具(就是現(xiàn)在的 npm ),他曾經(jīng)深度參與過 Nodejs 的開發(fā),這使得他可以在 Node.js 中實(shí)現(xiàn) CommonJS 的模塊規(guī)范。
?
這款包管理工具足夠優(yōu)秀,得到了 Node 官方的大力支持,它贏了。這款包管理工具,或者說 npm,開始和 Node 安裝包捆綁打包,它可不是一個(gè)單獨(dú)的第三方插件,不需要你裝完 Node 再去下載包管理工具。這塊 Node 官方認(rèn)證的金字招牌一直掛到今天。
?
也就是在這個(gè)時(shí)候(2010, Node.js 誕生的第二年),一家位于硅谷的創(chuàng)業(yè)公司注意到了該項(xiàng)目。這家公司就是 Joyent,主要從事云計(jì)算和數(shù)據(jù)分析等。Joyent 意識(shí)到 Node.js 項(xiàng)目的價(jià)值,Joyent 用很少一筆錢從 Ryan Dahl 手中買走了 Node.js。
?
Ryan Dahl 就以區(qū)區(qū)幾萬美元,把 Node.js 包括源碼在內(nèi)的所有一股腦賣給 Joyent。數(shù)百萬人每天用 Node.js 作為 JavaScript 開發(fā)的工具,而發(fā)明 Node.js 的人只用它賺了幾萬美元。
?
之后,Ryan Dahl 就加入 Joyent ,全職負(fù)責(zé) Node.js 的開發(fā),也就是從此刻起,Node.js 進(jìn)入了它生命歷程里的第二個(gè)階段:從個(gè)人項(xiàng)目變成一個(gè)公司組織下的項(xiàng)目。Joyent 注冊(cè)了“Node.js”這個(gè)商標(biāo),使用其相關(guān)內(nèi)容需要得到法律授權(quán)。
?
與此同時(shí),npm 的作者 Isaac Schlueter 被 Joyent 聘來開發(fā) Node.js,但他保留了 npmjs.org 域名、npm 源碼以及源碼中的任何專利的所有權(quán),這些都是他自己的知識(shí)產(chǎn)權(quán)。這個(gè)決定會(huì)對(duì)后世產(chǎn)生深遠(yuǎn)影響……
?
在加入 Joyent 成為全職的 Node 開發(fā)人員之后,Ryan Dahl 也隨之成為更加重量級(jí)的人物。參加各種大會(huì),被粉絲要求合影拍照,隨便寫點(diǎn)東西都會(huì)有很多人響應(yīng)。但 Ryan 并不喜歡這種狀態(tài),他說:"我是一個(gè)程序員,我想寫代碼,我想無拘無束地表達(dá)我的想法。我并不喜歡這種狀態(tài)……"。
?
2012 年,就在 Node.js 如日中天的時(shí)候,Ryan Dahl 選擇離開了 Node.js。npm 的作者 Isaac Schlueter 接替他登上了項(xiàng)目組的領(lǐng)導(dǎo)崗位。就是在這個(gè)時(shí)候,JavaScript 開發(fā)者們紛紛登場(chǎng)了,能用 JavaScript 實(shí)現(xiàn)某個(gè)工具,他們絕對(duì)不會(huì)看其他語言一眼!因此他們開始用 Javascript 開發(fā) Node 程序,并且樂在其中。
?
Isaac Schlueter 親眼目睹過 Joyent 給 Ryan Dahl 出的價(jià)格是多么低廉,也知道 Node.js 的價(jià)值到底應(yīng)該值多少錢。于是在 2013 年,他決定讓 npm 走商業(yè)化路線,因此他向 Joyent 遞交了辭呈,成立了一家公司 —— npm 公司。也就是從這個(gè)時(shí)候開始,Node.js 出現(xiàn)了很嚴(yán)重的問題:貢獻(xiàn)頻率開始下降,代碼提交主要來自社區(qū),代碼的版本下降到三個(gè)月才能發(fā)布一個(gè)小版本,社區(qū)一直期待的 1.0 版本遲遲不能發(fā)布。另外還發(fā)生了人稱代詞事件?致使 Node.js 項(xiàng)目的活躍度更低,Joyent 對(duì)于項(xiàng)目的不作為和其他層面對(duì)社區(qū)其他成員的干預(yù),導(dǎo)致項(xiàng)目進(jìn)展十分緩慢,用蝸牛的速度來形容一點(diǎn)也不為過。
?
2014 年 8 月,以社區(qū)里非常有威望的 Mikeal Rogers 為首,幾個(gè)重要的核心貢獻(xiàn)者,發(fā)起了 io.js 項(xiàng)目,宣告了 Node.js 社區(qū)的正式分裂。io.js 不再是之前的技術(shù)負(fù)責(zé)人模式,取而代之的是技術(shù)委員會(huì)模式。io.js 于 2015-01-14 發(fā)布了 v1.0.0 版本。自此 io.js 一發(fā)不可收拾,以周為單位發(fā)布新的版本,在架構(gòu)層面依然保持著 Node.js 的樣子(由 Ryan Dahl 時(shí)確立)但是對(duì)于 ECMAScript 6 持擁抱態(tài)度,又重新保持了周為單位的版本更新頻率。
?
與此同時(shí),Joyent 也意識(shí)到了問題,成立了臨時(shí)的 Node.js 顧問委員會(huì),想借助顧問委員會(huì)的形式來打造一個(gè)更加開放的管理模式,以找到辦法來平衡所有成員的需要,為各方提供一個(gè)平臺(tái)來投入資源到 Node.js 項(xiàng)目。顧問委員會(huì)調(diào)研了 IBM(Eclipse)、Linux 基金會(huì)、Apache 等,決定成立 Node.js 基金會(huì)的形式。
?
到了 2015 年 5 月,Node.js 顧問委員會(huì)最終決定與 io.js 進(jìn)行和解,共同制定一個(gè)新的管理模式來確保 Node.js 的下一步發(fā)展, Joyent 公司本著開放的原則,在這件事情上也做出很大的讓步。但此時(shí),io.js 已經(jīng)發(fā)了 2.0 版本,Node.js 遠(yuǎn)遠(yuǎn)落后于 io.js ,最終的解決方案是 Node.js 項(xiàng)目和 io.js 項(xiàng)目都將加入 Node.js 基金會(huì),Node.js 基金會(huì)之后 Node.js 版本的發(fā)布將基于目前 io.js 的進(jìn)展來進(jìn)行,也就是說 io.js 會(huì)繼續(xù)保持發(fā)布,而 Node.js 的下個(gè)大版本跨過 1.0、2.0、3.0,直接到 4.0。如下圖所示:
然后,npm 也做大做強(qiáng)了,讓 Node.js 的普及率爆炸性增長(zhǎng)。所有 JavaScript 開發(fā)者都開始用 Node.js 做開發(fā),而 npm 則成為每個(gè) JavaScript 開發(fā)者日常工作中不可或缺的一部分。可很少有人知道 npm 是一家企業(yè),是一個(gè)由風(fēng)投資金贊助的私人公司。
?
npm 的經(jīng)營(yíng)策略由一個(gè)公司來掌舵,其含義是什么?在去年的這個(gè)大會(huì)上,Node.js 之父 Ryan Dahl 再次登臺(tái)演講。他談到了 Node.js 的設(shè)計(jì)誤區(qū)。其中說了一句話:
?
模塊倉庫的中心化(甚至由私人所控制)是一種不幸。—— Ryan Dahl
?
2016年初, npm 圈發(fā)生了“一個(gè) 11 行的模塊引發(fā)的血案”。left-pad 工具模塊被作者從 npm 上撤下,所有直接或者間接依賴這個(gè)模塊的 npm 包就憂傷的掛掉了,包括 babel 這樣的熱門項(xiàng)目。
?
而其中的原因大概是這樣:作者 Azer 寫了一個(gè)叫 kik 的工具和某個(gè)公司同名了,這天公司的律師要求其刪掉這個(gè)模塊,把 kik 這個(gè)名字“讓”給他們,作者不答應(yīng),律師就直接找 npm 了,而 npm 未經(jīng)作者同意就把包的權(quán)限轉(zhuǎn)移給了這家公司。于是,Azer 一怒沖冠,將他所有的 npm 包全部刪掉了。
?
下一節(jié),聊聊 Commonjs 以及 前端模塊化規(guī)范……
?
參考文獻(xiàn)
?
-
如何正確的學(xué)習(xí)Node.js
-
Lars Bak:Google Chrome瀏覽器背后的天才
-
Node.js 與 io.js 那些事兒
-
深入淺出 Node.js(一):什么是 Node.js
-
NPM的經(jīng)濟(jì)風(fēng)云(上)
-
從 left-pad 事件我們可以學(xué)到什么
-
Node 之父 Ryan Dahl:我不想被定義
-
2018 Node.js 用戶調(diào)查報(bào)告顯示社區(qū)仍然在快速成長(zhǎng)
總結(jié)
以上是生活随笔為你收集整理的前端科普系列(2):Node.js 换个角度看世界,的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里文娱测试开发专家谈《算法基石:实时数
- 下一篇: 如何使用 一行代码 搞定一组数据的(极值