我們並不需要 Deno

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作者:","attrs":{}},{"type":"link","attrs":{"href":"www.leancloud.cn","title":null,"type":null},"content":[{"type":"text","text":"LeanCloud 王子亭","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://deno.land/","title":null,"type":null},"content":[{"type":"text","text":"Deno","attrs":{}}]},{"type":"text","text":" 一出生便帶着光環 —— 它發佈於 Node.js 創始人 Ryan Dahl 的演講「","attrs":{}},{"type":"link","attrs":{"href":"https://www.youtube.com/watch?v=M3BM9TB-8yA","title":null,"type":null},"content":[{"type":"text","text":"Design Mistakes in Node","attrs":{}}]},{"type":"text","text":"(","attrs":{}},{"type":"link","attrs":{"href":"https://tinyclouds.org/jsconf2018.pdf","title":null,"type":null},"content":[{"type":"text","text":"幻燈片","attrs":{}}]},{"type":"text","text":")」,當時有些人說 Node.js 要涼了,但我不這麼認爲。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"原生 TypeScript","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實目前我們在引擎的「用戶態」去使用 TypeScript 並沒有引入任何問題,而且給用戶帶來了很大的靈活性。考慮到 TypeScript 不可能離開 JavaScript 的生態 —— 畢竟引擎總是要支持 JavaScript 的;再加上 TypeScript 有不同的版本、不同的編譯開關,在用戶態使用 TypeScript 可以說是最好的方案了。TypeScirpt 遲早會成爲 Deno 的歷史包袱。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從性能的角度,在 TypeScript 沒出現之前,V8 已經在 JavaScript 上進行大量 ","attrs":{}},{"type":"link","attrs":{"href":"https://zhuanlan.zhihu.com/p/29638866","title":null,"type":null},"content":[{"type":"text","text":"魔法優化","attrs":{}}]},{"type":"text","text":" 了,可以說 JIT 出來的代碼並不比其他靜態類型的語言差太多,是沒法簡單地通過 TypeScript 來提升性能的。再加上前面說了引擎總還是要支持 JavaScript、TypeScript 的運行時語義依然是 JavaScript(TypeScript 並不能保證對象的實際類型在運行時不被修改),所以引擎也不可能從對 JavaScript 的魔法優化切換到基於 TypeScript 的類型來做優化。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"包管理器","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我一直認爲 NPM 是最好用的包管理器之一,這包括將依賴保存在項目目錄中 —— 在調整一個項目的依賴時不必擔心對其他項目產生影響;每個包都可以指定自己的依賴版本,允許多版本並存 —— 在升級一個包的依賴時不會影響到其他包,每個包都可以使用新的版本或繼續使用舊的版本;NPM 負責查找和安裝包,而 Node.js 則用相對簡單的協議去使用這些包,它們可以彼此獨立地升級演進。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到 NPM 最終極大地減輕了開發者的心智負擔,只要你按照正確的方式去使用它,極少會遇到其他語言中有關依賴管理的問題。而 Deno 則反其道行之。雖然 Deno 也提供了一些相關的功能(","attrs":{}},{"type":"link","attrs":{"href":"https://deno.land/manual@master/linking_to_external_code/reloading_modules","title":null,"type":null},"content":[{"type":"text","text":"deno cache","attrs":{}}]},{"type":"text","text":"),但你會發現 Deno 的本意仍然是不希望進行「依賴管理」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在代碼中包含 URL 是一個非常糟糕的做法(Golang 也是如此),Deno 稱之爲去中心化,但其實它只是重新將使用包的代碼與包的來源耦合在了一起(現在 Deno 提供了一個 ","attrs":{}},{"type":"link","attrs":{"href":"https://deno.land/x","title":null,"type":null},"content":[{"type":"text","text":"官方的代理","attrs":{}}]},{"type":"text","text":",但這樣和 NPM 的中心倉庫又有什麼區別呢)。緩存機制也帶來了相當大的不確定性:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"package-lock.json","attrs":{}}],"attrs":{}},{"type":"text","text":" 可以保證每次安裝的依賴是完全一致的,而 Deno 的 ","attrs":{}},{"type":"link","attrs":{"href":"https://deno.land/[email protected]/linking_to_external_code/integrity_checking","title":null,"type":null},"content":[{"type":"text","text":"lock.json","attrs":{}}]},{"type":"text","text":" 只能檢查依賴是否有變化(如果有的話就拒絕運行)。這使得開發者很難控制依賴更新的時機,","attrs":{}},{"type":"link","attrs":{"href":"https://deno.land/manual/linking_to_external_code#but-what-if-the-host-of-the-url-goes-down-the-source-won#39t-be-available","title":null,"type":null},"content":[{"type":"text","text":"Deno 則建議將依賴緩存放入 Git","attrs":{}}]},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"內建權限系統","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一直以來通用編程語言都不曾在語言層面引入權限控制,但確實開源社區也曾報出過多次惡意代碼的事件,但 Deno 的權限機制相當粗糙 —— 只能在進程級別進行權限控制,我可以大膽地預言,在幾乎所有的場景裏我們都需要 --allow-all,並不能對安全起到太多作用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們需要考慮 Deno 的用戶到底是開發者還是使用者:對於 Deno 腳本的使用者來說關注的當然是進程級別的權限;而對於開發者我認爲更關注的是第三方包的權限,權限系統應該以包爲單位(然而 Deno 裏並沒有包的概念了),Node 裏本來也有 vm 模塊可以一定程度上實現沙盒(但確實非常難以控制)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而且說起來我們現在已經有了 Docker(或者更廣泛的容器的概念)這種徹底的隔離和權限控制機制,業界對編程語言引入一套權限控制已經沒有太大的需求了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"孤立的生態","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以說 JavaScript 的生態來自於用戶態類庫的充分競爭,Deno 則在 Runtime API 之外提供了 Standard Library(類似 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"golang.org/x","attrs":{}}],"attrs":{}},{"type":"text","text":")、提供了全套的開發工具鏈(fmt、test、doc、lint、bundle),在試圖提供開箱即用的使用體驗的同時,也削弱了第三方生態。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 Node.js 和 NPM 已然成爲 JavaScript 事實標準的一部分的情況下,Deno 本來可以通過兼容 Node.js 或 NPM 有一個非常好的開場。但 Deno 卻選擇了和 Node.js 劃清界限,而是兼容了一些瀏覽器環境的 API(如 prompt 或 onload)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Deno 自己的說法是爲了遵循已有的 Web 標準避免發明新東西,但實際上這些 Web 標準在設計時並未充分考慮瀏覽器之外的 Runtime,況且 Deno 其實也沒能避免發明新東西(這些新東西被放在了 Deno 這個命名空間中)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"小結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Deno 就是這樣一個有着非常鮮明個人偏好的 JavaScript Runtime,它試圖去糾正 Node.js 的一些「設計失誤」、希望給出一種「JavaScript 最佳實踐」,希望提供高質量且開箱即用的標準庫和工具鏈。這些偏好的選擇總會有人喜歡或不喜歡,但除此之外 Deno 實在是缺少一個 killer featue(殺手級特性)讓一個「理性」的 Node.js 開發者(如一個公司)切換到 Deno。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過單一文件發行、進程級別的權限控制使 Deno 會更適合命令行工具的開發,但能否與已經廣泛用於命令行工具的 Golang 競爭尚且存疑。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作爲一個 Node.js 開發者,我並不覺得 Deno 可以在未來替代 Node 成爲我的主力開發工具,Deno 更像是 Golang 的設計哲學對 JavaScript 的一次入侵。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文地址:","attrs":{}},{"type":"link","attrs":{"href":"https://jysperm.me/2021/05/we-dont-need-deno/","title":null,"type":null},"content":[{"type":"text","text":"我們並不需要 Deno","attrs":{}}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章