deno 如何償還 node.js 的十大技術債

根據網絡資料整理前端

「Node如今太難用了!」。Node.js之父 Ryan Dahl 去年初要開發一款 JavaScript 互動式數據分析工具時,忍不住抱怨起本身十年前一手創造的技術。node

Ryan Dahl 想要設計出一款相似 IPython 的互動式數據科學分析命令行工具,但改用 JavaScript 語言,要讓 JavaScript 也能夠像 Python 那樣,進行各式各樣的數據分析、統計計算以及數據視覺化戰士。一度離開 Node.js 開發社區的 Rayn Dahl,再次拿起本身發明的 Node.js 來開發這個新的數據分析工具,可是越用越彆扭,他開始思考,有什麼方法能夠改進 Node.js。npm

Node.js 是他在 2009 年 11 月 8 日時,在 JavaScript 社區歐洲 JSConf 大會上首度發佈的,它把瀏覽器端的 JavaScript 技術,帶入了服務器端應用領域。前端網頁工程師歷來都沒想過,本身也能夠成爲後端工程師,但 Node.js 讓前端技術走出了瀏覽器,前端工程師甚至能夠成爲全端工程師,Node.js 改變了前端工程師的世界。json

從2009年 Ryan Dahl 設計出這個服務器端的 JavaScript 框架,至今已經發展到了第 10 版。而隨 Node.js 而生,另外一位開發者 Isaac 設計出的 JavaScript 包管理工具 npm,更成了網頁開發者必懂得技術,在 npm 的儲存庫上,註冊了超過 60 萬個 Node.js 模塊,這更讓 Node.js 的應用遍佈各種開發或軟件需求。後端

JavaScript是最普及的語言,而Node.js是最受歡迎的框架

根據 Stack OverFlow 在 2018年度的開發者大調查(全球超過 10 萬開發者參與),JavaScript 是開發者中最普及的技術,近 7 成開發者都會用,比 HTML 或 CSS 的普及率還要要高,而最多人懂的開發框架排名中,第一名就是 Node.js ,將近5成開發者(49.6%)常用,比 2017 年還小幅上升了 2 個百分點,同時使用者還在持續增長,遠高於排名第二的 Angular(36.9%),這正是由於 Node.js 是前端和後端工程師都能用的技術。瀏覽器

Node.js 不僅是當前的主流技術,也是下一代網頁應用架構 Serverless(無服務器)架構的關鍵技術。負責 Azure Functions 項目的微軟資深首席軟件工程師 Christopher Anderson 就曾直言,主流無服務器服務商紛紛把寶押在 Node.js,由於看上了 JavaScript 工具的豐富生態,再加上 Node.js 的輕量化、容易分散與水平擴充、各類操做系統都容易運行的特性,將 Node.js 做爲無服務器服務優先支持的框架,這也讓 Node.js 更適合用於超大規模部署的應用。緩存

Ryan Dahl 本身坦言,從沒想到 Node.js 往後會帶來這麼大的影響。他也將此歸功於開發社區的持續改善,才讓它愈來愈成熟。截止到2018年8月,參與 Node.js 的開發者已經超過2千人,十年來的更新發布次數超過 500 次,在 GitHub 上代碼的下載次數更是累計超過了10億次,就連大型科技公司如 PayPal,或頂尖科研機構 NASA 都在使用。安全

但 Ryan Dahl 在 2012 年開始淡出 Node.js 社區,轉而進入 Go、Rust 語言社區,也重回他擅長的數學應用領域,2017 年還申請了 Google 大腦一年的進駐計劃,成爲 Google 大腦研究團隊的一員,擔任深度學習工程師,並投入圖像處理技術的研究。直到 2018 年 6 月初,就在 Node.js 準備邁入第 10 年以前,JSConf 歐洲大會再次邀請Ryan Dahl 來進行開場演講。服務器

儘管大受歡迎,但 Node.js 仍有十大技術債

本來 Ryan Dahl 打算在 2018 年的 JSConf 演講中分享本身這款 JavaScript 版的 IPython 互動式數據分析工具,沒想到一直開發到 5 月份,這個工具都還不能用。原本要放棄此次演講的 Ryan Dahl 念頭一轉,乾脆把他重拾 Node.js 後發現的問題拿出來分享,這就是去年引起全球開發社區熱烈討論的那場演講,題目是 「我在 Node .js 最後悔的 10 件事」。Ryan Dahl 在演講中坦言,Node.js 有十大設計錯誤,甚至可說是他的 10 大悔恨(他刻意用Regret 這個詞來形容)!網絡

這些讓 Ryan Dahl 懊悔不已的錯誤,包括了沒采用 JavaScript 非同步處理的 Promise 對象、低估了安全性的重要性、採用 gyp 來設計 Build 系統、沒有遵從社區建議改用 FFI 而繼續用 gyp,另外,他也以爲 Node.js 過分依賴 npm 功能(內建到 package.json 支持是個錯誤)、用 require("")來嵌入任意模塊簡直太容易了、package.json 容易形成錯誤的模塊觀念(讓開發者誤覺得同一目錄下的文件就是同一模塊)、臃腫複雜的node_module設計以及開發社區抱怨已久的下載黑洞問題(下載npm得花上很是久的等待時間)、require("module")功能沒有強制要求註名.js擴展名,以及無用的 index.js 設計。

2012年,Ryan Dahl 離開了Node.js社區,他過後解釋,Node.js 的發展已經步入正軌,也達到他最初的目標,於是決定離開,但在2018年這場演講中,他坦言, Node.js 還有大把問題要修復,因此如今他回來了,要來償還當年的技術債,挽回 Node.js 的設計錯誤。

Ryan Dahl 的答案是打造一個全新的服務器端 JavaScript 運行環境,也就是 Deno 項目。

Deno從2018年5月在 Github 開源至今年3月,已有超過100名開發者參與,常常貢獻代碼的核心開發者也有5名。

讓Ryan Dahl懊悔不已的 Node.js 十大技術債

  1. 沒用 JavaScript 異步處理的 Promise 對象

  2. 低估了安全的重要性

  3. 使用了 gyp 來設計 Build 系統

  4. 沒有聽你們的建議提供 FFI 而繼續用 gyp

  5. 過分依賴 npm(內建 package.json支持)

  6. 太容易形成 require("任意模塊")

  7. package.json 創建了錯誤的模塊概念(在同一目錄下的文件就是同一模塊)

  8. 臃腫複雜的 node_module 設計和下載黑洞(每每下載 npm 得花上很是久的時間)

  9. require("module") 時沒有強制加上 .js 擴展名

  10. 無用的 index.js 設計。

Deno 如何挽回 Node.js 設計上遺留的問題

這是 Deno 項目的一個範例,是 Unix 系統基本命令 cat 的一個實現。cat 能夠從標準輸入取得文件, 再逐行把文件內容送出到標準輸出上。這個範例反映出 Deno 要將 I/O 抽象化和精簡化的意圖。

這是 Deno 項目的一個範例,是 Unix 系統基本命令 cat 的一個實現。cat 能夠從標準輸入取得文件, 再逐行把文件內容送出到標準輸出上。這個範例反映出 Deno 要將 I/O 抽象化和精簡化的意圖。

Ryan Dahl 但願經過打造 Deno 這個全新的服務器端 JavaScript 運行環境,來解決 Node.js 的三大問題,包括準確的 I/O 接口、預設安全性(Secure by Default)以及引進一套去中心化的模塊系統等,最後一項就是要解決下載太久過慢的老問題。

Ryan Dahl 進一步解釋,雖然他全部的時間都是用 C++、Go 或 Rust 這類編譯式語言來開發,可是他仍是有一些常常要作的事,須要使用動態的腳本程序。例如整理資料、協調測試任務、部署服務器或用戶端環境、繪製統計圖表、設定構建系統(Build System)的參數或是設計應用雛形等。

但是,這些不一樣用途的任務,須要切換使用多種不一樣的腳本語言或工具,如 Bash、Python 或是 Node.js 等才行,至關麻煩。而 2018 年上半年的這個互動式數據分析工具的開發挫折,更讓他有一股強烈地念頭,能不能有一個通用的腳本工具。

Deno

Deno 架構

打造一款簡單、好用的通用腳本工具

Ryan Dahl 在 2018 年 11 月參加臺灣年度 JavaScript 開發者大會(JSDC)時,特別提到:「我不喜歡用不一樣工具來處理不一樣的事情,我只想要有一個簡單,直接可執行,拿了就能用的順手工具,這正是打造Deno的初衷。」

簡單來講,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 編譯器。

Deno的目標是安全、簡潔、單一可執行文件

Deno的設計目標是安全、模塊簡潔、單一可執行文件(簡化封裝)等,目前已完成的特點之一,就是能夠透過URL 來匯入各類模塊,另外預設安全性,要存取實體資源或網絡時都須要受權,用戶的代碼只能在安全的沙箱中執行。爲何他最熟悉的 Go 作不到?由於「動態語言仍有其必要。「他強調,尤爲要創建一個適當好用的 I/O 處理流程(pipeline)時,動態腳本語言是不可或缺的工具。

而 JavaScript 就是那個他心中的理想動態語言,可是,Node.js 是一項將近 10 年曆史的技術,受限於最初的設計架構,他認爲,能夠從新用 JavaScript 近幾年出現的特性,從新思考 Node. js 的根本設計,包括像是可存取原始內存的標準方法 ArrayBuffers、適合彈性組合的 TypeScript Interfaces,以及新興的非同步機制 Async 和 Await。Ryan Dahl 把這些新的 JavaScipt 功能,放入了 Deno 中,來設計一款新的服務器端 JavaScript 框架。

可是,這一次,他不想重走 Node.js 的老路,將整個 Web 服務器放進框架,Ryan Dahl 決定打造出一支自給自足功能完整的 runtime 程序,容易帶着走,而不是有着一套複雜目錄和結構的框架。

並且,打包成 runtime 形式,就能夠部署到各類環境中,Ryan Dahl 舉例,若是在無服務器服務上部署了Deno,就可指定一個網址,就能啓動這個無服務器服務的調用,而不用上傳一段代碼到無服務器服務平臺上執行,也能夠部署到邊緣運算設備中,來完成小型的數據處理工做。

不信任使用者的代碼,只能在沙箱執行

另外在安全機制上,Deno 設計了兩層權限架構,一個是擁有特權的核心層,另外一個是沒有特權的用戶空間,RyanDahl 解釋到,這就像是操做系統的設計同樣,不信任使用者的代碼,區分出使用者的權限和系統核心的權限等級,使用者的程序,要向使用到關鍵的資源,必須透過系統調用,由系統核心程序來執行。Deno 也是同樣,「不信任用戶端的 JavaScript 程序,只能在安全的沙箱中執行。」

全部涉及到敏感資源的處理,如底層文件系統,都須要受權執行,這就是預設安全性的設計,包括網絡存取、文件系統寫入、環境變量存取、執行等這些敏感的動做,都須要取得受權才能執行。

另外,Deno 的設計還將 I/O 處理抽象化,讓 JavaScript 程序沒必要處理各類不一樣的輸出或輸入端配置,改由 runtime 接手,從而沒法直接接觸實體資源。一來簡化各類不一樣的 I/O 存取方式,不管是本地或遠 I/O,都是一樣的 read 和 write 指令就能夠搞定,二來也能夠強化安全性。

另外,Deno 還借鑑了很多 Go 語言的特性,例如 Deno 的 copy() 就參考了 Go 語言的 io.Copy()BufReader() 也參考了 Go 語言的 bufio.Reader 設計等,還有很多測試機制、文件等,Ryan Dahl 也都參考了他熟悉的Go語言。

指定URL,就能嵌入第三方函數庫

Deno 第三項設計目標是要打造一個去中心化的模塊系統,Ryan Dahl 的設計是,Deno 能夠像 JavaScript 同樣,經過 URL 網址來嵌入外部的第三方函數庫。除此以外,Deno和Rust語言也有很多整合,甚至改用Rust來實做Deno以後,Ryan Dahl透露,將會創建一個橋接機制,讓Deno能夠很容易地運用Rust中的函數庫。

不過他坦言,嵌入外部的第三方函數庫的機制,也是 Deno 項目發佈後,人們詢問最多、也最擔憂的功能,擔憂透過 URL 來引入外部函數庫後,容易引起安全問題或是中間人攻擊等問題。「這就是爲何 Deno 要採起預設安全性的設計的緣由,來隔絕來自外部第三方代碼的威脅。」

另外,經過 URL 連結到第三方函數庫時,Deno 會經過緩存,在本地環境生成一份第三方函數庫,第二次再調用到一樣的URL時就不需再次下載了,以此來加快執行速度。甚至這個經過外部 URL 來引用函數庫的功能,還能夠指定版本,就算是改版了,仍是能夠指向舊版。固然 Ryan Dahl 強調,全部存取外部網絡或下載寫入到本地文件的動做,都須要取得受權才能執行。

將來會支持 WebGL,Deno 就能調用 GPU 資源

Deno 還有一個與 Node.js 最大的差別,就是將來會支持機器學習。Ryan Dahl 透露,他們正在開發一個數值計算類的外掛模塊,最重要的就是要能支持 GPU,這也是機器學習模塊最須要的功能。「Deno將來將會原生支持 WebGL,就可讓 JavaScipt 程序調用 GPU 的資源。這是他打造 Deno 的目標之一。」甚至,Ryan Dahl 預告,將來說不定能夠把 TensorFlow JS 放上 Deno 來執行,由於 TensorFlow JS 用的也是 WebGL。

Deno將來將瞄準小型機器學習的推理需求

不一樣於 Nvidia的CUDA 能夠用來調度多顆 GPU 資源進行復雜的機器學習訓練工做,Ryan Dahl 解釋,Deno 想要提供的是簡單夠用的機器學習能力,能夠用來知足只有單顆 GPU,並且是小型或是隻須要推理的計算需求,支持WebGL 已經夠用了。

Deno 從 2018 年 5 月中放上 Github 網站開源至今年3月,已有超過80名開發者參與,常常貢獻代碼的核心開發者也有 5 名。目前正把主要精力放在在預設安全性架構的設計功能上。

最後企業能不能用 Deno?Ryan Dahl 坦言 Deno 距離 1.0 還有很長一段路要走,仍舊是一個很是新的技術。不過,「再等我1年,如有企業想用,請Email給我,我會提供技術支持。」 他認真地說。

關於Ryan Dahl

2009年11月8日,Node. js之 父RyanDahl在歐洲 JSConf 大會,第一次發佈了 Node.js ,一舉成名,將瀏覽器端的 JavaScript 技術,帶入了服務器端應用領域。不過他從 2012 年開始淡出 Node.js 社區,轉而進入Go、Rust語言社區,2017年加入 Google 大腦研究團隊,擔任深度學習工程師。現爲自由開發者。

2018年6月初,Ryan Dahl 在 JSConf 歐洲大會發表了 Node.js 十大悔恨,並推出了新的服務器端 JavaScript runtime 方案 Deno。

歡迎關注京程一燈公衆號:jingchengyideng,獲取更多前端乾貨。

相關文章
相關標籤/搜索