Deno 如何償還 Node.js 的十大技術債?

cpongo 5test\12發表於2019-03-21
\u003cp\u003e本文轉載自京程一燈公眾號。\u003c/p\u003e\n\u003cp\u003e“Node現在太難用了!”。Node.js之父 Ryan Dahl 去年初要開發一款 JavaScript 互動式資料分析工具時,忍不住抱怨起自己十年前一手創造的技術。\u003c/p\u003e\n\u003cp\u003eRyan Dahl 想要設計出一款類似 IPython 的互動式資料科學分析命令列工具,但改用 JavaScript 語言,要讓 JavaScript 也可以像 Python 那樣,進行各式各樣的資料分析、統計計算以及資料視覺化戰士。一度離開 Node.js 開發社群的 Rayn Dahl,再次拿起自己發明的 Node.js 來開發這個新的資料分析工具,但是越用越彆扭,他開始思考,有什麼方法可以改進 Node.js。\u003c/p\u003e\n\u003cp\u003eNode.js 是他在 2009 年 11 月 8 日時,在 JavaScript 社群歐洲 JSConf 大會上首度釋出的,它把瀏覽器端的 JavaScript 技術,帶入了伺服器端應用領域。前端網頁工程師從來都沒想過,自己也可以成為後端工程師,但 Node.js 讓前端技術走出了瀏覽器,前端工程師甚至可以成為全端工程師,Node.js 改變了前端工程師的世界。\u003c/p\u003e\n\u003cp\u003e從2009年Ryan Dahl 設計出這個伺服器端的 JavaScript 框架,至今已經發展到了第 10 版。而隨 Node.js 而生,另一位開發者 Isaac 設計出的 JavaScript 包管理工具 npm,更成了網頁開發者必懂得技術,在 npm 的儲存庫上,註冊了超過 60 萬個 Node.js 模組,這更讓 Node.js 的應用遍及各類開發或軟體需求。\u003c/p\u003e\n\u003ch3\u003eJS是最普及的語言,而Node.js是最受歡迎的框架\u003c/h3\u003e\n\u003cp\u003e根據 Stack OverFlow 在 2018年度的開發者大調查(全球超過 10 萬開發者參與),JavaScript 是開發者中最普及的技術,近 7 成開發者都會用,比 HTML 或 CSS 的普及率還要要高,而最多人懂的開發框架排名中,第一名就是 Node.js ,將近5成開發者(49.6%)經常使用,比 2017 年還小幅上升了 2 個百分點,同時使用者還在持續增加,遠高於排名第二的 Angular(36.9%),這正是因為 Node.js 是前端和後端工程師都能用的技術。\u003c/p\u003e\n\u003cp\u003eNode.js 不只是當前的主流技術,也是下一代網頁應用架構 Serverless(無伺服器)架構的關鍵技術。負責 Azure Functions 專案的微軟資深首席軟體工程師 Christopher Anderson 就曾直言,主流無伺服器服務商紛紛把寶押在 Node.js,因為看上了 JavaScript 工具的豐富生態,再加上 Node.js 的輕量化、容易分散與水平擴充、各種作業系統都容易執行的特性,將 Node.js 作為無伺服器服務優先支援的框架,這也讓 Node.js 更適合用於超大規模部署的應用。\u003c/p\u003e\n\u003cp\u003eRyan Dahl 自己坦言,從沒想到 Node.js 日後會帶來這麼大的影響。他也將此歸功於開發社群的持續改善,才讓它越來越成熟。截止到2018年8月,參與 Node.js 的開發者已經超過2千人,十年來的更新發布次數超過 500 次,在 GitHub 上程式碼的下載次數更是累計超過了10億次,就連大型科技公司如 PayPal,或頂尖科研機構 NASA 都在使用。\u003c/p\u003e\n\u003cp\u003e但 Ryan Dahl 在 2012 年開始淡出 Node.js 社群,轉而進入 Go、Rust 語言社群,也重回他擅長的數學應用領域,2017 年還申請了 Google 大腦一年的進駐計劃,成為 Google 大腦研究團隊的一員,擔任深度學習工程師,並投入影像處理技術的研究。直到 2018 年 6 月初,就在 Node.js 準備邁入第 10 年之前,JSConf 歐洲大會再次邀請Ryan Dahl 來進行開場演講。\u003c/p\u003e\n\u003ch3\u003e儘管大受歡迎,但 Node.js 仍有十大技術債\u003c/h3\u003e\n\u003cp\u003e原本 Ryan Dahl 打算在 2018 年的 JSConf 演講中分享自己這款 JavaScript 版的 IPython 互動式資料分析工具,沒想到一直開發到 5 月份,這個工具都還不能用。本來要放棄這次演講的 Ryan Dahl 念頭一轉,乾脆把他重拾 Node.js 後發現的問題拿出來分享,這就是去年引發全球開發社群熱烈討論的那場演講,題目是 “我在 Node .js 最後悔的 10 件事”。Ryan Dahl 在演講中坦言,Node.js 有十大設計錯誤,甚至可說是他的 10 大悔恨(他刻意用Regret 這個詞來形容)!\u003c/p\u003e\n\u003cp\u003e這些讓 Ryan Dahl 懊悔不已的錯誤,包括了沒采用 JavaScript 非同步處理的 Promise 物件、低估了安全性的重要性、採用 gyp 來設計 Build 系統、沒有聽從社群建議改用 FFI 而繼續用 gyp,另外,他也覺得 Node.js 過度依賴 npm 功能(內建到 package.json 支援是個錯誤)、用 require(\u0026quot;\u0026quot;)來嵌入任意模組簡直太容易了、package.json 容易造成錯誤的模組觀念(讓開發者誤以為同一目錄下的檔案就是同一模組)、臃腫複雜的node_module設計以及開發社群抱怨已久的下載黑洞問題(下載npm得花上非常久的等待時間)、require(“module”)功能沒有強制要求註名.js副檔名,以及無用的 index.js 設計。\u003c/p\u003e\n\u003cp\u003e2012年,Ryan Dahl 離開了Node.js社群,他事後解釋,Node.js 的發展已經步入正軌,也達到他最初的目標,因而決定離開,但在2018年這場演講中,他坦言, Node.js 還有大把問題要修復,所以現在他回來了,要來償還當年的技術債,挽回 Node.js 的設計錯誤。\u003c/p\u003e\n\u003cp\u003eRyan Dahl 的答案是打造一個全新的伺服器端 JavaScript 執行環境,也就是 Deno 專案。\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://static.geekbang.org/infoq/5c93316542469.png\" alt=\"\" /\u003e\u003c/p\u003e\n\u003ch3\u003e讓Ryan Dahl懊悔不已的Node.js十大技術債\u003c/h3\u003e\n\u003cp\u003e1.沒用 JavaScript 非同步處理的 Promise 物件\u003c/p\u003e\n\u003cp\u003e2.低估了安全的重要性\u003c/p\u003e\n\u003cp\u003e3.使用了 gyp 來設計 Build 系統\u003c/p\u003e\n\u003cp\u003e4.沒有聽大家的建議提供 FFI 而繼續用 gyp\u003c/p\u003e\n\u003cp\u003e5.過度依賴 npm(內建 package.json支援)\u003c/p\u003e\n\u003cp\u003e6.太容易造成 require(“任意模組”)\u003c/p\u003e\n\u003cp\u003e7.package.json 建立了錯誤的模組概念(在同一目錄下的檔案就是同一模組)\u003c/p\u003e\n\u003cp\u003e8.臃腫複雜的 node_module 設計和下載黑洞(往往下載 npm 得花上非常久的時間)\u003c/p\u003e\n\u003cp\u003e9.require(“module”) 時沒有強制加上 .js 副檔名\u003c/p\u003e\n\u003cp\u003e10.無用的 index.js 設計。\u003c/p\u003e\n\u003ch3\u003eDeno 如何挽回 Node.js 設計上遺留的問題\u003c/h3\u003e\n\u003cp\u003e\u003cimg src=\"https://static.geekbang.org/infoq/5c9331f560839.png\" alt=\"\" /\u003e\u003c/p\u003e\n\u003cp\u003e這是 Deno 專案的一個範例,是 Unix 系統基本命令 cat 的一個實現。cat 可以從標準輸入取得檔案, 再逐行把檔案內容送出到標準輸出上。這個範例反映出 Deno 要將 I/O 抽象化和精簡化的意圖。\u003c/p\u003e\n\u003cp\u003eRyan Dahl 希望通過打造 Deno 這個全新的伺服器端 JavaScript 執行環境,來解決 Node.js 的三大問題,包括準確的 I/O 介面、預設安全性(Secure by Default)以及引進一套去中心化的模組系統等,最後一項就是要解決下載過久過慢的老問題。\u003c/p\u003e\n\u003cp\u003eRyan Dahl 進一步解釋,雖然他所有的時間都是用 C++、Go 或 Rust 這類編譯式語言來開發,但是他還是有一些經常要做的事,需要使用動態的指令碼程式。例如整理資料、協調測試任務、部署伺服器或使用者端環境、繪製統計圖表、設定構建系統(Build System)的引數或是設計應用雛形等。\u003c/p\u003e\n\u003cp\u003e可是,這些不同用途的任務,需要切換使用多種不同的指令碼語言或工具,如 Bash、Python 或是 Node.js 等才行,相當麻煩。而 2018 年上半年的這個互動式資料分析工具的開發挫折,更讓他有一股強烈地念頭,能不能有一個通用的指令碼工具。\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://static.geekbang.org/infoq/5c93322babb0f.png\" alt=\"\" /\u003e\u003c/p\u003e\n\u003cp\u003eDeno 架構\u003c/p\u003e\n\u003ch3\u003e打造一款簡單、好用的通用指令碼工具\u003c/h3\u003e\n\u003cp\u003eRyan Dahl 在 2018 年 11 月參加臺灣年度 JavaScript 開發者大會(JSDC)時,特別提到:“我不喜歡用不同工具來處理不同的事情,我只想要有一個簡單,直接可執行,拿了就能用的順手工具,這正是打造Deno的初衷。”\u003c/p\u003e\n\u003cp\u003e簡單來說,Deno 跟 Node.js 一樣都採用了 Chrome 的 JavaScript 引擎 V8,但 Deno 採用了更嚴格的 JavaScript 語法規範 TypeScript,Deno 等於是一個 TypeScript runtime。第一個版本的 Deno runtime 是用 Go 語言實現的,但是 Ryan Dahl 又重新用 Rust 語言開發了一次 Deno 的 runtime,避免因為重複使用兩套垃圾回收器(Go語言一套、V8引擎也內建了一套)而影響效能。另外,Deno runtime 中也內建了 TypeScript 編譯器。\u003c/p\u003e\n\u003ch3\u003eDeno的目標是安全、簡潔、單一可執行檔案\u003c/h3\u003e\n\u003cp\u003eDeno的設計目標是安全、模組簡潔、單一可執行檔案(簡化封裝)等,目前已完成的特色之一,就是可以透過URL 來匯入各種模組,另外預設安全性,要存取實體資源或網路時都需要授權,使用者的程式碼只能在安全的沙箱中執行。為什麼他最熟悉的 Go 做不到?因為“動態語言仍有其必要。“他強調,尤其要建立一個適當好用的 I/O 處理流程(pipeline)時,動態指令碼語言是不可或缺的工具。\u003c/p\u003e\n\u003cp\u003e而 JavaScript 就是那個他心中的理想動態語言,但是,Node.js 是一項將近 10 年曆史的技術,受限於最初的設計架構,他認為,可以重新用 JavaScript 近幾年出現的特性,重新思考 Node. js 的根本設計,包括像是可存取原始記憶體的標準方法 ArrayBuffers、適合彈性組合的 TypeScript Interfaces,以及新興的非同步機制 Async 和 Await。Ryan Dahl 把這些新的 JavaScipt 功能,放入了 Deno 中,來設計一款新的伺服器端 JavaScript 框架。\u003c/p\u003e\n\u003cp\u003e但是,這一次,他不想重走 Node.js 的老路,將整個 Web 伺服器放進框架,Ryan Dahl 決定打造出一支自給自足功能完整的 runtime 程式,容易帶著走,而不是有著一套複雜目錄和結構的框架。\u003c/p\u003e\n\u003cp\u003e而且,打包成 runtime 形式,就可以部署到各種環境中,Ryan Dahl 舉例,如果在無伺服器服務上部署了Deno,就可指定一個網址,就能啟動這個無伺服器服務的呼叫,而不用上傳一段程式碼到無伺服器服務平臺上執行,也可以部署到邊緣運算裝置中,來完成小型的資料處理工作。\u003c/p\u003e\n\u003ch3\u003e不信任使用者的程式碼,只能在沙箱執行\u003c/h3\u003e\n\u003cp\u003e另外在安全機制上,Deno 設計了兩層許可權架構,一個是擁有特權的核心層,另一個是沒有特權的使用者空間,RyanDahl 解釋到,這就像是作業系統的設計一樣,不信任使用者的程式碼,區分出使用者的許可權和系統核心的許可權等級,使用者的程式,要向使用到關鍵的資源,必須透過系統呼叫,由系統核心程式來執行。Deno 也是一樣,“不信任使用者端的 JavaScript 程式,只能在安全的沙箱中執行。”\u003c/p\u003e\n\u003cp\u003e所有涉及到敏感資源的處理,如底層檔案系統,都需要授權執行,這就是預設安全性的設計,包括網路存取、檔案系統寫入、環境變數存取、執行等這些敏感的動作,都需要取得授權才能執行。\u003c/p\u003e\n\u003cp\u003e另外,Deno 的設計還將 I/O 處理抽象化,讓 JavaScript 程式不必處理各種不同的輸出或輸入端配置,改由 runtime 接手,從而無法直接接觸實體資源。一來簡化各種不同的 I/O 存取方式,不論是本地或遠 I/O,都是同樣的 read 和 write 指令就可以搞定,二來也可以強化安全性。\u003c/p\u003e\n\u003cp\u003e另外,Deno 還借鑑了不少 Go 語言的特性,例如 Deno 的 copy() 就參考了 Go 語言的 io.Copy(), BufReader() 也參考了 Go 語言的 bufio.Reader 設計等,還有不少測試機制、檔案等,Ryan Dahl 也都參考了他熟悉的Go語言。\u003c/p\u003e\n\u003ch3\u003e指定URL,就能嵌入第三方函式庫\u003c/h3\u003e\n\u003cp\u003eDeno 第三項設計目標是要打造一個去中心化的模組系統,Ryan Dahl 的設計是,Deno 可以像 JavaScript 一樣,通過 URL 網址來嵌入外部的第三方函式庫。除此之外,Deno和Rust語言也有不少整合,甚至改用Rust來實作Deno之後,Ryan Dahl透露,將會建立一個橋接機制,讓Deno可以很容易地運用Rust中的函式庫。\u003c/p\u003e\n\u003cp\u003e不過他坦言,嵌入外部的第三方函式庫的機制,也是 Deno 專案釋出後,人們詢問最多、也最擔心的功能,擔心透過 URL 來引入外部函式庫後,容易引發安全問題或是中間人攻擊等問題。“這就是為什麼 Deno 要採取預設安全性的設計的原因,來隔絕來自外部第三方程式碼的威脅。”\u003c/p\u003e\n\u003cp\u003e另外,通過 URL 連結到第三方函式庫時,Deno 會通過快取,在本地環境生成一份第三方函式庫,第二次再呼叫到同樣的URL時就不需再次下載了,以此來加快執行速度。甚至這個通過外部 URL 來引用函式庫的功能,還可以指定版本,就算是改版了,還是可以指向舊版。當然 Ryan Dahl 強調,所有存取外部網路或下載寫入到本地檔案的動作,都需要取得授權才能執行。\u003c/p\u003e\n\u003ch3\u003e未來會支援 WebGL,Deno 就能呼叫 GPU 資源\u003c/h3\u003e\n\u003cp\u003eDeno 還有一個與 Node.js 最大的差異,就是未來會支援機器學習。Ryan Dahl 透露,他們正在開發一個數值計算類的外掛模組,最重要的就是要能支援 GPU,這也是機器學習模組最需要的功能。“Deno未來將會原生支援 WebGL,就可以讓 JavaScipt 程式呼叫 GPU 的資源。這是他打造 Deno 的目標之一。”甚至,Ryan Dahl 預告,未來說不定可以把 TensorFlow JS 放上 Deno 來執行,因為 TensorFlow JS 用的也是 WebGL。\u003c/p\u003e\n\u003ch3\u003eDeno未來將瞄準小型機器學習的推理需求\u003c/h3\u003e\n\u003cp\u003e不同於 Nvidia的CUDA 可以用來排程多顆 GPU 資源進行復雜的機器學習訓練工作,Ryan Dahl 解釋,Deno 想要提供的是簡單夠用的機器學習能力,可以用來滿足只有單顆 GPU,而且是小型或是隻需要推理的計算需求,支援WebGL 已經夠用了。\u003c/p\u003e\n\u003cp\u003eDeno 從 2018 年 5 月中放上 Github 網站開源至今年3月,已有超過80名開發者參與,經常貢獻程式碼的核心開發者也有 5 名。目前正把主要精力放在在預設安全性架構的設計功能上。\u003c/p\u003e\n\u003cp\u003e最後企業能不能用 Deno?Ryan Dahl 坦言 Deno 距離 1.0 還有很長一段路要走,仍舊是一個非常新的技術。不過,“再等我1年,若有企業想用,請Email給我,我會提供技術支援。” 他認真地說。\u003c/p\u003e\n\u003ch3\u003e關於Ryan Dahl\u003c/h3\u003e\n\u003cp\u003e2009年11月8日,Node. js之 父RyanDahl在歐洲 JSConf 大會,第一次釋出了 Node.js ,一鳴驚人,將瀏覽器端的 JavaScript 技術,帶入了伺服器端應用領域。不過他從 2012 年開始淡出 Node.js 社群,轉而進入Go、Rust語言社群,2017年加入 Google 大腦研究團隊,擔任深度學習工程師。現為自由開發者。\u003c/p\u003e\n\u003cp\u003e2018年6月初,Ryan Dahl 在 JSConf 歐洲大會發表了 Node.js 十大悔恨,並推出了新的伺服器端 JavaScript runtime 方案 Deno。\u003c/p\u003e\n\u003cp\u003e推薦閱讀:\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==\u0026amp;mid=2247488986\u0026amp;idx=1\u0026amp;sn=7f03d4a056096fffa826e2b619e39836\u0026amp;chksm=f951a099ce26298f8372277785c472cd25558e516cc38175f0c141e70c6604a29ec9b33fef96\u0026amp;scene=27#wechat_redirect\"\u003eNode之父ry釋出新專案deno:下一代Node\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==\u0026amp;mid=2247489010\u0026amp;idx=1\u0026amp;sn=a1332dcda4643caba3f5347fc6f47382\u0026amp;chksm=f951a0b1ce2629a747f7c5fa8fc801c6d6924b0c8dd727d1e4e15b971436754a2e1b68c3e194\u0026amp;scene=27#wechat_redirect\"\u003eNode之父ry:Node中的設計錯誤\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e更多內容,請關注前端之巔。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e會議推薦\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e2019年6月,GMTC全球大前端技術大會2019即將到來。小程式、Flutter、移動AI、工程化、效能優化…大前端的下一站在哪裡?點選下圖瞭解更多詳情。\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://gmtc.geekbang.org/?utm_source=infoq\u0026amp;utm_medium=bottombanner\"\u003e\u003cimg src=\"https://static.geekbang.org/infoq/5c8868e093844.png?imageView2/0/w\" alt=\"\" /\u003e\u003c/a\u003e\u003c/p\u003e\n

相關文章