天天看點

前端科普系列(2):Node.js 換個角度看世界

主要介紹了Node的前世今生、核心科技以及背後的故事。

本文首發于 vivo網際網路技術 微信公衆号 

連結: https://mp.weixin.qq.com/s/fPNMaeNYgU3eJsh0SLMRRg

作者:孔垂亮

【前端科普系列】往期精彩内容:

《前端科普系列(1):前端簡史》主要介紹 web 前端發展的曆史、大事件。

本文為系列文章(2),主要介紹 Node.js 的前世今生、核心科技以及背後的故事。

一、關于 Node.js

1.Node.js 是什麼

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

按照 Node.js官網的解釋非常簡單:

Node.js® 是一個基于 Chrome V8 引擎 的 JavaScript 運作時。

那我們該怎麼了解這句話呢?

  • Node.js 不是 JavaScript 的應用、也不是一種架構、更不是一門語言。它是一個 JavaScript 的運作環境,就和浏覽器是一個 JavaScript 運作環境一樣。
  • 它是建構在 Chrome’s V8 這個著名的 JavaScript 引擎之上的。

這裡不得不聊聊 Chrome & V8。

2.Node.js 誕生的背景

2008年,Google開發了Google地圖,但Google地圖那時是安卓的原生應用。為了進一步擴充Google 地圖的服務範圍,Google 針對浏覽器開發了浏覽器版本的Google 地圖。而這對浏覽器的處理能力提出來更高的要求,于是當時的産品經理 Sundar Pichai 極力說服當時的董事會,要求開發一款浏覽器(也就是現在的Chrome)。

當時的浏覽器市場還是微軟的,因為作業系統内置IE,讓IE幾乎占據整個江山,并且IE是免費的,是以當時要開發一款浏覽器遭到了董事會極力反對。

Sundar Pichai 強調價值不在浏覽器本身,而在于它能通路的内容:也就是網絡應用程式。當時最賣錢的産品,像 Google 文檔。Google 地圖 如果想吸引更多的使用者使用,并從其中的廣告銷售牟利,就必須徹底地提高浏覽器的性能,最終他說服了董事會,把開發浏覽器立了項。

随之而來的就是如何提高浏覽器性能的問題?當時項目組認識到,開發者不太願意使用 JavaScript 是因為它在浏覽器中運作得太慢了,和傳統語言不是一個量級的。

恰在此時,Lars Bak 出現了。這位 Google Chrome 背後的天才,早在1991年就在矽谷引起了人們的注意,後來成為業界最優秀的程式員之一。可是在2000年初,他選擇離開矽谷,回到他的祖國丹麥過幸福的生活,他覺得矽谷的開發者工作太緊張,生活方式不健康。Lars Bak 回到丹麥後,賺了足夠的錢養家糊口,就租了一大片農場,開始粉刷農舍。

然後就接到了 Sundar Pichai 的電話。Lars Bak 說 他并不在乎當什麼進階經理,他想要做的就是打破技術的邊界,于是他接受了 Google 的 offer,但并沒有回到矽谷,而是在他自己的農場裡就開始了工作。

2008年9月2日,V8 與 Chrome 在同一天宣布開源。世界以非同尋常的方式發現了 Chrome。Chrome 是通過Google 早前釋出的漫畫冊傳出去的。公關忙成一團來回應這個消息,匆匆忙忙地舉行了電話會議,發表部落格日志解釋到底發生了什麼,随後決定開新聞釋出會,最後在Googleplex舉辦産品展示。

看過釋出會的同學可能會留意到,當時非常倉促,連一個精美的PPT都沒有。
前端科普系列(2):Node.js 換個角度看世界

(圖檔來源于網絡)

漫畫中明确提到了将 V8 嵌入到非浏覽器項目中的可能性。

3.Node.js 的誕生

談到 Node.js 的誕生,不可避免的要聊到它的創始人 —— Node.js 之父 Ryan Dahl。Ryan Dahl 在開發 Node.js 之前是高性能Web服務的開發專家,在幫客戶解決性能問題的同時,碰到了Web服務的高并發帶來的性能問題,他嘗試過很多語言,都失敗了。經過多年的研究,Ryan Dahl 大緻的感覺到了解決問題的關鍵是通過事件驅動和異步I/O來達成目的。

就在他快要絕望的時候,V8 随着 Chrome 浏覽器的問世而出現,JavaScript 腳本語言的執行效率得到質的提升,這給 Ryan Dahl 帶來新的啟示:JavaScript 本身就是單線程的,而且浏覽器發起的 AJAX 請求就是非阻塞的。如果将 JavaScript 和異步 IO 以及一個簡單的 HTTP 伺服器集合在一起,就會變成一個很酷的東西。他原本的研究就這樣與 V8 之間碰撞出火花,V8 滿足他關于高性能 Web 服務的所有想象:

  1. 沒有曆史包袱,沒有同步 I/O。不會出現一個同步 I/O 導緻事件循環性能急劇降低的情況。
  2. V8 性能足夠好,遠遠比 Python、Ruby 等其他腳本語言的引擎要快。
  3. JavaScript 語言的閉包特性非常友善,比 C 中的回調函數好用。

于是在 2009 年的 2 月,按新的想法他送出了項目的第一行代碼,這個項目的名字最終被定名為"node"。

2009 年 5 月,Ryan Dahl 正式向外界宣布他做的這個項目。

2009 年底,Ryan Dahl 在柏林舉行的 JSConf EU 會議上發表關于 Node.js 的演講,之後 Node.js 逐漸流行于世。

總得來說,Node.js 并不是憑空誕生的,它的出現要歸功于 Ryan Dahl 曆時多年的研究,以及一個恰到好處的節點。

二、Node.js 現狀

2018 年 5 月 31 日,Node.js 基金會釋出的使用者調查報告,顯示學習 Node.js 看起來更容易了,少于 2 年 node 經驗的使用者中,有 43% 的覺得“容易”。絕大多數(85%)Node.js 使用者用于網頁開發,43% 參與一些企業級開發,13% 用于大資料分析,8% 用于嵌入式系統。

使用者調查報告中還顯示,受訪的使用者會用如下的詞語來描述 Node.js。

前端科普系列(2):Node.js 換個角度看世界
前端科普系列(2):Node.js 換個角度看世界

更為重要的是,報告顯示 Node.js 社群仍然在快速成長。而這得益于 Node.js 的應用場景非常廣泛.

前端科普系列(2):Node.js 換個角度看世界
前端科普系列(2):Node.js 換個角度看世界

越來越多的開發者開始轉向 Node.js ,幾乎每個公司/小組都會有自己的指令行工具、腳手架。使用 Node.js 能夠快速開發各式各樣的能極大提高開發效率的神器。

三、Node.js 核心科技

Node.js 采用事件驅動、異步程式設計,為網絡服務而設計。

在前面我們聊 Node.js 誕生的時候,就提過 Node.js 之父 Ryan Dahl 在設計 Node.js 時就是為了解決 web 服務高并發帶來的性能問題,而這個問題随着 V8 的出現而迎刃而解。

如下圖,當網絡請求發生時,如果有檔案或者資料庫操作,Node.js 會注冊一個回調函數,然後就去處理下一個請求了。當之前檔案或者資料庫操作完成後,觸發之前注冊的事件回調,進而響應之前的網絡請求。

前端科普系列(2):Node.js 換個角度看世界
前端科普系列(2):Node.js 換個角度看世界

由于整個設計都是以事件驅動為核心的,它的重要優勢在于,充分利用了系統資源,執行代碼無須阻塞等待某種操作完成,有限的資源可以用于其他的任務。

之後的很長一段時間,Ryan Dahl 四處發表演講,試圖說服人們相信阻塞式 IO 是錯誤的方式,如果使用非阻塞的方式來處理所有的事情,那麼就可以解決很多難點。

關于事件驅動程式設計,可以參考我的一篇知乎文章:《JavaScript運作機制:事件驅動程式設計詳解》

Node.js 的性能不錯。

前面提到的使用者調查報告中顯示,使用者評價 Node.js 最多的就是 Fast ,對,就是快!

按照 Ryan Dahl 的說法,性能是 Node.js 考慮的重要因素,選擇 C++ 和 V8 而不是别的也是基于性能的考慮。

Node.js 在設計上比較大膽,它以單程序、單線程模式運作(和 Javascript 的運作方式一緻),事件驅動機制是 Node.js 通過内部單線程高效地維護事件循環隊列來實作的,沒有多線程的資源占用和上下文切換,這意味着面對大規模的 http 請求,Node.js 憑借事件驅動搞定一切。由此我們可以知道這樣的設計會導緻負載的壓力集中在 CPU 而不是記憶體。是以 Node.js 特别适合 IO 密集型的應用,能夠充分發揮 CPU 的威力。

Node.js 支援 JavaScript。

這是 Node.js 能夠發展壯大的一個非常重要的間接原因。

  • 首先,Javascript 作為前端工程師的主力語言,在技術社群中有相當的号召力。而且,随着 Web 技術的不斷發展,特别是前端的重要性增加,不少前端工程師開始試水”背景應用“,在許多采用 Node.js 的企業中,工程師都表示因為習慣了 Javascript,是以選擇 Node.js。
  • 其次,Javascript 的匿名函數和閉包特性非常适合事件驅動、異步程式設計。
  • 有 Google V8 引擎的加持,Node.js 的性能也是受益其中。
當然事件驅動、異步程式設計也不是沒有它的弊端,當都寫成回調函數的形勢後,會有違正常人的思維,剛開始會特别不習慣,并且回調太多,容易産生回調地獄,當然後面的 Promise、Async、Await 都緻力于解決這個問題。

四、Node.js 背後的那些人那些事

Node.js 誕生後,就吸引了一群有趣的人參與 Node.js 早期的開發,他們一開始就發現軟體包管理在 Node.js 裡将會非常有用武之地,于是他們開始各自開發包管理工具。其中有一個癡迷于 Node.js 的 Yahoo 員工 Isaac Schlueter,他辭掉工作,開始專心開發包管理工具(就是現在的 npm ),他曾經深度參與過 Nodejs 的開發,這使得他可以在 Node.js 中實作 CommonJS 的子產品規範。

這款包管理工具足夠優秀,得到了 Node 官方的大力支援,它赢了。這款包管理工具,或者說 npm,開始和 Node 安裝包捆綁打包,它可不是一個單獨的第三方插件,不需要你裝完 Node 再去下載下傳包管理工具。這塊 Node 官方認證的金字招牌一直挂到今天。

也就是在這個時候(2010, Node.js 誕生的第二年),一家位于矽谷的創業公司注意到了該項目。這家公司就是 Joyent,主要從事雲計算和資料分析等。Joyent 意識到 Node.js 項目的價值,Joyent 用很少一筆錢從 Ryan Dahl 手中買走了 Node.js。

Ryan Dahl 就以區區幾萬美元,把 Node.js 包括源碼在内的所有一股腦賣給 Joyent。數百萬人每天用 Node.js 作為 JavaScript 開發的工具,而發明 Node.js 的人隻用它賺了幾萬美元。

之後,Ryan Dahl 就加入 Joyent ,全職負責 Node.js 的開發,也就是從此刻起,Node.js 進入了它生命曆程裡的第二個階段:從個人項目變成一個公司組織下的項目。Joyent 注冊了“Node.js”這個商标,使用其相關内容需要得到法律授權。

與此同時,npm 的作者 Isaac Schlueter 被 Joyent 聘來開發 Node.js,但他保留了 npmjs.org 域名、npm 源碼以及源碼中的任何專利的所有權,這些都是他自己的知識産權。這個決定會對後世産生深遠影響……

在加入 Joyent 成為全職的 Node 開發人員之後,Ryan Dahl 也随之成為更加重量級的人物。參加各種大會,被粉絲要求合影拍照,随便寫點東西都會有很多人響應。但 Ryan 并不喜歡這種狀态,他說:"我是一個程式員,我想寫代碼,我想無拘無束地表達我的想法。我并不喜歡這種狀态……"。

2012 年,就在 Node.js 如日中天的時候,Ryan Dahl 選擇離開了 Node.js。npm 的作者 Isaac Schlueter 接替他登上了項目組的上司崗位。就是在這個時候,JavaScript 開發者們紛紛登場了,能用 JavaScript 實作某個工具,他們絕對不會看其他語言一眼!是以他們開始用 Javascript 開發 Node 程式,并且樂在其中。

Isaac Schlueter 親眼目睹過 Joyent 給 Ryan Dahl 出的價格是多麼低廉,也知道 Node.js 的價值到底應該值多少錢。于是在 2013 年,他決定讓 npm 走商業化路線,是以他向 Joyent 遞交了辭呈,成立了一家公司 —— npm 公司。也就是從這個時候開始,Node.js 出現了很嚴重的問題:貢獻頻率開始下降,代碼送出主要來自社群,代碼的版本下降到三個月才能釋出一個小版本,社群一直期待的 1.0 版本遲遲不能釋出。另外還發生了人稱代詞事件 緻使 Node.js 項目的活躍度更低,Joyent 對于項目的不作為和其他層面對社群其他成員的幹預,導緻項目進展十分緩慢,用蝸牛的速度來形容一點也不為過。

2014 年 8 月,以社群裡非常有威望的 Mikeal Rogers 為首,幾個重要的核心貢獻者,發起了 io.js 項目,宣告了 Node.js 社群的正式分裂。io.js 不再是之前的技術負責人模式,取而代之的是技術委員會模式。io.js 于 2015-01-14 釋出了 v1.0.0 版本。自此 io.js 一發不可收拾,以周為機關釋出新的版本,在架構層面依然保持着 Node.js 的樣子(由 Ryan Dahl 時确立)但是對于 ECMAScript 6 持擁抱态度,又重新保持了周為機關的版本更新頻率。

與此同時,Joyent 也意識到了問題,成立了臨時的 Node.js 顧問委員會,想借助顧問委員會的形式來打造一個更加開放的管理模式,以找到辦法來平衡所有成員的需要,為各方提供一個平台來投入資源到 Node.js 項目。顧問委員會調研了 IBM(Eclipse)、Linux 基金會、Apache 等,決定成立 Node.js 基金會的形式。

到了 2015 年 5 月,Node.js 顧問委員會最終決定與 io.js 進行和解,共同制定一個新的管理模式來確定 Node.js 的下一步發展, Joyent 公司本着開放的原則,在這件事情上也做出很大的讓步。但此時,io.js 已經發了 2.0 版本,Node.js 遠遠落後于 io.js ,最終的解決方案是 Node.js 項目和 io.js 項目都将加入 Node.js 基金會,Node.js 基金會之後 Node.js 版本的釋出将基于目前 io.js 的進展來進行,也就是說 io.js 會繼續保持釋出,而 Node.js 的下個大版本跨過 1.0、2.0、3.0,直接到 4.0。如下圖所示:

前端科普系列(2):Node.js 換個角度看世界

然後,npm 也做大做強了,讓 Node.js 的普及率爆炸性增長。所有 JavaScript 開發者都開始用 Node.js 做開發,而 npm 則成為每個 JavaScript 開發者日常工作中不可或缺的一部分。可很少有人知道 npm 是一家企業,是一個由風投資金贊助的私人公司。

npm 的經營政策由一個公司來掌舵,其含義是什麼?在去年的這個大會上,Node.js 之父 Ryan Dahl 再次登台演講。他談到了 Node.js 的設計誤區。其中說了一句話:

子產品倉庫的中心化(甚至由私人所控制)是一種不幸。—— Ryan Dahl

2016年初, npm 圈發生了“一個 11 行的子產品引發的xue案”。left-pad 工具子產品被作者從 npm 上撤下,所有直接或者間接依賴這個子產品的 npm 包就憂傷的挂掉了,包括 babel 這樣的熱門項目。

而其中的原因大概是這樣:作者 Azer 寫了一個叫 kik 的工具和某個公司同名了,這天公司的律師要求其删掉這個子產品,把 kik 這個名字“讓”給他們,作者不答應,律師就直接找 npm 了,而 npm 未經作者同意就把包的權限轉移給了這家公司。于是,Azer 一怒沖冠,将他所有的 npm 包全部删掉了。

下一節,聊聊 Commonjs 以及 前端子產品化規範……

參考文獻

  • 如何正确的學習Node.js
  • Lars Bak:Google Chrome浏覽器背後的天才
  • Node.js 與 io.js 那些事兒
  • 深入淺出 Node.js(一):什麼是 Node.js
  • NPM的經濟風雲(上)
  • 從 left-pad 事件我們可以學到什麼
  • Node 之父 Ryan Dahl:我不想被定義
  • 2018 Node.js 使用者調查報告顯示社群仍然在快速成長

更多内容敬請關注 vivo 網際網路技術 微信公衆号

前端科普系列(2):Node.js 換個角度看世界

注:轉載文章請先與微信号:labs2020 聯系。

分享 vivo 網際網路技術幹貨與沙龍活動,推薦最新行業動态與熱門會議。