原作者 | 瑞安·达尔 |
---|---|
开发者 | Various |
首次发布 | 2018年5月13日[1] |
稳定版本 | 1.11.2 (2021年6月21日[2]) |
预览版本 | 1.0.0-rc3 (2020年5月12日[3]) |
源代码库 | https://github.com/denoland/deno |
编程语言 | TypeScript, JavaScript, Rust, C++ |
操作系统 | Linux, macOS, Microsoft Windows |
类型 | 执行环境 |
许可协议 | MIT许可证[4][5] |
Deno是基于V8引擎和Rust语言所创建的JavaScript、TypeScript执行环境,由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的相同之处:
Deno与Node.js的不同之处[7]:
- 预设模块系统是使用ES Module,而不是CommonJS。
- 使用URL加载本地端或远端的dependencies。
- 使用内建的包管理器来抓取资源,因此不需要NPM。
- 使用具有缓存机制的快照TypeScript编译器,因此Typescript也能开箱即用。
- 兼容具有广泛Web API的浏览器。
- 允许控制文件系统与网络访问,以执行沙盒内的代码。
- 重新利用Promise、ES6、Typescript来设计API。
- 最小化核心API的大小,同时提供许多的标准函数库,因此不需要再使用外部的dependencies。
- 使用讯息传递通道来调用特权系统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/
参考资料
- ↑ Contributors, denoland/deno, Github. [5 July 2019].
- ↑ Releases · denoland/deno. [2021-06-21].
- ↑ Deno 1.0.0-rc3. [12 May 2020] –通过GitHub.
- ↑ deno/LICENSE at master. GitHub. [5 July 2019].
- ↑ The MIT License. Open Source Initiative. 17 September 2018 [17 September 2018].
- ↑ Deno: Secure V8 TypeScript Runtime from Original Node.js Creator. InfoQ. [2019-05-17].
- ↑ 7.0 7.1 7.2 Deno Manual. deno.land. [2019-05-17].
- ↑ Paul Krill. Ryan Dahl’s Node.js regrets lead to Deno. InfoWorld. 2018-06-21 [2020-06-03].
- ↑ 引用错误:
<ref>
标签无效;未给name(名称)为:0
的ref(参考)提供文本 - ↑ Dahl, Ryan. Design mistakes in Node (PDF). Github. 2018-06-06 [2020-06-03].
- ↑ denoland/deno, branch "golang". Github.
- ↑ Suggestion: Look into porting to Rust and using Tokio. GitHub. [2020-06-03].
- ↑ Tokio - The asynchronous run-time for the Rust programming language.. Tokio.rs. [2020-06-03].
- ↑ Protobuf seems like a lot of overhead for this use case?. Github.
- ↑ Replace flatbuffers. GitHub.
- ↑ Remove flatbuffers. GitHub.
- ↑ denoland/deno_std: deno standard modules. Github. [2020-06-03].
- ↑ Deno 1.0. deno.land. [2020-05-14].