专栏名称: __ihhu
前段
目录
相关文章推荐
歸藏的AI工具箱  ·  终于有给设计师用的 Cursor 了 ·  昨天  
歸藏的AI工具箱  ·  终于有给设计师用的 Cursor 了 ·  昨天  
前端早读课  ·  【第3454期】如何用语音学习编程的 ·  昨天  
前端大全  ·  真的建议所有前端立即拿下软考(红利期) ·  5 天前  
前端大全  ·  Create React ... ·  6 天前  
51好读  ›  专栏  ›  __ihhu

襁褓中的 deno(零):初次见面,多多关照

__ihhu  · 掘金  · 前端  · 2018-06-04 05:49

正文

Tips: deno 项目现在属于飞速发展的阶段,源码随时可能更新,所以这篇文章中的代码只是作为说明需要,和项目中的代码不保持同步。展示代码只保留核心,异常检查等会酌情删去。

最近前端风起云涌, Ryan Dahl 大佬的 deno 甫一开源就引起了巨大的关注,甚至引发了一些不太好的刷 issue 事件。不过 deno 这一席华美的袍之下,到底隐藏着什么呢?这个系列文章就结合源码来对 deno 的做一点简单的分析与梳理,也算是一份学习笔记了。


deno 是什么?

这个问题非常好回答,在 deno 的 GitHub 主页 上有着非常明确的定义: A secure TypeScript runtime on V8 ,也就是 一个基于 v8 的 TypeScript 运行时 。单纯看定义,可能有些盆友会发出「每个字都能看懂但是合在一起就不懂」的感慨,不过我们可以采用类比法来理解这个定义。

在 Node.js 的 GitHub 主页 上,写着一段相似的定义: Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js 是一个基于 v8 的 JavaScript 运行时 。这么一对比就非常明显了, deno 和 node 的定位相似,都是一个「运行时」,而且底层都是基于知名的 JS 引擎 v8,不过一个支持 TS,一个支持 JS。举个最简单的例子,我们可以写出这样的代码:

// hello.ts
const name: string = "yingying";
console.log(name);

然后我们可以用 deno 的可执行文件来运行这个 hello.ts 代码文件

 $ deno ./hello.ts
 yingying

有个很有意思的点,Node 和 deno 在名字上只是简单地调换了一下字母顺序,这更是说明了两者的兄弟关系 :) 。


deno 有什么特点?

Node 之父选择再做一个定位与 Node 类似的运行时出来,这肯定是有很多理由的,正巧在 jsconf 2018 上,Ryan Dahl 专门阐述了他设计 deno 的原因,感兴趣的可以阅读 Design Mistakes in Node 这篇 PPT,我这里只是针对 deno 的主要特点进行简单的描述和解释。

安全

这里所说的安全不止是二进制代码安全,还包括比较容易被人忽视的 IO 安全。

在 Node 中我们可以利用 vm 来构建沙盒运行环境,然后调用 vm 上的相关方法来执行相应操作。而在 deno 中则是隔离地更为彻底,我们只能通过消息的发送与接收来进行系统调用,将恶意代码完全隔绝在实现层(go、c++)而不是调用层(ts)之中。

除此之外,在 deno 中运行的 ts 代码将默认没有网络请求和文件读取的权限,用户必须在运行代码的时候手动加上 --allow-net --allow-write 等 flags 来开启相应的权限,这样可以更安全地运行第三方的代码。

简化模块系统

Ryan 认为 Node 的模块系统太过繁琐复杂, package.json 文件更是包含了过多的冗余信息,所以在 deno 中,模块系统选择向 go 看齐,通过 url 或者相对路径来引用文件,并且需要指定文件的格式,而不再像 Node 中的利用 resolve 算法 来进行文件路径补全。通过网络加载的文件会被缓存,下次引入会直接加载缓存文件。而模块的版本控制则是通过在包名中加入语义化版本号来实现,比如 https://unpkg.com/[email protected]/testing.ts , 去中心化的版本控制可以实现更细粒度的依赖管理。

面向 TypeScript

没有人不喜欢 TypeScript

在 8102 年,TypeScript 已经毫无争议地成为了(前端)新项目开发和老项目重构的 dream language,关于它的优点够再写一篇文章了,所以这里就按下不表。deno 中 主要是修改了一些 TS compiler 中的钩子函数,以支持新的模块查找策略。比如 fileExists :

class TypeScriptHost implements ts.LanguageServiceHost {
    // ts 转换器的钩子函数之一
    fileExists(fileName: string): boolean {
      // 这里的 resolveModule 就是自定义的模块解析函数
      const m = resolveModule(fileName, ".");
      const exists = m != null;
      util.log("fileExist", fileName, exists);
      return exists;
    }
}

deno 的不足

deno 本身虽然说是「TS runtime」,但是由于基于的运行引擎是一个 JS 的引擎(V8),所以需要在 runtime 保持一个 ts compiler,来自动地将 ts 转译为 js ,最后交给 v8 来执行,这无疑增加了启动性能与运行的性能,关于这一点的讨论可以参见 Compare bootstrap speed with Node.js







请到「今天看啥」查看全文