Deno 是什么
Deno 是一个简单、现代、安全的 JavaScript、TypeScript、Webassembly 运行时环境。
它是建立在:
- Rust(Deno 的底层是用 Rust 开发,而 Node 是用 C++)
- Tokio(Deno 的事件机制是基于 Tokio,而 Node 是基于 libuv)
- TypeScript
- V8
Deno 的背景
Deno 起源于 Node 的创建者 Ryan Dahl,这也是大家对 Deno 项目充满期待的原因之一。在 JSConfEu 上,Dahl 在他的的演讲中说出了自己对 Node 中存在的一些缺陷,并解释了如何围绕 Node 的架构做出更好的决定,在演讲的最后,宣布了 Deno 的第一个原型,并承诺构建一个更好、更安全的运行时环境。
Node 的缺陷
原生 API 缺少 Promise
Node 最大的亮点在于事件驱动, 非阻塞 I/O 模型,这使得 Node 具有很强的并发处理能力,非常适合编写网络应用。在 Node 中大部分的 I/O 操作几乎都是异步的,于是乎 Callback Hell 产生了:
若要实现链式调用,你需要使用 Promise 重新包装下原生 API,如下所示:
缺少安全性
在 Node 中,可以调用 fs.chmod 来修改文件或目录的读写权限。说明 Node 运行时的权限是很高的。如果你在 Node 中导入一份不受信任的软件包,那么很可能它将删除你计算机上的所有文件,所以说 Node 缺少安全模块化运行时。除非手动提供一个沙箱环境,诸如 Docker 这类的容器环境来解决安全性问题。
构建系统与 Chrome 存在差异
首先我们需要了解构建系统是啥?
写惯前端的童鞋可能不是很明白这个东西是干啥用的?但是其实平时你都会接触到,只是概念不同而已。前端我们一般称其为打包构建,类似工具诸如 webpack、rollup、parcel 做的事情。它们最后的目标其实都是想得到一些目标性的文件,这里我们的目标是编译 V8 代码。
Node 的 V8 构建系统是 GYP(Generate Your Projects),而 Chrome 的 V8 已升级为 GN(Generate Ninja)。我们知道 V8 是由 Google 开发的,这也证明 Node 和 Google 的亲儿子 Chrome 渐行渐远,而且 GN 的构建速度比 GYP 快20倍,因为 GN 是用 C++ 编写,比起用 python 写的 GYP 快了很多。但是 Node 底层架构已无法挽回。
复杂的包管理模式
Node 自带的 NPM 生态系统中,由于严重依赖语义版本控制和复杂的依赖关系图,少不了要与 package.json、node_modules 打交道。node_modules 的设计虽然能满足大部分的场景,但是其仍然存在着种种缺陷,尤其在前端工程化领域,造成了不少的问题。特别是不同包依赖版本不一致时,各种问题接踵而来,于是乎 yarn lock、npm lock 闪亮登场。
然而还是有很多场景是 lock 无法覆盖的,比如当我们第一次安装某个依赖的时候,此时即使第三方库里含有 lock 文件,但是 npm install|、yarn install 也不会去读取第三方依赖的 lock,这导致第一次创建项目的时候,还是会可能会触发 bug。而且由于交叉依赖,node_modules 里充满了各种重复版本的包,造成了极大的空间浪费,也导致 install 依赖包很慢,以及 require 读取文件的算法越来越复杂化。
读取文件复杂化
Node 使用 require 引用其他脚本文件,其内部逻辑如下:
可以看得出来,require 的读取逻辑是很复杂的,虽然用起来很可爱,但是没必要。
Deno 的架构
-
Deno 以 Rust 作为启动入口,通过 Rust FFI 去执行 C++ 代码,然后在 C++ 中引入 V8 实例。
-
初始化 V8 对象以及注入外部 C++ 方法,例如 send、recv 等方法。
-
向 V8 全局作用域下注入 Deno 对象,暴露 Deno 的一些基本 API 给 JavaScript。
-
通过绑定在 V8 上的 C++ 方法,调用对应的 Rust 方法,去执行底层逻辑。
不难发现 Deno 其实和 RN、Flutter 这些框架很类似,因为它本质上也是跑了个 JS 引擎,只是这个 JS 引擎是 V8,不负责 UI 的 binding 而已。所以说架构的本质就是思路复刻、模块重组。
Deno 的特点
安全
与 Node 相反,Deno 默认在沙箱中执行代码,这意味着运行时无法访问以下权限:
- 文件系统
- 网络
- 环境变量
你可以通过命令行参数形式来开启默认关闭的权限,类似下面这样:
或者通过编程形式控制权限,类似下面这样:
内置工具
Deno 目前提供了以下内置工具,在使用 JavaScript 和 TypeScript 时非常有用,只需要执行以下命令即可:
- deno bundler (自带打包和 tree shaking功能,可以将我们的代码打包成单文件)
- deno compile (将 Deno 项目构建为完全独立的可执行文件)
- deno installe (可以将我们的代码生成可执行文件进行直接使用)
- deno info (查看所有模块的依赖关系树)
- deno doc (将源代码中的注释生成文档)
- deno fmt (递归地格式化每个子目录中的每个文件)
- deno repl (启动一个 read-eval-print-loop,它允许您在全局上下文中交互式地构建程序状态)
- deno test (对名为 .test 的文件进行单元测试)
- deno lint (代码检测器)
支持 TyprScript
使用 Deno 运行 TypeScript 代码不需要编译步骤以及繁琐的配置文件—— Deno 会自动为你执行这一步骤。
源码中我们发现,Deno 其实是集成了一个 TypeScript 编译器和一个用于运行时快照的小型编译器主机。转换的核心代码如下:
前段时间 Deno 内部把 TS 改回 JS 的讨论很是热闹,但并不意味着 Deno 放弃了 TypeScript,它依然是一个安全的 TS/JS Runtime。
例如:
你可以直接在命令行运行并打印出 hello word:
支持 ES 模块标准
Deno 采用的是 ES Module 的浏览器实现。ES Module 大家应该都是比较熟悉的,它是 JavaScript 官方的标准化模块系统,其浏览器实现如下所示:
需要注意的是,Deno 不支持以下写法:
兼容浏览器 API
Deno 通过与浏览器 API 保持一致,来减少大家的认知。
- 模块系统:从上面的介绍看出 Deno 是完全遵循浏览器实现的。
- 默认安全
- 对于异步操作返回 Promise
- 使用 ArrayBuffer 处理二进制
- 存在 window 全局变量
- 支持 fetch、webCrypto、worker 等 Web 标准,也支持 onload、onunload、addEventListener 等事件操作函数
支持 Promise
Deno 所有的异步操作,一律返回 Promise,并且全局支持 await。
去中心化包
Deno 没有 package.json、node_modules,那么它是怎么进行包管理的呢?我们先看下面的例子:
我们看到执行时会有 Download
和 Compile
两个步骤,于是乎我们会产生几个疑问:
1、每次执行都要下载吗?
答:不需要每次下载,有缓存机制。
2、Download 和 Compile 的文件在哪里呢?
答:我们可以通过上面介绍的自带工具 deno info 来查看依赖关系。
3、依赖代码更新了怎么办?
答:当依赖模块更新时,我们可以通过 --reload
进行更新缓存,例如:
4、多版本怎么处理?
答:暂时没有好的解决方案,只能通过 git tag 的方式区分版本。
Deno 是通过 URL 导入代码,可以在互联网上的任何地方托管模块。并且相比 Node 的 require 读取文件,它显得更加轻巧玲珑,并且无需集中注册表即可分发 Deno 软件包。不需要 package.json 文件和依赖项列表,因为所有模块都是在应用程序运行时下载,编译和缓存的。
上手 Deno
安装
使用 Shell (macOS 和 Linux):
使用 PowerShell (Windows):
运行 deno --version,如果它打印出 Deno 版本,说明安装成功。
实战体验
Hello Word
本地创建一个 index.ts 文件,内容如下所示:
打开终端,输入以下命令行:
以上输出 "Welcome to Deno ?"。
HTTP 请求
本地创建一个 http.ts 文件,内容如下所示:
打开终端,输入以下命令行:
以上输出 json 对象。
远程导入
从远程模块导入 add 和 multiply 方法:
支持 WASM
打开终端,输入以下命令行:
以上输出数字42。
RESTful 服务
终端输入以下命令:
本地访问 http://localhost:8000/book/1 将会返回id为1的book数据。
静态资源服务
终端输入以下命令:
本地访问 http://localhost:8000/static.ts 将会返回 static.ts 的源码。
结束语
Deno 是一个非常伟大的项目,但却不是 “下一代 Nods.js ”。Ryan Dahl 自己也说: “Node.js isn't going anywhere” 。并且 Deno 还处在开发中,功能还不稳定,不建议用于生产环境。但是,它已经是一个可用的工具,有很多新特性都是 Node 所没有的,大家可以多多试玩。
推荐阅读
数据可视化探索之 SpreadJS
H5 页面列表缓存方案
招贤纳士
政采云前端团队(ZooTeam),一个年轻富有激情和创造力的前端团队,隶属于政采云产品研发部,Base 在风景如画的杭州。团队现有 40 余个前端小伙伴,平均年龄 27 岁,近 3 成是全栈工程师,妥妥的青年风暴团。成员构成既有来自于阿里、网易的“老”兵,也有浙大、中科大、杭电等校的应届新人。团队在日常的业务对接之外,还在物料体系、工程平台、搭建平台、性能体验、云端应用、数据分析及可视化等方向进行技术探索和实战,推动并落地了一系列的内部技术产品,持续探索前端技术体系的新边界。
如果你想改变一直被事折腾,希望开始能折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变既定的节奏,将会是“5 年工作时间 3 年工作经验”;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊… 如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的前端团队的成长历程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 ZooTeam@cai-inc.com
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!