Node之父重構的Deno終於釋出了,它終究會取代Node嗎?

手撕紅黑樹發表於2020-05-15

Node之父是誰?


沒錯!就是這個叫Ryan Dahl的男人在2009年創造了Node。你看,其實也不是說大神就都沒頭髮,這位大神毛髮不是挺旺盛的嘛!
不過既然是在2009年締造的Node,那麼就不得不吐槽那時候的JS了。在2009年的JavaScript啥樣大家都知道(好像貌似那時候的程式設計師畢竟少),ES5.0(不成熟的ES5)在09年年底才剛剛釋出,而ES5.1(我們們現在用的ES5)在2011年6月才開始釋出併成為ISO國際標準。

想象一下即使現在有了ES6 ~ ES2020這麼新的版本,JS依然經常被大家拿來吐槽,更別提那個ES5都沒普及的年代了。
在那時候既沒有合適的非同步方式也沒有模組化,也沒有什麼包管理啥的。那麼這樣的JS寫大型專案或服務端專案簡直就是一場災難,於是乎就產生了各種模組化方案(Node採用了CommonJS),也有了npm、node_modules等各種歷史遺留問題。
一方面是當年的Ryan Dahl技術沒有現在好,思想也沒有現在這麼全面、另一方面當年的JS本來就很坑,用它創造出來的東西肯定不會很完美的。

但是如今的JS越來越發展壯大,雖然現在還是很坑,不過比起以前的JS來說簡直強百倍。不僅有了自己的模組化,還有了Promise、Proxy、Bigint、塊級作用域等一系列非常實用的特性、而且還有更好的TypeScript來為JavaScript負重前行。而Node的歷史包袱實在太重,即使想支援一下標準的模組化都不得不把.js變成.mjs以保持相容。

Deno起因

Node之父並沒有一直在維護Node,他後來離開了NodeJS加入了谷歌,在谷歌他研究的主要方向就是機器學習裡面的影像著色和超解像技術。雖然取得了一定的成就,但是Ryan Dahl認為現在的機器學習還很簡單,離真正的人工智慧還有著十萬八千里。但是這並不妨礙人們去提升機器學習的技術,因為他相信,總有一天,人工智慧會變得越來越完善。

提到機器學習和人工智慧就不得不提python,Node他爸始終不是很喜歡Python,久而久之,就想搞一個JavaScript的人工智慧開發框架(以後前端可能還得再學個人工智慧)。等到他再回過頭撿起Node.js,發現這個專案已經背離了他的初衷,有一些無法忽視的問題。

這些啥破玩意?那個又是些什麼鬼?原來,他覺得當初自己建立Node時失誤實在是太多了,他甚至還在2018年得JS開發者會上列出了自己設計NodeJS的十個錯誤:

  • 沒有堅持使用Promise
  • 沒有注重安全性
  • 沒有從GYP構建系統轉到GN
  • 繼續使用GYP,沒有提供FFI
  • package.json以及依賴了npm
  • 在任何地方都可以require(”somemodule“)
  • package.json 提供了錯誤的module概念
  • 設計了軟體界黑洞node_modules
  • require("module")可以不寫.js
  • index.js

為了彌補這些錯誤,他研發了一個新的專案,用來解決他的十個痛點(其實遠遠不止十個),這個專案就是Deno。

Deno的技術

Node的底層依賴的是C++,那Deno一樣嗎?

答案是否定,一部分程式設計師可能還記得Deno一開始依賴的是Go語言,這曾經在GoLang社群掀起了不小的波瀾。
但是好景不長,後來換成了Rust。然後好多人藉機黑Go吹Rust了一番。

至於為什麼換成Rust,Ryan Dahl說是因為不想同時存在兩個GC(Go和TS)

Deno的名字

細心的朋友可能會發現deno這四個字母就是node的四個字母兩兩顛倒了一下:

  • de + no = Deno
  • no + de = Node

顛倒Node字母的寓意是要顛覆Node嗎?

其實也差不多,它的意思是:Destroy Node (毀滅Node!

看來Ryan Dahl對他的Deno很有信心,我是希望它能真的幹掉Node的,因為它的優點實在是太過於突出啦!

那麼接下來我們就來看一看Deno的優勢都有哪些:

Deno的優勢

內建tsc引擎,可以直接執行ts程式碼(還是要先編譯成JS)。這就不用你每次編寫完ts程式碼還要去手動去編譯了,而且也不用再去搭建什麼ts-node之類的了,方便你我他。它的內部會根據檔案字尾名判斷,如果是.ts字尾名,就先呼叫TS編譯器,將其編譯成 JavaScript;如果是.js字尾名,就直接傳入 V8 引擎執行。

由於是用Rust語言開發的,Rust原生支援 WebAssembly,所以它也能直接執行WebAssembly。它的非同步操作不使用libuv這個庫,而是使用Rust的Tokio庫來實現event loop。

那麼為什麼不像Node一樣用C++而是選擇用Rust呢?主要是因為Rust提供了很多現成的模組,對於Deno來說,可以節約很多開發時間。也許是看到了Rust提供了很多現成模組,Deno也決定在自己的專案中新增許多現成模組。

Deno具有安全控制,預設情況下指令碼不具有讀寫許可權。如果指令碼未授權,就讀寫檔案系統或網路,會報錯。想要讀寫檔案系統的話必須使用要引數,顯式開啟許可權才可以。Ryan在總結Node的十個錯誤時曾說:V8引擎本身有很好的sandbox架構,但是有時候Node本身卻沒有好好利用,例如有可以直接讀取Memory的例子,或者linter可以直接使用網路功能等的漏洞。從npm下載了一個包就任由他執行了,這其中存在著很大的安全隱患。

Deno 支援 Web API,儘量跟瀏覽器保持一致。它提供 window 這個全域性物件,同時支援 fetch、webCrypto、worker 等 Web 標準,也支援 onload、onunload、addEventListener 等事件操作函式。不像Node,Web API和Node的API不一致只會增加開發者的學習成本。以後window全域性物件就可以不僅僅只侷限於瀏覽器環境啦!

Deno只支援ES模組,跟瀏覽器的模組載入規則一致。既沒有npm,也沒有npm_modules這個無底洞,同時不支援CommonJS模組,也不需要package.json檔案。所有模組通過URL載入,比如import vue from "https://vue.org"(絕對地址)或import vue from './vue.runtime.js'(相對地址)。因此,Deno 不需要一箇中心化的模組儲存系統,可以從任何地方載入模組。但是,Deno 下載模組以後,依然會有一個總的目錄,在本地快取模組,因此可以離線使用。也就是說其實還是有一個類似於npm_modules的資料夾。

Deno 內建了開發者需要的各種功能,不再需要外部工具。打包、格式清理、測試、安裝、文件生成、linting、指令碼編譯成可執行檔案等,都有專門命令,不知道會不會在幹掉Node的路上順便把Webpack也給幹掉。

Deno的劣勢

雖然這麼一對比,感覺NodeJS完全不是對手,但是有一點是Deno暫時望塵莫及的,那就是巨大的生態。

就像C#和Java一樣,他們真的差距那麼巨大嗎?其實並沒有吧,但是流行度差這麼多有很多原因是因為生態。

就像華為想搞自己的鴻蒙系統,即使真的能比安卓優秀,但是安卓巨大的生態就足夠領先很多年。當年Windows Phone系統不就是這麼輸的麼?啥軟體都沒有,自然沒人願意賣Windows Phone手機。

Ryan說了,Deno現在不打算對Node做相容處理,也就是說很多東西在Node能用但是在Deno上用不了,能不能真的幹掉Node就要看廣大造輪子愛好者們了,看看他們願不願意在Deno身上再造一個。

如果React、Vue以後都從Deno身上建生態了,那麼Deno的前途就真的光明瞭,希望那一天能夠早點到來。

相關文章