本文主要讲解“为什么要开发Deno”,感兴趣的朋友不妨看看。本文介绍的方法简单、快速、实用。让边肖带你学习“为什么要发展Deno”!
0. 为什么开发 Deno?
这是我上周做的一张图片,介绍了JavaScript的发展历史。刚才修改了,增加了Node.js和Deno发布时间的标注。
Node.js和Deno分别是Ryan Dahl在2009年和2018年基于当年的前端技术开发的非浏览器JavaScript运行时* * *。
Ryan Dahl开发deno并不是因为“只是为了好玩”,也不是为了替代node。下面慢慢解释。
1. 目前 deno 只是一个 demo
花了两天时间看了deno的源代码(还好是初级阶段,源代码很少很容易理解),顺带看了所有的问题和pr。不知道“根据官方介绍,可以认为是下一代Node”是怎么发明的。
既然是Node.js的父亲新作,那么Node.js在讨论中必不可少。而作者很皮的回复到:
主要区别是Node工作,Deno不工作(:)
* * *区别是:Node可以工作,Deno不行(:)
目前Deno只是一个Demo,甚至没有二进制分布。幸运的是,从源代码编译相对简单(如果您没有使用Windows系统)。
在高层,Deno提供了一个尽可能简单的V8到系统API的绑定。为什么用Golang而不用C,因为与Node相比,Golang让我们更容易添加新功能,比如http2。
至于为什么不选Rust,笔者没有回答。
让我们比较一下两者的启动性能。单独运行:
控制台日志(' hello world ')
差距还是很大的。毕竟,deno需要加载一个TypeScript编译器。毕竟是演示版,希望以后能优化一下。
性能提升的另一个思路是,LLVM可以作为后端编译器,将TypeScript代码编译成WebAssembly,然后在V8中运行,甚至可以直接将源代码编译成二进制代码运行。Ryan Dahl说deno只需要一个编译器,就是TS。但是由于deno是浏览器兼容的,所以也应该支持WebAssembly。
Deno可以缓存ts (~/)的编译结果。deno/cache),所以目前我们重点关注启动速度和初始编译速度。
或者先编译再发布,这样deno就脱离了开发的初衷。Deno是ts运行时,所以应该可以直接运行ts代码。如果ts提前编译成js,那么deno将返回js运行时。
2. 初学者应该学习 Node.js 还是 Deno?
瑞安达尔对这个问题给出了一个简洁的答案:
使用节点。Deno是一个原型/实验。
使用节点。Deno只是一个原型或实验产品。
从介绍中可以看出,Deno的目标不是兼容Node,而是兼容浏览器。
因此,Deno不会取代Node.js,也不会成为下一代Node.js,更不会放弃npm,重建Node生态。Deno目前的目标是拥抱浏览器生态。
不得不说,这个目标真的很伟大。Ryan Dahl开发了Node.js,社区构建了整个npm生态。在对justjavac的另一个回答中:在纯前端开发的眼中,nodejs是什么?上面写着“Node.js是前端工程的重要支柱之一”。
虽然Ryan Dahl离开Node.js去了Golang社区,但现在Ryan Dahl回来了,把Golang带到了JavaScript社区,开发了Deno,拥抱了浏览器生态。
让我们看看deno的网络应用编程接口的目标:
ft-2">
High level
-
Console √
-
File/FileList/FileReader/Blob
-
XMLHttpRequest
-
WebSocket
Middle level
-
AudioContext/AudioBuffer
-
Canvas
甚至还会包括 webGL 和 GPU 等的支持。
3. Deno 的架构
Parsa Ghadimi 绘制了一张关于 Deno 的架构图:
底层使用了作者开发的 v8worker2,而 event-loop 则基于 pub/sub 模型。
我比较好奇的是 deno 使用了 protobuf,而没有使用 Mojo。既然目标是要兼容浏览器,却不使用 Mojo,而是要在 protobuf 上重新造轮子,可见 Ryan Dahl 是真正的“轮子哥”啊。但是从 issue 中可以看出,Ryan Dahl 之前是没有听说过 Mojo 的,但是他看完 mojo 之后,依然觉得 protobuf 的选择是正确的。
Mojo 是 Google 开发的新一代 IPC 机制,用以替换旧的 Chrome IPC。目前 Chrome 的***版本是 67,而 Google 的计划是在 2019 年的 75 版本用 mojo 替换掉所有的旧的 IPC。
Mojo 的思路确实和 protobuf 毕竟像,毕竟都是 Google 家的。旧的 IPC 系统是基于在 2 个进程(线程)之间的命名管道(IPC::Channel)实现的。这个管道是一个队列,进程间的 IPC 消息按照先进先出的顺序依次传递,所以不同的 IPC 消息之间有先后次序的依赖。相比之下,Mojo 则为每一个接口创建了一个独立的消息管道,确保不同接口的 IPC 是独立的。而且为接口的创建独立的消息管道的代价也并不昂贵,只需分配少量的堆内存。
Mojo 的架构设计:
我们可以看一下 Chrome 引入 Mojo 之后的架构变化。
之前:
之后:
是不是有点微服务的感觉。
熟悉 Java 的 Spring 的可以明显看出这个依赖倒置。Blink 本来是浏览器***层的排版引擎,通过 Mojo,Blink 变成了要给中间模块。最近大热的 Flutter 也是基于 Mojo 架构的。
4. TypeScript VS JavaScript
deno 的介绍是一个安全的 TypeScript 运行环境。但是我们看源码就会发现,deno 集成进了一个 TypeScript 编译器,而入口文件中 ry/deno:main.go
// It's up to library users to call // deno.Eval("deno_main.js", "denoMain()") func Eval(filename string, code string) { err := worker.Load(filename, code) exitOnError(err) } // It's up to library users to call // deno.Eval("deno_main.js", "denoMain()") func Eval(filename string, code string) { err := worker.Load(filename, code) exitOnError(err) }
使用 V8 运行的 deno_main.js 文件。是 JavaScript 而不是 TypeScript 。
在前面的分析中我们知道这会影响 deno 的初次启动速度。那么对于执行速度呢?从理论上,TypeScript 作为一种静态类型语言,编译完成的 JavaScript 代码会有更快的执行速度。我之前在《前端程序员应该懂点V8 知识》曾经提到过 V8 对于 JavaScript 性能提升有一项是 Type feedback。
当 V8 执行一个函数时,会基于函数传入的实参(注意是实参,而不是形参,因为 JavaScript 的形参是没有类型的)进行即时编译(JIT):
但是当后面再次以不同的类型调用函数时,V8 会进行去优化(Deopt)操作。
(将之前优化完的结果去掉,称为“去优化”)
但是如果我们使用 TypeScript ,所有的参数都是由类型标注的,因此可以防止 V8 引擎内部执行去优化操作。
5. 对 deno 性能的展望和猜想
虽然 TypeScript 可以避免 V8 引擎的去优化操作,但是 V8 执行的是 ts 编译后的结果,我们通过字节码或者机器码可以看到,V8 依然生成了 Type Check 的代码,每次调用函数之前,V8 都会对实参的类型进行检查。也就是说,虽然 TypeScript 保证了函数的参数类型,但是编译成 JavaScript 之后,V8 并不能确定函数的参数类型,只能通过每次调用前的检查来保证参数的类型。
其次,当 V8 遇到函数定义时,并不知道参数的类型,而只有函数被调用后,V8 才能判断函数的类型,才对函数进行 Typed 即时编译。这里又有一个矛盾了,typescript 在函数定义时就已经知道了形参的类型,而 V8 只有在函数调用时才根据实参的类型进行优化。
所以,目前 deno 的架构还存在很多问题,毕竟只是一个 demo。未来还有很多方向可以优化。
V8 是一个 JavaScript 运行时,而 deno 如果定义为“安全的 TypeScript 运行时”,至少在目前的架构上,性能是有很大损失的。但是目前还不存在一个 TypeScript 运行时,退而求其次只能在 V8 前面放一个 TypeScript 编译器了。
执行流程是这样的:
虽然我在项目中没有使用过 TypeScript ,但是基本上我在项目里面写的第三方库都会提供一d.ts 文件。目前 TypeScript ***的用途还是体现在开发和维护过程中。
我们想到的一个方式就是 fork 一份 V8 的源码,然后把编译流程整合进去。TypeScript 在编译为 JavaScript 的过程中也需要一份 AST,然后生成 js 代码。V8 执行 js 代码是再 parse 一份 AST,基于 AST 生成中间代码(ByteCode)。如果 TypeScript 可以直接生成对用的字节码则会提升运行时的性能。
不过 Ryan Dahl 大概不会这么干。但是也未必,毕竟社区已经把 TypeScript 的一个子集编译为 WebAssembly 了。
之前微软的 JScript 和 VBScript 在和 JavaScript 的竞争中败下阵来,而现在 TypeScript 势头正猛。虽然对 ES 规范的兼容束缚了 TypeScript 的发展,但很期待微软可以提供一个 TS 运行时,或者在 Chakra 引擎增加对 TS 运行时的支持。
到此,相信大家对“为什么开发Deno”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/83250.html