Deno
是 node.js
的作者 Ryan Dahl
编写的,这是否意味着 Deno
实际上就是 Node.js
的替代品,我们是否应该开始计划重构冲刺呢? 如果你想了解更多,请往下看。
在2018年,Ryan
进行了一次演讲,在演讲中他提出了他认为的有关 Node.js
的十大问题。在演讲结束时,他揭开了 Deno
的面纱。当时 Deno
只是他正在建设中的一个小项目,也许被大家称作 Node.js
v2版本,在 Node.js
的基础上进行了改进,并且更加安全。
这里是演讲的视频地址,大家最好去看一看。
两年后,在2020年5月13日,官方正式发布了 Deno
1.0版本。一个全新的让 JavaScript
运行在服务端的开发平台。不像 Node.js
是用 C++
语言开发,Deno
底层是用基于 Tokio
平台(提供 JavaScript
所需的异步运行环境)的 Rust
语言编写的,仍然运行在 V8
引擎上。
有什么新知识
我们不单单在谈论与当前 Node.js
完全兼容的新 JavaScript
运行环境,相反的是,Ryan
在 Deno
中增加了一些他认为在 Node.js
中所缺少的东西。
安全集成
默认情况下,Node.js
允许你访问任何内容,也就是说,你可以读写文件系统,发送传输请求,访问环境变量等等。 作为开发人员,具有这种访问权限当然是有好处的,但在编写代码时万一不小心,有可能会带来安全风险。
因此,Deno
可以使用命令行参数来启用或禁用对不同安全功能的访问。如果你需要脚本能够访问 /etc
文件夹,可以执行以下操作:
deno --allow-read=/etc myscript.ts
这样,你的代码就可以从该文件夹中读取任何内容,并且会在没有权限的情况下抛出全异常。 这类似于其他平台处理安全性的方式。如果你是 Android
用户,你肯定遇到过很多应用程序曾要求你允许它们读取联系人,电话,文件夹等,这与此类似。 通过在执行脚本的命令行中敲上这些参数,就可以提供代码所需的权限。
更完整的标准库
自从第一个 Node.js
版本以来,JavaScript
就开始改进其标准库。但是与其他语言相比,它还有很长的路要走。 Deno
也致力于改善这一点,并声称其拥有一个非常完整的标准库,允许开发人员使用官方工具来执行基本的任务,只有复杂的任务时才需要使用外部库(比如 NPM
)。
本质上讲,Deno
提供了诸如 为终端文本添加颜色、使用外部数据结构(例如二进制,csv
,yaml
等)、生成 UUID
甚至编写 websocket
等开箱即用的方法。 还有一些其他的更基本的模块可用,例如访问文件系统,日期转换函数,http
相关函数等等。
集成Typescript
你没有看错,如果你是 TypeScript
的爱好者,那么 Deno
本身就可以满足你的需要,不需要额外引入外部库,默认情况下就可以将 Typescript
转换为 JavaScript
。
尽管默认情况下,Deno
自身会完成转换,但是你可以使用自己的 tsconfig.json
文件来覆盖默认配置:
deno run -c tsconfig.json [your-script.ts]
默认配置采用的是严格模式,因此任何不符合规范的编码都会立即得到警告。
不再需要 NPM 或node_modules 文件夹
在 Node.js
中, 每一个模块和它的祖先模块都有着千丝万缕的依赖关系。是否太臃肿了呢?是否是一个错误的方式来分发管理依赖呢?这绝对是 Node.js
最具争议的方面之一,因此 Deno
决定完全放弃它。
那么,Deno
是如何处理依赖关系的? 它允许你从任何地方引入模块。换句话说,你可以简单地执行以下操作:
import * as log from "https://deno.land/std/log/mod.ts";
从此不再需要拥有自己的集中式存储库,但是你必须谨慎的进行此操作,因为从无法控制的第三方来源导入模块会使你暴露。
实际上,我们也不再需要 package.json
,现在通过在名为 deps.ts
的文件中维护模块列表及其各自的URL即可实现依赖管理。 但是版本控制怎么办呢?我知道你就会问。你可以在 URL
上指定软件包的版本,虽然不是很精美,但确管用。
一个简单的 deps.ts
文件也许是这样子的:
export { assert } from "https://deno.land/std@v0.39.0/testing/asserts.ts";
export { green, bold } from "https://deno.land/std@v0.39.0/fmt/colors.ts";
这将重新导出模块,如果你想更改其引用版本,简单的更改 URL
就可以了。
顺便说一下,第一次执行代码后,导入的模块就会被缓存下来直到你下一次重启。
还有啥
Deno
还包含其他功能,例如开箱即用的大型工具,包括 test runner, debugger, file watcher
等。 但是有些只是其提供的 API
,需要在其基础上写自己的逻辑才能使用它们。
以 Deno.watchFs
提供的 file watcher API
为例,如果你正在寻找与 nodemon
类似的解决方案,你必须自己编写代码来实现。 下面的23行代码是一个解决这种问题的列子:
function startProcess(args: string[] = []): Deno.Process {
return Deno.run({ cmd: ['deno', ...args] });
}
const throttle = 500;
let app: Deno.Process = startProcess(Deno.args);
let timeout: number|null = null;
function runApp() {
app && app.close();
app = startProcess(Deno.args);
}
for await (const event of Deno.watchFs('.')) {
if (event.kind !== "access") {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(runApp, throttle);
}
}
会取代Node.js吗
我们中的有些人早在 Node.js
0.10 版本推出的那天起就已经开始使用它了,并且是在生产环境中使用它!真相听起来也许有点吓人,但是我们正在做,因为没有别的能替代的。 PHP,Python
甚至 Ruby
(更不用说 Java
或 .NET
)都无法与具有 JavaScript
和异步I/O模型的 Node.js
相提并论。 多年来,Node
(和JavaScript)已经发展到可以满足行业要求。 是不是很完美? 但是,就像生活中的任何其他事物一样,编程语言也不是完美无缺的。
Deno
现在只是一个仅有2年开发迭代的产品。它尚未在生产环境中进行尝试,也尚未编写异常的测试用例来了解其如何处理边界情况。直到做到了这一点,它才能供早期尝试者使用。也许一年后,我们将看到有些公司开始分享他们的使用经验,他们如何解决新发现的缺点等。最终,社区将对其进行调整让它变得更有用,更受众。它会取代 Node.js
吗?我们拭目以待。