本篇文章参考以下博文
前段时间 Deno1.0 发布了,作为前端小白,连 Node 都还没掌握熟练,不知道哪来的勇气,居然对 Deno 蠢蠢欲动。可能由于最近处在学习 Node 的蜜月期,对于这方面知识兴致正浓,所以就翻了 Deno 的牌子。写下本篇博客,记录一下我的作死学习路。
Deno 的创作者,也是 Node 的创作者之一,Ryan Dahl,Web 界的一名天降猛男。
创建出 Node 之后,在最火的时代,转战 GO 专心研究人工智能。现在回来再捡起 Node 发现这个项目已经背离了他的初衷,有一些无法忽视的问题。
首先 JavaScript 语言脱胎换骨,ES6 标准引入了大量新的语法特性。其中,影响最大的语法有两个:Promise 接口(以及 async 函数)和 ES 模块。
Node 对于上面两个语法不太友好,Node 必须支持回调函数(callback ),导致异步接口会有 Promise 和回调函数两种写法;同时,Node 自己的模块格式 CommonJS 与 ES 模块不兼容,导致迟迟无法完全支持 ES 模块。
最终由于 Node 的种种问题,这位猛男决定从头写一个替代品,解决这些问题。Deno 应运而生。
使用 Shell ( macOS 和 Linux ):
curl -fsSL https://deno.land/x/install/install.sh | sh
使用 PowerShell ( Windows ):
iwr https://deno.land/x/install/install.ps1 -useb | iex
更新与更新到指定版本
deno upgrade
deno upgrade --version 1.0.1
Deno 相比于 Node ,默认是安全的,这就决定了 Deno 的权限要专门去启用,尤其对于一些敏感区域或功能,需要使用在命令行上授予 deno 进程的权限。
可以使用以下权限:
-A,-- allow -all 允许所有权限。这将禁用所有安全性。
--allow-env 允许环境访问,例如获取和设置环境变量。
--allow-hrtime 允许高分辨率时间测量。高分辨率时间可用于定时攻击和指纹识别。
--allow-net = <允许网络> 允许网络访问。您可以指定一个可选的,用逗号分隔的域列表,以提供允许域的允许列表。
--allow-plugin 允许加载插件。请注意–allow-plugin是一个不稳定的功能。
--allow-read = <允许读取> 允许文件系统读取访问。您可以指定目录或文件的可选逗号分隔列表,以提供允许的文件系统访问的允许列表。
--allow-run 允许运行子进程。请注意,子流程未在沙箱中运行,因此没有与deno流程相同的安全限制。因此,请谨慎使用。
--allow-write = <允许写> 允许文件系统写访问。您可以指定目录或文件的可选逗号分隔列表,以提供允许的文件系统访问的允许列表。
Deno run --allow-read mod.ts //允许读取文件
Deno 支持与浏览器兼容的生命周期事件: load 和 unload 。我们可以使用这些事件在程序中提供设置和清除代码。这意味着, Deno 可以访问到 window 作为全局对象了, Node 的全局对象是 global ,而 JS 中又没有 global 对象, 之前会存在一些不统一的情况,比如在服务端渲染的时候, node 就不会解析 window ,而且要避免把 window 写入到 node 的模板字符串中,防止解析报错。
import "./imported.ts";
const handler = (e: Event): void => {
console.log(`got ${
e.type} event in event handler (main)`);
};
window.addEventListener("load", handler);
window.addEventListener("unload", handler);
window.onload = (e: Event): void => {
console.log(`got ${
e.type} event in onload function (main)`);
};
window.onunload = (e: Event): void => {
console.log(`got ${
e.type} event in onunload function (main)`);
};
console.log("log from main script");
Deno 支持 async 啦!!!可喜可贺,解决了 Node 的一个头疼问题
import {
delay } from "https://deno.land/[email protected]/async/delay.ts";
Deno.test("async hello world", async () => {
const x = 1 + 2;
// await some async task
await delay(100);
if (x !== 3) {
throw Error("x should be equal to 3");
}
});
在 Deno 中,没有包管理器的概念,外部模块会直接导入到本地模块中。这就提出了一个问题,即如何在没有包管理器的情况下管理远程依赖关系。在具有许多依赖性的大型项目中,如果将模块全部单独导入到单个模块中,则更新模块将变得繁琐且耗时。( Node 中模块依赖管理就很头疼)
在 Deno 中解决此问题的标准做法是创建一个 deps.ts 文件。此文件中引用了所有必需的远程依赖关系,并且重新导出了所需的方法和类。然后,从属本地模块将引用 deps.ts 而不是远程从属。
这样就可以轻松跨大型代码库更新模块,并解决“程序包管理器问题”(如果存在)。开发依赖项也可以在单独的 dev_deps.ts 文件中进行管理。
/**
* deps.ts re-exports the required methods from the remote Ramda module.
**/
export {
add,
multiply,
} from "https://x.nest.land/[email protected]/source/index.js";
本文只是整理了一些 Node 中的痛点问题,其实 Deno 的功能远不止这些,包括 TypeScript , ES6 等功能, Deno 都做了适配和兼容,不过现在有个比较凸显的问题是,目前 Deno 不兼容 Node ,这就有点头疼,不利于后期的发展部署,不过对于一项新技术,有很多问题需要处理,期待后续的版本中 Deno 还能带来一些意外的惊喜。
文中不足支持,欢迎各位前辈指点,我会及时改正。