- 原文地址:Why I Believe Deno is a Step in the Wrong Direction for JavaScript Runtime Environments
- 原文作者:Mehul Mohan
- 原文發(fā)布時間:2020-05-14
- 譯者:hylerrix
- 備注:本文遵循 freeCodeCamp 翻譯規(guī)范翔脱,同時本文會收錄在《Deno 鉆研之術(shù)》的翻譯篇中米愿。
- 備注:非營利組織 freeCodeCamp.org 自 2014 年成立以來,以“幫助人們免費學(xué)習(xí)編程”為使命,創(chuàng)建了大量免費的編程教程翁脆,包括交互式課程、視頻課程拦盹、文章等鹃祖。線下開發(fā)者社區(qū)遍布 160 多個國家、2000 多個城市普舆。FCC 正在幫助全球數(shù)百萬人學(xué)習(xí)編程恬口,希望讓世界上每個人都有機會獲得免費的優(yōu)質(zhì)的編程教育資源,成為開發(fā)者或者運用編程去解決問題沼侣。搜索關(guān)注微信公眾號 “freeCodeCamp”祖能,可了解更多信息。
譯者序
在為《Deno 鉆研之術(shù)》引入第一篇翻譯文章的時候蛾洛,就看到了這篇文章养铸,那時還覺得駕馭不了,就重點先寫了若干篇入門級別的 Deno 文章轧膘。
轉(zhuǎn)眼到 2021 年钞螟,從《Deno 雙周刊》第一期繼續(xù)開啟新的一年的 Deno 之旅,于是就回想起了本文谎碍,覺得可以通過好好閱讀本文及相關(guān)后鳞滨,從另一個角度了解 Deno,翻譯就開始了蟆淀。
相比前面對文章的直接翻譯外拯啦,本文有很多想要記筆記的地方(甚至“大開眼界”的地方),因此獨特地開辟本文的“譯者序”篇章熔任,來梳理一下原文及其相關(guān)視頻到底針對 Deno 的另一面褒链,都講了什么。
也正如原文所說疑苔,這注定是一篇有爭議的文章甫匹,從文章中引入的兩個視頻中的點踩數(shù)都微微大于點贊數(shù)、其評論區(qū)都充滿著“火熱”的討論就能看出多個觀點的沖撞惦费。原文也存在些過度批評的地方赛惩,但是不妨礙下方譯文開始后一比一地還原原作者想要表達的觀點!
所以趁餐,原作者 Mehul 在原文以及兩個視頻中到底想要說 Deno 為什么沒那么好喷兼?其觀點大致梳理如下:
注意:如果想先看原文的話可以跳過閱讀并在之后來看這份簡單的總結(jié)。
- Deno 和 Node 確實有競爭關(guān)系后雷,因為你必須在你的下個項目中作出選擇季惯。
- Deno 現(xiàn)在所做的成果并不是很多吠各,大多特性都可以在 Node 生態(tài)中較好地解決掉。
- URL import 還是一場災(zāi)難勉抓。NPM 中已經(jīng)有很多明星項目“竟然只有一行代碼”贾漏、“暗中偷竊用戶數(shù)據(jù)”、“注入挖礦代碼”藕筋、“兼容性出現(xiàn)問題導(dǎo)致很多上游庫受影響”等問題纵散,URL import 本身并不能解決這些問題,更沒有一個像 Node 一樣強壯的社區(qū)來保證受人信任的依賴庫隐圾,也就不會有更多的開發(fā)者愿意加入到 Deno 生態(tài)中伍掀。
- 由于 TypeScript 是 JavaScript 的超集,完全可以選擇跳過類型驗證暇藏,此時推薦新手在 Deno 上直接使用 TypeScript 編程坑會很大蜜笤,很可能會出現(xiàn)一堆 any 類型。在經(jīng)常性的調(diào)試報錯下盐碱,TypeScript 的學(xué)習(xí)成本也較高把兔,很容易寫出低質(zhì)量代碼。
- TypeScript 并不是直接在 Deno 上跑的瓮顽,其實還是變成了 JavaScript 來跑县好,何必一定要集成到 Deno 中呢?
- 安全是一個很難的事情暖混,Deno 宣傳自己的“安全沙箱”注定要承擔(dān)很大的責(zé)任缕贡。Deno 安全沙箱也沒有必要,完全可以用 Docker 等容器或虛擬化技術(shù)來支持儒恋。同時,真正想搞破壞的腳本也會找到自己的方式來規(guī)避安全問題黔漂。
- 以當(dāng)時版本下的
deno --allow-run
運行主進程從而開啟的子進程能輕松突破安全沙箱的驗證來獲得更多權(quán)限為例诫尽,發(fā)現(xiàn) Deno 的“安全沙箱”并沒有所說的那么安全。 - Deno 沒有必要集成太多工具鏈(代碼格式化炬守、測試工具牧嫉、TypeScript 等等)于一體,讓各種第三方工具鏈來一起共建生態(tài)的同時减途,保證 Deno 本身的專注性并提供更友好的插件支持會很好酣藻。
- Node 的異步模型并沒有被淘汰,promise 和事件偵聽器模型也沒有被淘汰鳍置,因此不確定 Deno 將如何解決這些沒有被淘汰的問題辽剧。
- 未來并不確定會有多少開發(fā)者愿意將 npm 中的成熟庫逐漸遷移到 Deno 中。
可以看出税产,無論你是 Node 開發(fā)者還是 Deno 愛好者怕轿,這些觀點都有很多值得思考的地方偷崩。但也有有失偏頗的地方,比如文中將 Deno 說明為編程語言撞羽,也將 Deno 只發(fā)展了兩年多的生態(tài)直接和建設(shè)了十年的 Node 生態(tài)作橫向?qū)Ρ取狣eno 注定會有自己獨特的發(fā)展軌跡阐斜。
最后,原文作者 Mehul 總結(jié)了他眼中的 Deno v1.0 的真實面貌:
Deno = (大多數(shù)情況下)[TypeScript + Node + 正確配置的 Docker 容器 + 單一可執(zhí)行程序 + <各種各樣的小工具> - NPM]
譯文開始
目前诀紊,我還沒有在 Youtube 上找到任何一個像 codedamn 一樣的頻道(超過 10 萬名開發(fā)者訂閱)谒出,其對 Deno v1 版本的發(fā)布并不感到興奮。
上周邻奠,我在我的頻道上發(fā)布了一個視頻笤喳,介紹了一些“為什么我認為我們不需要 Deno——另一個基于 V8 和 Node 的 JavaScript 運行時”的原因,這些原因?qū)ξ襾碚f都很簡明扼要惕澎。
同時通過本文莉测,我可以在視頻外拓展闡述更多的原因。但如果你想先看視頻唧喉,可以看看這個:
為了證明我總體上并不是反對 Deno 甚至 JavaScript 本身捣卤,我想聲明一下:我喜歡 JavaScript 勝過于很多其它的編程技術(shù)。我的主要技術(shù)棧也只圍繞著 JavaScript 展開——Node/React/MongoDB/React Native/NativeScript/Ionic/甚至你能想到的更多相關(guān)庫八孝。
我也是主要用 JavaScript 這一門語言董朝,就讓我的 Youtube 頻道及一個開發(fā)者平臺的訂閱人數(shù)達到了 10 萬多人。
但重要的事情在于干跛,保持公平客觀的角度來看到一個事務(wù)的兩面性很重要子姜。Deno 當(dāng)然有好的一面,但也有大多數(shù)人尚未看到/寫文探討的另一面楼入。一起來看看吧哥捕!
_
注意:本文注定會是一個有爭議性的文章。請先讓我們保持禮貌的態(tài)度并控制好自己的情緒嘉熊。如果你能仔細閱讀全文直到結(jié)尾遥赚,然后再說說你的更多想法,那我會備受感激阐肤。
_
本文底部我會列出我的社交賬號凫佛,也希望我們能在哪里針對此主題進行更多的良好探討。
Deno vs Node:名副其實的競爭關(guān)系
有很多業(yè)內(nèi)人士都在說:“Deno 和 Node 之間沒有任何競爭關(guān)系孕惜,彼此之間可以學(xué)到很多東西”愧薛。
在某種程度上,我同意這個看法衫画,Node 和 Deno 確實可以互相學(xué)習(xí)毫炉。但是兩者間真的沒有競爭關(guān)系了嗎?我完全不同意這關(guān)觀點削罩。
讓我們重新看一下 Deno 和 Node 的共同特征:
- 它們都是 JavaScript 的運行時環(huán)境碘箍;
- 它們都可以在可以運行 V8 的任何計算機上運行遵馆;
- 它們都有 ECMAScript 標(biāo)準支持;
- 它們都在被積極的維護中丰榴。
如果你這兩年都是 Deno 的粉絲货邓,這兩年里不選擇 Node 而直接用 Deno 作為新項目的技術(shù)選型是不可能的。
同理四濒,如果你以前從未使用過 TypeScript换况,并且認為自己想要嘗試 Deno,此時你會很難同時用上 NPM 生態(tài)中的各種模塊盗蟆。
所以:Deno 和 Node 的開發(fā)人員目前確實存在分歧——你必須做選擇戈二,我想說這是兩者為競爭關(guān)系的一個很重要的例子。
Deno 到底好在哪里喳资?
首先觉吭,我需要列舉一下 Deno 對自己的宣傳中的那些優(yōu)勢,Deno 為什么說自己是更好的運行時:
- 它克服了 Node 的一些缺點仆邓;
- 它在默認情況下是一個安全的運行時環(huán)境鲜滩;
- 它內(nèi)置 TypeScript 支持;
- 它將 Promise 的支持下放到底層节值;
- 它基于 Rust 語言構(gòu)建(對比與 C++ 之于 Node)徙硅。
在接下來的章節(jié)中,我將一個一個針對上面的每一個屬于 Deno 的優(yōu)點搞疗,來看看 Node 可以從中學(xué)到什么嗓蘑。我也將會在必要之時探討灰嫉,為什么 Deno 還沒有那么有意義猛拴。
Deno 畫蛇添足在了哪些地方?
讓我們開始拿起 Deno 的獨特宣傳點(USP验游,Unique Selling Proposition) 并將它們一一解析:
默認安全的運行時環(huán)境
這是 Deno 里很受歡迎的特性幢炸,我很驚喜泄隔。Deno 直接默認支持一個安全的沙箱環(huán)境,除非你明確的選擇開啟訪問文件系統(tǒng)或訪問網(wǎng)絡(luò)等功能權(quán)限阳懂。
Deno 這樣做是因為它想更加地貼近瀏覽器梅尤。Deno 遵守 ECMAScript 標(biāo)準這點很不錯柜思,但為什么如此熱衷于率先貼近瀏覽器岩调?
或許答案是,Deno 想要保持在客戶端和服務(wù)端上編寫的代碼之間有良好的兼容性赡盘。但 Deno 如此強烈的想要支持瀏覽器以至于我覺得方向有些偏失号枕、甚至有些過頭了。
Node 雖不支持“安全的運行時”——但經(jīng)過深思熟慮后陨享,我覺得也有理由支持 Node:
- 眾所周知葱淳,你不應(yīng)該在系統(tǒng)上運行不受信任的代碼和可執(zhí)行文件钝腺。這就是我們總是選擇像 Express 庫之于 Node 的原因(而不是隨便找個聲稱自己速度比 Express 快 100 倍的庫)。信任來自于社區(qū)的大量使用赞厕。
- 我不知道有任何編程語言像 Deno 這樣提供如此的沙箱環(huán)境艳狐。盡管這個功能可能不錯,但似乎應(yīng)該交由諸如 Docker 這類的容器環(huán)境來完成皿桑。我相信一個被良好配置的 Docker 環(huán)境毫目,相比在沙箱化的 Deno 環(huán)境中運行不受信任的 Node 代碼來說,能更好的處理不受信任文件的安全性問題诲侮。
- 沙箱化并沒那么容易——我雖然不是網(wǎng)絡(luò)安全專家镀虐,但我覺得某些功能越多,攻擊面就可能越大沟绪。Deno 承諾提供安全的運行時環(huán)境刮便,但我想說安全很難實現(xiàn)。Deno 的承諾帶來了巨大的安全責(zé)任绽慈。世界上最大的企業(yè)們?yōu)橹С炙鼈兊陌踩酌庇媱澓藓担枰磕隇楠毩㈤_發(fā)者和安全公司投入將近數(shù)億美金。因此久信,Deno 到底會將它們的“安全環(huán)境”帶向何方窖杀?時間會證明一切。
所以裙士,Node 可以從 Deno 中學(xué)到什么入客?我想說不會學(xué)到太多。Node 或許可以從競爭對手可以引入一些安全環(huán)境的標(biāo)識腿椎,但是沒有太多意義桌硫。如果你想在你的系統(tǒng)上隨意運行一些未知代碼,則最好克隆一個 C/C++ 倉庫并運行 make 命令損害系統(tǒng)啃炸。
譯者注:上段最后一句話是“If you randomly run arbitrary code on your systems, you might as well clone a C/C++ repo and run a make command over it and get your whole system compromised.”铆隘,有些難以翻譯,也不容易看出為什么從 Node/Deno 突然跑到了 C/C++南用,歡迎交流膀钠。
據(jù)我所知,你不能在像 C/C++ 這樣的底層語言上來“沙盒化”文件系統(tǒng)或網(wǎng)絡(luò)訪問——這樣效率并不高裹虫。
注意:最近我發(fā)現(xiàn)啟用 --allow-run
標(biāo)志的 Deno 幾乎可以完成任何操作肿嘲。該視頻詳細介紹了相關(guān)內(nèi)容:
內(nèi)置支持 TypeScript
為 TypeScript 現(xiàn)階段的進展歡呼,我很高興 Deno 開箱即用地支持 TypeScript筑公。
注: 感謝 @lilasquared 指出 Deno 也能開箱即用地運行 .js
文件雳窟。本文重點強調(diào)使用 .ts
文件編寫代碼。Deno 當(dāng)然可以直接運行 .js 文件匣屡。
但是封救,讓我們退一步來說:你知道為什么 JavaScript 和 Node 在全球擁有數(shù)以萬計的開發(fā)人員嗎拇涤?因為進入這個領(lǐng)域的壁壘幾乎為零。JavaScript 是靈活的誉结,可以容許你的諸多錯誤鹅士。而 TypeScript 總會給你一些奇怪的錯誤。
對于生產(chǎn)級的應(yīng)用程序來說就糟糕了:生產(chǎn)環(huán)境上可不需要這些時髦的東西惩坑。同時對于學(xué)習(xí)者來說如绸,JavaScript 是寬容的,縱使你可能會遇到一些 Bug旭贬,但也可以很輕松的改正怔接,引用一句話,JavaScript 可以被快速編碼并將事情搞定稀轨。
對于初學(xué)者來說扼脐,我擔(dān)心他們?nèi)绻x擇使用 Deno(并被要求使用 TypeScript),因為他們還不了解 TypeScript奋刽,想著快速在服務(wù)端上跑通代碼瓦侮,我們可能會看到很多這種的代碼:
const httpResponse: any = await getAPIResponse<any>({ myParams })
// ...
const someOtherVariable = something() as any
// ...
any, any, any
TypeScript 是 JavaScript 的超集。你完全可以無意識間寫一段質(zhì)量很差的 TypeScript 代碼佣谐,僅僅使用 TypeScript 并不會讓你的項目無懈可擊肚吏。
直到你想起來本來就能在 Node 中寫 TypeScript 之前,這種體驗確實很有趣狭魂。我相信現(xiàn)在每個在生產(chǎn)環(huán)境中使用 Node 的大型公司都引入了 TypeScript 來編寫項目——沒有例外罚攀。當(dāng)你處理諸多文件及其依賴關(guān)系、處理大量代碼時雌澄,JavaScript 真的很難拓展斋泄。
TypeScript 是 JavaScript 生態(tài)系統(tǒng)中革命性的工具包,更好地同時支持了靜態(tài)和動態(tài)語言镐牺。
因此 Deno 聲明自己會內(nèi)置 TypeScript 支持炫掐。但我想問為什么一定要這樣?確實睬涧,如果不內(nèi)置的話募胃,可能需要額外引入 Babel 和 Webpack 來完成這項工作,但這不是一堆第三方工具鏈圍繞身邊來共建生態(tài)的重要意義嗎畦浓?我們難道不想增強 DX 嗎痹束?
譯者注:DX,開發(fā)人員體驗宅粥,是 Developer Experience 的簡稱参袱。當(dāng)軟件或系統(tǒng)的用戶是開發(fā)人員時电谣,開發(fā)人員體驗(DX)就相當(dāng)于用戶體驗(UX, User experience design)秽梅。
JavaScript 依然還會是 JavaScript抹蚀,保持自身的風(fēng)格。況且企垦,如果 Deno 真的能直接運行 TypeScript(或類似于 TypeScript 的語言)环壤,我覺得沒什么問題。但事實上钞诡,Deno 其實也只是將 TypeScript 代碼轉(zhuǎn)換為 JavaScript 代碼郑现,并運行它罷了。
從這些角度能看出荧降,Deno 似乎是一個 Node 下各種工具的的集成版本接箫,Deno 將一個測試工具、一個代碼格式化程序和 TypeScript 等一次性的包括進來朵诫。我更喜歡一個精簡的編程語言并在合適的時候由我自己添加各種插件——當(dāng)然辛友,我不能代表所有開發(fā)人員,這也只是我的觀點剪返。
為什么我會在已經(jīng)有專注于代碼格式化的 prettier 庫的情況下废累,依然需要領(lǐng)一個內(nèi)置的代碼格式化工具?為什么要解決這種本身就做的不錯的東西脱盲?
單體架構(gòu)確實集中起來提供了很多工具邑滨,但它也真的很龐大,一個更精簡和專注的核心庫才能更好的維護和拓展钱反。
Promise 的支持下放到底層
和 Node 作為對比掖看,Deno v1 的發(fā)布對我來說看不出太多的意義。我非常尊重 Node 和 Deno 的創(chuàng)建者面哥,但是 Node 擁有一些 Deno 所沒有的東西——世界各地眾多經(jīng)驗豐富的開發(fā)人員的支持乙各。
Node 由近 3000 位開發(fā)者貢獻力量,并且是異步 I/O 事件處理的引領(lǐng)者幢竹。Deno 確實建立在 Rust 之上耳峦,并公開了類似 Promise 的的抽象。但是 Node 有 C++焕毫,有 3000 名開發(fā)人員以及 10 年以上的開發(fā)和維護蹲坷。
Node 的異步模型并沒有被淘汰,promise 和事件偵聽器模型也沒有被淘汰邑飒,因此我不確定 Deno 將如何解決這些并沒被淘汰的問題循签。
再見了,npm
很重要的事情是:Deno 并不支持 NPM疙咸。Ryan(Node 和 Deno 的創(chuàng)建者)在為此推廣 Go 語言的相關(guān)特性县匠。讓我想到一些包管理器:
- npm for JS (obviously)
- npm 之于 JS(真很明細)
- apt-get
- composer 之于 PHP
- brew 之于 macOS
- cargo 之于 Rust(Deno 正是基于 Rust 構(gòu)建)
我認為不使用包管理器來管理是很不好的一步。包管理器能做的太多了:標(biāo)明版本、編寫腳本乞旦、管理依賴關(guān)系等等贼穆。為什么 Deno 不使用 npm 呢?我并不清楚兰粉,但這些是我想到的:
- 首先故痊,因為 Deno 需要 TypeScript 生態(tài),但是后者生態(tài)更多的是 JavaScript 的玖姑。更正:Deno 也能良好的運行
.js
文件愕秫。 - 其次,大量 npm 模塊需要要求使用到文件/網(wǎng)絡(luò)甚至更多的條件焰络,而這些 Deno 都很嚴格的默認不提供這些權(quán)限了戴甩。所以你需要在 package.json 里注入大量頗許冗余的“permissions”字段來提供更多權(quán)限。然而...Deno 無法和 npm 互相配合闪彼,因此也沒有 package.json等恐。接下來我們會來看看 Deno 到底如何處理模塊系統(tǒng)的。
- NPM 模塊數(shù)量及其龐大甚至臃腫备蚓,但這也是 Node 生態(tài)的強大生命力所在课蔬。想要找一個庫來將 tar 文件內(nèi)容提取到 stream 流中?你可以選擇 tar-steram郊尝。想要一個數(shù)據(jù)格式驗證庫二跋?你可以選擇 joi。想要配合 JWT 協(xié)同使用流昏?你可以選擇 jsonwebtoken扎即。我懷疑得有多久才能讓開發(fā)者們將他們的各種庫變得兼容 Deno 系統(tǒng)?
Deno 對模塊系統(tǒng)采用了一種完全不同的方法况凉。但無論如何谚鄙,Deno 在嘗試以某種方式“修補”現(xiàn)有的 NPM 模塊。那么除了嘗試在 Docker 容器中“入侵”(hacking around)一個 TS + Node 項目外刁绒,我看不到太多使用 Deno 的意義闷营。
根據(jù)我目前所了解的有關(guān) Deno 的一切,這是 Deno 現(xiàn)在的真實面貌:
Deno = (大多數(shù)情況下)[TypeScript + Node + 正確配置的 Docker 容器 + 單一可執(zhí)行程序 + <各種各樣的小工具> - NPM]
搞定知市!讓我們冷靜一下傻盟,然后聽我一下的總結(jié)。
總結(jié)
我和其它人對 Deno 的出現(xiàn)一樣感到興奮嫂丙。但當(dāng) Deno 準備完全重寫 JavaScript 運行時時娘赴,我的期望便有所變動。
Deno 的自動化 TypeScript 文檔等諸多不錯的特性我沒有提到跟啤,是因為我希望這篇文章旨在展示 Deno 的另一面诽表。因為 Deno 的優(yōu)點幾乎可以再任何其他 Deno 的文章中找到唉锌,所以我需要再次強調(diào)硬幣的兩面性。
坦白來說竿奏,Deno 看起來為了一些很小的益處承擔(dān)了巨大的責(zé)任和代價袄简,包括轉(zhuǎn)移現(xiàn)有的 NPM 模塊和代碼庫的諸多債務(wù)。你同意還是不同意我的這些觀點呢议双?我很期待你的想法。推特聯(lián)系我 @mehulmpt 或 Instagram 也可以捉片!
祝好平痰!
全文譯完,歡迎前往 @hylerrix/deno-tutorial 倉庫點個 star 或 watch伍纫。
《Deno 鉆研之術(shù)》生態(tài)現(xiàn)已支持四大方向的不同倉庫宗雇,持續(xù)共建中...
- deno-tutorial:核心倉庫,電子書集中地莹规,圍繞 Deno 全生態(tài)的各種原創(chuàng)/翻譯文章赔蒲。
- deno-feedly:Deno 雙周刊,中英雙語每兩周地匯總 Deno 動態(tài)良漱,2021 開年之作舞虱。
- deno-algorithm:想在 Deno 上用 TypeScript 刷 LeetCode 算法?或許可以看看這個(才開源不久母市,刷一定的題后再宣傳)矾兜。
- awesome-deno-cn:見名知意,中文社區(qū)下的 Deno 資源全圖譜患久,求 PR椅寺。
以及更多使用 Deno 生態(tài)庫構(gòu)建的電子書如 es-interview (《ECMAScript+ 面試寶典》)等,盡請 follow 好家伙:Github@hylerrix