首頁  >  文章  >  web前端  >  什麼是Deno?與Node.js的差別是什麼?

什麼是Deno?與Node.js的差別是什麼?

青灯夜游
青灯夜游轉載
2021-06-24 11:28:553254瀏覽

Deno是為解決Node的一些內在問題而創建的,那麼與Node.js的區別是什麼?以下本篇文章帶大家詳細了解Deno,介紹一下Deno和Node.js的差別。

什麼是Deno?與Node.js的差別是什麼?

【推薦學習:《nodejs 教學》】

Node.js的作者Ryan Dahl,過去一年半的時間都在打造一個新的JavaScript運行環境Deno來解決Node的一些內在問題。

不過別誤會,由於JavaScript龐大的社群生態與使用範圍,Node是個非常好的JavaScript運作環境。然而,Dahl 也承認在Node的某些方面他應該考慮得更全面一些,例如:安全性,模組機制,依賴管理等。

在他的計畫中,他並不會去預想Deno在短時間內能夠發展成一個多大規模的平台。當然咯,把時間調回2009年,JavaScript還是人人都能取笑的一個有些怪異的小語言,也木有現在這麼多語言特性。

什麼是Deno,以及它的主要特性是哪些?

Deno是基於Google V8引擎所建構的安全的TypeScript運行環境。 以下是建構Deno的一些物料:

  • Rust(Deno的核心模組使用Rust編寫,Node的核心模組是用C 實現的)
  • Tokio(Rust實現的非同步編程框架)
  • TypeScript(Deno對JavaScript和TypeScript都支援開箱即用)
  • V8(Google出品JavaScript執行時,主要用在Chrome和Node中)

接下來再看看Deno提供了哪些特性。

安全性(權限管理)

Deno最重要的功能就是安全性。

相較於Node,Deno預設使用沙箱環境執行程式碼,這表示執行環境沒有操作下列模組權限:

  • 檔案系統
  • 網路
  • 執行其他的腳本
  • 系統環境變數

讓我們檢視一下Deno的權限系統是如何運作滴。

(async () => {
 const encoder = new TextEncoder();
 const data = encoder.encode('Hello world\n');

 await Deno.writeFile('hello.txt', data);
 await Deno.writeFile('hello2.txt', data);
})();

這個腳本分別創建了兩個名為hello.txthello2.txt的文件,並在其中寫入Hello world。但是這段程式碼運行在沙箱環境中,所以是沒有檔案系統的操作權限滴。

還有一點值得注意,在上面的腳本中我們使用Deno命名空間來操作文件,而不像在Node中使用fs模組。 Deno命名空間提供了超多基礎方法。不過使用Deno命名空間會導致我們的程式碼失去了對瀏覽器的相容性,這個問題我們晚點再聊。

使用下面的命令執行上述腳本:

$ deno run write-hello.ts

執行之後,我們會收到下面的提示:

Deno requests write access to "/Users/user/folder/hello.txt". Grant? [a/y/n/d (a = allow always, y = allow once, n = deny once, d = deny always)]

實際上,基於上面創建文件的腳本我們會收到兩次來自沙箱環境的權限提示。不過如果我們選擇allow always選項,就只會被詢問一次啦。

如果我們選了deny,會拋出一個PermissionDenied的錯誤,如果我們沒寫錯誤處理邏輯的話,進程在此時就被終止啦。

如果我們用下面的命令來執行腳本:

deno run --allow-write write-hello.ts

會在沒有提示的情況下建立這兩個檔案。

Deno針對檔案系統的命令列標誌位,除了--allow-write,還有--allow-net/--allow- env/--allow-run,分別用來開啟針對網路、系統環境變數和操作子程序的權限。

模組機制

Deno使用瀏覽器一樣的方式,透過URL來載入模組。很多人第一次見到在服務端的import語句中見到URL會感到有點困惑,但對我來說這還蠻好理解的:

import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

你覺得透過URL來引入模組會有啥大不了的嗎?答案其實蠻簡單的:透過使用URL來載入模組,Deno就可以避免引入一個類似npm的中心化系統來發布package,npm最近受到了很多吐槽

透過URL來引入程式碼,可以讓套件的作者們使用自己最喜歡的方式來維護和發布自己的程式碼。再也不會有package.jsonnode_modules了。

當我們啟動應用程式之後,Deno會下載所有被引用的文件,並將它們快取到本地。一旦引用被快取下來,Deno就不會再去下載它們了,除非我們使用-- relaod標誌位元去觸發重新下載。

還有幾個問題值得我們討論一哈:

万一存放引用的站点挂了咋办?

由于没有了一个中心化的包管理站点,那些存放模块的站点可能因为各种各样的原因挂掉。如果在开发甚至生产环境出现这种情况是非常危险滴!

我们在上一节提到,Deno会缓存好已下载的模块。由于缓存是存放在我们的本地磁盘的,Deno的作者建议将这些缓存提交到代码仓库里。这样一来,即使存放引用的站点挂了,开发者们还是可以使用已经下载好的模块(只不过版本是被锁住的啦)。

Deno会把缓存存储在环境变量$DENO_DIR所指定的目录下,如果我们不去设置这个变量,它会指向系统默认的缓存目录。我们可以把$DENO_DIR指定我们的本地仓库,然后把它们提交到版本管理系统中(比如:git

只能使用URL来引用模块吗?

总是敲URL显得有点XX,还好,Deno提供了两种方案来避免我们成为XX。

第一种,你可以在本地文件中将已经引用的模块重新export出来,比如:

export { test, assertEquals } from "https://deno.land/std/testing/mod.ts";

假如上面这个文件叫local-test-utils.ts。现在,如果我们想再次使用test或者assertEquals方法,只需要像下面这样引用它们:

import { test, assertEquals } from './local-test-utils.ts';

看得出来,是不是通过URL来引用它们并不是最重要的啦。

第二种方案,建一个引用映射表,比如像下面这样一个JSON文件:

{
   "imports": {
      "http/": "https://deno.land/std/http/"
   }
}

然后把它像这样import到代码里:

import { serve } from "http/server.ts";

为了让它生效,我们还需要通过--importmap标志位让Deno来引入import映射表:

$ deno run --importmap=import_map.json hello_server.ts

如何进行版本管理

版本管理必须由包作者来支持,这样在client端可以通过在URL中设置版本号来下载:https://unpkg.com/liltest@0.0.5/dist/liltest.js

浏览器兼容性

Deno有计划做到兼容浏览器。从技术上讲,在使用ES module的前提下,我们不需要使用任何类似webpack的打包工具就能在浏览器上运行Deno代码。

不过呢,你可以使用类似Babel这样的工具可以把代码转化成ES5版本的JavaScript,这样可以兼容那些不支持所有最新语言特性的低版本浏览器中,带来的后果就是最终文件里有很多不是必须的冗余代码,增大代码的体积。

结果取决于我们的主要目的是啥。

支持TypeScript开箱即用

不需要任何配置文件就能在Deno中轻易地使用TypeScript。当然咯,你也可以编写纯JavaScript代码,并使用Deno去执行它。

总结

Deno,作为一个新的TypeScript和JavaScript的运行环境,是一个非常有趣的技术项目,并且至今已经稳定发展了一段时间。但是距离在生产环境中去使用它还有比较长的一段路要走。

通过去中心化(或者翻译成分布式?)的机制,把JavaScript生态系统从npm这样中心化的包管理系统中解放了出来。

Dahl希望在这个夏天快结束的时候能够发布1.0版本,所以如果你对Deno未来的新进展感兴趣的话,可以给它个star

最后还有一个日志系统的广告,大家可以去原文查看。

英文原文地址:https://blog.logrocket.com/what-is-deno/

更多编程相关知识,请访问:编程视频!!

以上是什麼是Deno?與Node.js的差別是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除