Deno

本页使用了标题或全文手工转换,现处于中国大陆简体模式
求闻百科,共笔求闻
Deno
原作者瑞安·达尔
开发者Various
首次发布2018年5月13日,​6年前​(2018-05-13[1]
稳定版本
1.11.2
(2021年6月21日,​2年前​(2021-06-21[2]
预览版本
1.0.0-rc3
(2020年5月12日,​4年前​(2020-05-12[3]
源代码库https://github.com/denoland/deno
编程语言TypeScript, JavaScript, Rust, C++
操作系统Linux, macOS, Microsoft Windows
类型执行环境
许可协议MIT许可证[4][5]

Deno是基于V8引擎和Rust语言所创建的JavaScriptTypeScript执行环境,由Node.js的原始开发者瑞安·达尔所创造。 [6]达尔在2018年的演讲“我为Node.js感到后悔的十件事”中宣布了Deno。 Deno在单个可执行档中扮演执行环境和包管理系统的角色,不需要将其分开。 [7][8]

历史

Deno于2018年瑞安·达尔的演讲“我为Node.js感到后悔的十件事”中宣布。[9]在这场演讲中,达尔提到他后悔Node.js的设计,例如没有在API中使用JavaScript的Promise、GYP建构系统、省略文件的副档名、node_modules与package.json、使用index.js进行模块解析、V8的沙盒环境等等[10]。他在演讲的最后提出了Deno的原型,Deno旨在透过如Protocol Buffers之类的序列化工具传递讯息来实现绑定系统的调用,并提供命令行接口访问控制

Deno初始版本是使用Go语言编写,并使用Protocol Buffers来实作特权(Go)与非特权(V8)之间的序列化[11]。然而因顾虑到双重运行与垃圾搜集,Go在不久后就被Rust取代[12]

为了让Deno拥有异步的事件触发环境,Tokio也被引进来取代原本的libuv[13]

Deno原本采用Flatbuffers以进行更快的零复制序列化与反序列化[14],在2019年4月发布序列化的标准之后[15],2019年8月被移除[16]

2018年11月创建了一个以Go标准函数库为基底的标准函数库,并提供了广泛的工具,解决部分Node.js的dependency问题。[17]

Deno于2020年5月13日正式发布。[18]

概览

Deno目标是成为对目前的工程师来说最具有生产力的的脚本环境[7]。Deno强调事件触发架构,并提供一套非阻塞IO与阻塞IO。

Deno可用于创建网页服务器、执行数学的运算等等。

与Node.js的比较

Deno与Node.js的相同之处:

  1. 皆运行于V8上。
  2. 拥有相同的事件循环
  3. 提供CLI让用户可以执行脚本语言。
  4. 庞大的实用程序

Deno与Node.js的不同之处[7]

  1. 预设模块系统是使用ES Module,而不是CommonJS
  2. 使用URL加载本地端或远端的dependencies。
  3. 使用内建的包管理器来抓取资源,因此不需要NPM
  4. 使用具有缓存机制的快照TypeScript编译器,因此Typescript也能开箱即用。
  5. 兼容具有广泛Web API的浏览器。
  6. 允许控制文件系统网络访问,以执行沙盒内的代码。
  7. 重新利用Promise、ES6、Typescript来设计API。
  8. 最小化核心API的大小,同时提供许多的标准函数库,因此不需要再使用外部的dependencies。
  9. 使用讯息传递通道来调用特权系统API。

范例

最基本的Deno脚本,没有任何读写网络的权限:

deno run main.ts

若要获取权限,需要相对应的flag:

deno run --allow-read --allow-net main.ts

若要检视代码的dependency tree,使用info子命令:

deno info main.ts

Hello World代码(与Node.js相同):

console.log("Hello world");

Deno为浏览器中大多数不可用的Deno特定API提供了全局的命名空间。下列是Unix中的cat程序的实作:

/* cat.ts */
// Deno API透过`Deno`命名空间来公开
const { stdout, open, copy, args } = Deno;
// 支援Top-level await
for (let i = 0; i < args.length; i++) {
    const filename = args[i]; // CLI的参数.
    const file = await open(filename); // 开啓相对应的档案读取.
    await copy(file, stdout); // 执行从`file`到`stdout`的非同步零复制
}

上面的Deno.copy函数的执行方式与Go的io.Copy相像。Writer的输出的目标是stdout,file是Reader的输入来源。

若要执行本程序,我们需要提供读的权限:

deno run --allow-read cat.ts myfile

下面的Deno代码实作了最基本的网页服务器

// 使用URL从远端的Deno标準函式库引入`serve`
import { serve } from "https://deno.land/std@0.55.0/http/server.ts";
// `serve`函式回传非同步的iterator, 产生请求的stream
for await (const req of serve({ port: 8000 })) {
    req.respond({ body: "Hello World\n" });

}

当执行这个程序时,Deno会自动下载远端的标准函数库并编译,相似地,我们也可以借由提供URL当作参数(-A 获取所有权限)来执行标准函数库里的代码(像是文件服务器)而不需要另外下载

$ deno run -A https://deno.land/std/http/file_server.ts
Download https://deno.land/std/http/file_server.ts
Compile ttps://deno.land/std/http/file_server.ts
...
HTTP server listening on http://0.0.0.0:4500/

参考资料

  1. Contributors, denoland/deno, Github. [5 July 2019]. 
  2. Releases · denoland/deno. [2021-06-21]. 
  3. Deno 1.0.0-rc3. [12 May 2020] –通过GitHub. 
  4. deno/LICENSE at master. GitHub. [5 July 2019]. 
  5. The MIT License. Open Source Initiative. 17 September 2018 [17 September 2018]. 
  6. Deno: Secure V8 TypeScript Runtime from Original Node.js Creator. InfoQ. [2019-05-17]. 
  7. 7.0 7.1 7.2 Deno Manual. deno.land. [2019-05-17]. 
  8. Paul Krill. Ryan Dahl’s Node.js regrets lead to Deno. InfoWorld. 2018-06-21 [2020-06-03]. 
  9. 引用错误:<ref>标签无效;未给name(名称)为:0的ref(参考)提供文本
  10. Dahl, Ryan. Design mistakes in Node (PDF). Github. 2018-06-06 [2020-06-03]. 
  11. denoland/deno, branch "golang". Github. 
  12. Suggestion: Look into porting to Rust and using Tokio. GitHub. [2020-06-03]. 
  13. Tokio - The asynchronous run-time for the Rust programming language.. Tokio.rs. [2020-06-03]. 
  14. Protobuf seems like a lot of overhead for this use case?. Github. 
  15. Replace flatbuffers. GitHub. 
  16. Remove flatbuffers. GitHub. 
  17. denoland/deno_std: deno standard modules. Github. [2020-06-03]. 
  18. Deno 1.0. deno.land. [2020-05-14]. 

外部链接