Deno源码简析(一)架构

代码探风鹤
• 阅读 3646

开始

感觉又很久很久没写东西了,心里有点忐忑不安:一直埋头工作而不去学习新知识可是程序员的大忌,刚好Deno又正式发布1.0,所以忙里偷闲也要学习一下,那么今天就是带来一波简单的Deno源码分析。

Deno vs Node.js

有人说Deno就是Destroy Node的缩写就是为了替代Node.js而生,也有人说Deno目前不成熟并不能替代现在的Node.js等等;自从Ryan指出Node.js的十大问题并且公开了新的项目Deno,在某乎上立马就展开各种(友好)讨论。不过无论怎么样,有竞争才有进步,Deno已经作为一个挑战者走进我们的视野,我们只需客观正视它的优缺点就好了。
不过个人的一些看法,Deno的出现基本意味着这是一场死斗,因为彼此基本特性实在太相似了:v8引擎,单线程异步,背靠着js的生态圈...,基本意味着开发者选择两者其一就永远不需要考虑其二,长远来看用户群可能会分裂吧;而Deno目前在这个基础上主打的是稳定性和安全性,这是服务端开发所必须的,只有满足这两个要求基础上才能去追求更高的性能,所以现在Deno的性能从官方的测试来看跟Node.js比还是有一段距离,但是个人并不太担心这一块性能差距,迟早也是会慢慢赶上来的,毕竟才1.0嘛。

前置知识

准备深入Deno部分知识还是要提前准备一下的:

  • Typescript(对于前端开发大多没啥压力)
  • Rust(主打安全和高性能的语言,学习曲线奇高,长期被编译器教做人)
  • V8引擎(Isolate,Context,Handle等等概念常记心里)

不得不说,其实rust就是Deno和Node.js分界点,感觉Deno的一个潜在目标就是把Deno的生态与rust的生态捆绑在一起,这样Deno一开始的生态比较弱的问题也可以得到一些缓解吧,另外对于前端来说迟早也是需要学习一门静态语言的,rust也是一个不错的选择(rust可是StackOverflow最受欢迎的语言)。

Deno的架构

直接贴上官网的架构图:
Deno源码简析(一)架构
这里官方的架构图还没来得及更新,libdeno已经替换成rusty_v8,这样意味着我们开发native插件的时候可以完全绕过了c/c++,直接使用rust就可以完成功能开发(加上rust本身自带一个可靠强大的标准库更加得心应手),当然开发者还是需要了解V8引擎相关的知识了。
再回到架构图上,我们知道Node.js是由libuv提供调度和io的能力,那么在Deno上这个角色就由rust的Tokio库提供相似的能力,而一开始Deno还是想使用go语言来提供这样的能力(Ryan果然是go语言的真粉),但是毕竟go语言也是带gc的(一个应用上同时跑两个gc,稳定性实在很难想象)而且性能上也是差rust一截,后面替换成rust也是相当明智的,另外Tokio其实对比libuv也是毫不逊色的(任务调度算法也是参考了go语言的实现)
另外在Deno里面js与rust的交互都会通过Deno.core.send和Deno.core.recv这两个方法,这样做对于应用做审计和权限控制是非常有好处,后面再会分析js和rust是如何交互的。最后例如js异步读取文件这些操作都会扔到Tokio线程池中执行,这也是Deno实现非阻塞的关键点。
然后Deno为了安全的原因,对资源都做了一层映射,原本系统的文件描述符或者其他资源都映射成了一个rid(非负整数),对资源的操作都需要通过rid进行。

|                       **Linux** | **Deno**                         |
| ------------------------------: | :------------------------------- |
|                       Processes | Web Workers                      |
|                        Syscalls | Ops                              |
|           File descriptors (fd) | [Resource ids (rid)](#resources) |
|                       Scheduler | Tokio                            |
| Userland: libc++ / glib / boost | https://deno.land/std/           |
|                 /proc/\$\$/stat | [Deno.metrics()](#metrics)       |
|                       man pages | deno types                       |

好吧,把所有的概念汇集在一起,跟Linux一对比,就会发现Deno真的很有意思了,难道是想要变成一个轻量级js应用平台吗?官方文档透露的信息实在太少了,感觉一些设计意图也没有表达出来,希望文档能够再详细一点就好了。

项目结构

.
├── cli //负责实现各种接口,包括兼容浏览器和Deno.xxx的接口
├── core //负责实例化和执行模块代码,处理js与rust之间交互还有实现event-loop
├── deno_typescript //负责编译打包typescript文件和生成v8的snapshot
├── docs //文档
├── std //std标准库
├── target
├── test_plugin
├── third_party
└── tools

自己再整理里面各个模块的依赖关系,大致如下:
Deno源码简析(一)架构

当然发现更有趣的是std目录下还有有一个node的模块:

.
├── README.md
├── _fs
├── _utils.ts
├── events.ts
├── events_test.ts
├── fs.ts
├── global.ts
├── module.ts
├── module_test.ts
├── os.ts
├── os_test.ts
├── path.ts
├── process.ts
├── process_test.ts
├── querystring.ts
├── querystring_test.ts
├── tests
├── timers.ts
├── util.ts
└── util_test.ts

是不是看到这些文件名称就有一种相当熟悉的感觉,嗯,这就是deno为了兼容node模块所做的一个兼容层,虽然还没有完成,不过至少也知道deno也是有这个意愿去兼容node的模块,或许在下一个版本我们就能看到deno能够直接使用node的模块去开发应用了。

结束

暂时先介绍到这里,好像一点也没有深入到代码,真的是标题党,哈哈,下一篇文章再来深入代码分析。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Alex799 Alex799
4年前
Deno 运行时入门教程:Node.js 的替代品
Deno运行时入门教程:Node.js的替代品作者:日期:这几天假期,我学习了一下。它是Node.js的替代品。有了它,将来可能就不需要Node.js了。这篇文章就是Deno的一个初步介绍,尝试回答为什么Node.js不能满足需要,以及Deno能够带给我们什么?以下内容主要基于
洛竹 洛竹
4年前
Deno GitHub Action 源码解析
GitHubAction是GitHub官方的CI/CD工具,相较于TravisCI和CircleCI,更轻量和易于扩展,中有大量社区贡献的插件。各大开源项目都纷纷转向使用GitHubAction作为持续集成的工具,比如本文的主角Deno。GitHub的文档中有很多概念写的十分晦涩,有些翻译很僵硬影响理解。截止发稿时,Deno
洛竹 洛竹
4年前
向 Deno 学习脚本的管理
前言🌱如果你使用过Deno、Go或者配置过AndroidStudio,那么你一定对配置环境变量不陌生。那么如果我们自己写了一个脚本或者命令行工具,如何分享给朋友们玩呢?最简单的当然是直接把脚本放出去,供别人手动下载和手动配置环境变量。但这既不优雅,也不利于传播,本文就是研读了Deno的安装机制后,总结出的一套可用的二进制可执行文件分发教程
洛竹 洛竹
4年前
基于 Go 实现 Deno upgrade
书接上篇,我在中向大家介绍了Deno是如何管理它的安装包的——以Githubrelease的形式发布、执行编写好的shell脚本安装程序以及基于tags的版本管理。有版本管理就会有更新的需求,本文就是在研读了Deno的upgrade命令后使用Go语言实现了自己的upgrade命令。获取最新版本我们先来看下Deno
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Easter79 Easter79
3年前
TypeScrip最污的技术课
!alt(https://usergoldcdn.xitu.io/2018/9/21/165f98863487350a?imageView2/0/w/1280/h/960/format/webp/ignoreerror/1)近日Node.js之父瑞安达尔(RyanDahl)发布新的开源项目deno,从官方介绍来看,可以认为它是下一代Nod
Stella981 Stella981
3年前
Deno TCP Echo Server 是怎么运行的
创建了一个“重学TypeScript”的微信群,想加群的小伙伴,加我微信 "semlinker",备注重学TS。在“了不起的Deno入门教程”这篇文章中,我们介绍了如何使用Deno搭建一个简单的TCPechoserver,本文将使用该示例来探究TCPechoserver是怎么运行
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(