Node与Deno brotherhood of man

542 阅读17分钟

deno 这个名字就是来自 Node 的字母重新组合(Node = no + de),表示"拆除 Node.js"(de = destroy, no = Node.js)

Deno 是 Ryan Dahl 在2017年创立的,2020年正式上线了1.0版本。

1 Ryan Dahl 也是 Node.js 的创始人,从2007年一直到2012年,他后来把 Node.js 移交给了其他开发者,不再过问了,转而研究人工智能。他始终不是很喜欢 Python 语言,久而久之,就想搞一个 JavaScript 语言的人工智能开发框架。等到他再回过头捡起Node.js,发现这个项目已经背离了他的初衷,有一些无法忽视的问题。

2 首先,过去五六年,JavaScript 语言脱胎换骨,ES6 标准引入了大量新的语法特性。其中,影响最大的语法有两个:Promise 接口(以及 async 函数)和 ES 模块。Node.js 对这两个新语法的支持,都不理想。由于历史原因,Node.js 必须支持回调函数(callback),导致异步接口会有 Promise 和回调函数两种写法;同时,Node.js 自己的模块格式 CommonJS 与 ES 模块不兼容,导致迟迟无法完全支持 ES 模块。其次,Node.js 的模块管理工具 npm,逻辑越来越复杂;模块安装目录 npm_modules 极其庞杂,难以管理。Node.js 也几乎没有安全措施,用户只要下载了外部模块,就只好听任别人的代码在本地运行,进行各种读写操作。再次,Node.js 的功能也不完整,导致外部工具层出不穷,让开发者疲劳不堪:webpack,babel,typescript、eslint、prettier......

3 由于上面这些原因,Ryan Dahl 决定放弃 Node.js,从头写一个替代品,彻底解决这些问题。deno 这个名字就是来自 Node 的字母重新组合(Node = no + de),表示"拆除 Node.js"(de = destroy, no = Node.js)。跟 Node.js 一样,Deno 也是一个服务器运行时,但是支持多种语言,可以直接运行 JavaScript、TypeScript 和 WebAssembly 程序。它内置了 V8 引擎,用来解释 JavaScript。同时,也内置了 tsc 引擎,解释 TypeScript。它使用 Rust 语言开发,由于 Rust 原生支持 WebAssembly,所以它也能直接运行 WebAssembly。它的异步操作不使用 libuv 这个库,而是使用 Rust 语言的 Tokio 库,来实现事件循环(event loop)。

4 你可能会问,为什么使用 Rust,而不是 C++(Node.js 的开发语言)?主要原因是 Rust 提供了很多现成的模块,对 Deno 项目来说,可以节约很多开发时间。

5、Deno 本身也是 Rust 的一个模块。如果你想在 Rust 里面使用 V8 引擎,就可以加载 Deno。它等于是一个 V8 的包装层,提供一些底层 API,让你跟 V8 引擎互动。

6、Deno 只有一个可执行文件,所有操作都通过这个文件完成。它支持跨平台(Mac、Linux、Windows)。

7、Deno 具有安全控制,默认情况下脚本不具有读写权限。如果脚本未授权,就读写文件系统或网络,会报错。必须使用参数,显式打开权限才可以。

--allow-read:打开读权限,可以指定可读的目录,
比如--allow-read=/temp。
--allow-write:打开写权限。
--allow-net=google.com:允许网络通信,可以指定可请求的域,比如--allow-net=google.com。
--allow-env:允许读取环境变量

8. Deno 支持 Web API,尽量跟浏览器保持一致。

它提供 window 这个全局对象,同时支持 fetch、webCrypto、worker 等 Web 标准,也支持 onload、onunload、addEventListener 等事件操作函数。 此外,Deno 所有的异步操作,一律返回 Promise。

9、Deno 只支持 ES 模块,跟浏览器的模块加载规则一致。没有 npm,没有 npm_modules 目录,没有require()命令(即不支持 CommonJS 模块),也不需要package.json文件。所有模块通过 URL 加载,比如import { bar } from "foo.com/bar.ts"(绝对 URL)或import { bar } from './foo/bar.ts'(相对 URL)。因此,Deno 不需要一个中心化的模块储存系统,可以从任何地方加载模块。但是,Deno 下载模块以后,依然会有一个总的目录,在本地缓存模块,因此可以离线使用。

10、由于 Deno 只支持从 URL 加载模块,导致 Node.js 的模块加载写法都会失效。上面的写法在 Deno 里面都是非法的。Deno 的所有模块都要通过入口脚本加载,不能通过模块名加载,所以必须带有脚本后缀名。Deno 原生支持 TypeScript 语言,可以直接运行,不必显式转码。它的内部会根据文件后缀名判断,如果是.ts后缀名,就先调用 TS 编译器,将其编译成 JavaScript;如果是.js后缀名,就直接传入 V8 引擎运行。

import React from "react";
import { Box, Grid } from "@material-ui/core";
import { initializeApp } from "firebase/app";

Deno 内置了开发者需要的各种功能,不再需要外部工具。打包、格式清理、测试、安装、文档生成、linting、脚本编译成可执行文件等,都有专门命令。 执行deno -h或deno help,就可以显示 Deno 支持的子命令。

deno bundle:将脚本和依赖打包
deno eval:执行代码
deno fetch:将依赖抓取到本地
deno fmt:代码的格式美化
deno help:等同于-h参数
deno info:显示本地的依赖缓存
deno install:将脚本安装为可执行文件
deno repl:进入 REPL 环境
deno run:运行脚本
deno test:运行测试

Node.js发展史

取名Node:主要重构:程序名称现在为“ node”Ryan Dahl在2009/3/3的这次代码提交将蛋壳中的NodeJS项目命名为node,从此,世界上多了一个Node.js

2009年

讨论npm(Node程序包管理器):npm的第一个非常早期的预览,Node程序包管理器 首次公开宣布:Ryan Dahl(Node.js的创建者)原创Node.js演讲 包管理器是第一件要考虑的事情,目的在于解决代码替换的问题:

有很多非常有用的模块,但是现在要同时使用多个模块是很棘手的。

通过一套模块定义规范来实现补充,目标是:

易声明易公开:很容易定义一个程序包并公开出去 易安装易引用:要能轻易引用开源模块,而不需要提供太多的package元信息,并且装完之后能够很方便地引用其功能 即取即用:package的版本,验证,配置,安装位置等都不必担心,所有对可用没有明显影响的问题都应该替换 集中管理:共享同一个软件包,方便维护 彻底今(2019/6/29)为止,npm仍具有这些特征,也是早期设计所决定的

同年,Ryan Dahl在JSConf发表了关于Node.js的首次公开演讲,尝试走出去

2010年

Express诞生:Express:一个Node.js Web开发框架 Socket.io诞生:Socket.io初始版本 Heroku提供Node.js支持:Heroku上的实验性Node.js支持 第二次公开演讲:Ryan Dahl在Node.js上的Google技术讲座 Node.js发布v0.2.0:Node.js 0.2.0发布 Express与Socket.io是生态发展的必然成果,Express作为Node.js生态中资格最老的Web开发框架,仍然存在一些难以替代的优势(尽管成熟可靠的生态支持)

Heroku对Node.js提供了实验性的支持,这意味着走出去了一小步。同时,一边推广(Google Tech Talk),一边持续替换(迭代v0.2.0)

2011年

出现新手教程:Node.js指南
创立论坛:Ryan Dahl在Reddit上的AMA
npm正式发布:npm 1.0:发布了
出现新手教程电子书:Node.js简介的Node Beginner Book现已完成
推广生产使用:LinkedIn使用Node.js
讲述Node.js的故事:Ryan Dahl谈到Node.js的历史以及他为什么创建它
又一个大型企业用了起来:Uber生产中的Node.js

一级新手教程的出现意味着大家发现了Node.js的(学习)价值,之后LinkedIn,Uber陆续上船更是印证了这一点,也标志着Node.js正式投入生产使用,算是一个重要的举措 Node.js诞生2年后,其包管理器终于正式正式面世,就叫npm。最后集成到Node.js安装包中,成为Node模块管理的事实标准: 最终,我将NPM包含在Node发行版中,这使其成为事实上的标准。 同时,通过Reddit论坛,Youtube讲故事的方式与社区联动,让更多的思想汇聚起来

2012年

创始人离开:Node.js创建者Ryan Dahl远离Node的日常工作
Node.js发布v0.8.0:Node.js v0.8.0 [稳定]已退出
出现商用解决方案框架:Hapi,一个Node.js框架

重组完libuv之后,Node.js核心部分已经趋于完备,创始人Ryan Dahl功成身退,将决策权交给npm的创始人Isaac Schlueter Node.js发展趋于于成熟的另一个标志是生态中出现了针对企业的解决方案,例如Hapi: hapi是一个易于使用的以配置为中心的框架,并具有对输入验证,缓存,身份验证以及用于构建Web和服务应用程序的其他基本功能的内置支持。

2015年

Q1 IO.js率先走向1.0:IO.js 1.0.0 成立Node.js基金会:Joyent着手建立Node.js基金会 IO.js与Node.js和解:IO.js和Node.js协调提议 这场冲向1.0版本的竞速赛以IO.js获胜告终。继而,顾问委员会中的几大公司联手成立了Node.js基金会,表态支持社区驱动的开放管理模式:

Joyent,IBM,Microsoft,PayPal,Fidelity,SAP和Linux Foundation联合起来以中立和开放式治理支持Node.js社区,为开发人员提供资源

紧接着开源社区做出回应,逐渐和解,因为管理模式上的冲突已经消除了

Q2 npm支持私有模块:npm私有模块 第三任领袖离开:节点负责人TJ Fontaine辞职并离开Joyent IO.js合入Node.js:Node.js和io.js在Node Foundation下合并 Node.js基金会成立后不久,第三任领袖TJ Fontaine宣布离开,交由基金会与社区管理:

正是由于这个强大的团队,社区和基金会的成立,才使我有适当的时间退后一步。

紧接着,和解之后,IO.js合入Node.js,从分裂走向统一

另外,npm还提供了私有模块支持,例如Github私有仓库,算是对商用的支持

Q3 4.0是新的1.0 IO.js合入之后,Node.js迎接了真正意义上的1.0版本,版本帝正式从混乱​​的0.x进入4.x时代

Q4 首次发布LTS:Node v4.2.0,第一个长期支持版本 新成员加入基金会:Apigee,RisingStack和Yahoo加入Node.js基金会 Node Interactive大会:Node Interactive 发布了第一个LTS版本,标志着Node.js进入稳定发布阶段

同时,Yahoo,RisingStack等大公司也纷纷加入基金会,共同参与Node.js建设。。,还投入了第一次Node Interactive大会,分享Node.js在生产中的应用价值

2018年

Q1 搜罗案例展示:宣布Node.js应用程序展示 创立JS Interactive大会:JS Interactive简介:JavaScript生态系统活动 基金会建站搜罗Node.js应用案例,见[foundation.nodejs.org/resources/a…](应用展示):

使用Node.js构建的惊人应用,产品和项目

同时,由于Node.js与JavaScript密不可分,干脆合作一起参加,就叫JS Interactive

Q2 支持HTTP2 push特性:Node.js可以HTTP / 2 push! 开启10.x:Node.js项目引入了最新的发行版:Node.js 10.x 发布npm 6:宣布npm @ 6 发布第三份年度调查报告:现已提供第三次年度Node.js用户调查数据 npm 6在安全方面做了更多的事情,对存在安全问题的程序包有一些管控措施,如npm audit

HTTP2等前沿特性也在持续推进,用户调查也没有停下,注意Node.js应用趋势

同时,8.x时代落幕,进入10.x,期望搭载V8引擎v6.6

Q3 Node.js创始人道出10大懊悔:Ryan Dahl:我对Node.js感到遗憾的10件事 Google App Engine支持Node.js部署:现在,您可以将Node.js应用部署到App Engine标准环境 跨LTS的N-API支持:N-API:适用于所有LTS发行版的适用于Node.js本机插件的下一代API 9年后,Node.js的创始人Ryan Dahl指出了Node.js的10大设计失误,包括加进来又去掉了Promise API,安全问题,GYP构建系统,package.json入口入口,node_modules结构等等

回过头看,npm上大量的案例说明跨版本(从6.x到10.x)的N-API支持确实有其实践意义

Q4 开会,疯狂开会:Node + JS Interactive 2018视频发布 10.x迎来LTS,11.x提上日程:10月将Node.js 10.x引入LTS,将Node.js 11引入Current! 重新计划ES模块:Node.js中的ECMAScript模块:新计划 继实验性支持(Node.js 8.5.0(2017-09-12))之后,正式的ES模块支持终于进入议程

2019年

Q1 介绍Node.js各个工作组:介绍Node.js工作组系列:从安全到性能 nodejs.dev上线:Node.js被Google选择为.dev顶级域名抢先访问 Node.js Foundation + JS Foundation = OpenJS Foundation:OpenJS Foundation简介:JavaScript生态系统发展的下一阶段 准备参加:现在打开!征集Node + JS Interactive 2019的论文 首次介绍基金会内部的工作机制,进一步公开透明。紧接着,Node.js基金会与JS基金会合并,成立OpenJS基金会

Q2 迎来新的实验性ES模块支持:宣布一个新的实验模块 npm人事变动:好人事吗?NPM可能代表“不礼貌地管理”-裁员会使员工感到痛苦 Node.js创始人启动deno:Ryan Dahl:Deno,一种新的JavaScript方法 发布Node.js 12:Node.js 12简介 npm开源与盈利的矛盾:CJ Silverio的《开源经济学》 Node.js创始人再度出发,希望重新建立更好的Node.js,即表示:

使用V8,Rust和Tokio构建的安全JavaScript / TypeScript运行时

同时,Node.js增强了实验性的ES模块支持,包括动态约会(import())等,并伴随着V8引擎版本升级以及ES特性支持,进入12.x迭代

另外,npm经营上似乎有一些变化,出现一波人事变动,可能关乎Node.js的发展:

我真正担心的是,JavaScript包管理器和语言共享权掌握在一家由VC资助的公司手中,这可能会或可能不会造成财务麻烦。如果这不好,这就是整个JavaScript语言社区现在需要注意。

因为Node.js语言的发展与盈利性质的npm公司绑定在一起,一直以来都是个隐患:

JS软件包的共同点在一个营利性实体手中。我们通过共享代码信任npm,但是我们无法让npm对其行为负责。没有信任度的基于信任的系统无法运行,但是仍然有人需要为服务器付费。我们如何到达这里,JavaScript现在应该做什么?

Node优缺点

Node.js采用了谷歌的v8引擎,同时提供了多个系统级的API,这样就避免了在浏览器端运行javascript代码各种的限制,而node.js就是运行在服务器端的js代码。

JavaScript原始运行环境 JavaScript最早在浏览器中值扮演个提供上下文的角色,但是没有表明JavaScript具体是什么,他是一门完整的语言。 node node事实上就是另外一种形式的上下文,就是node解决了JavaScript依赖浏览器运行,使得JavaScript语言可以脱离浏览器的环境,允许在后端使用JavaScript代码,除此之外node还提供了许多有用的模块。因此node事实上就是 个运行时的环境,也是一个库。

node.js的特点 node.js采用事件驱动,异步编程,为网络服务而设计 node.js的特点,可以根据程序的需要进行取舍

可靠性低 高性能 单线程 异步事件驱动 非阻塞I/O 轻量高效* node.js的性能测试 node采用单线程的放行来运行程序,事件驱动机制是node通过内部单线程高效率的时间循环队列来实现的,没有多线程的资源站用和上下文替换,node借助事件驱动搞定了全部请求,但是,这样的设计会将复杂i的压力集中在CPU(事件循环处理)而不是内存中.因此使用弄node.js加大了cpu的处理负荷,这也是单线程的弊病之一.

nodejs的优缺点

优点:

高并发(最重要的优点)适合环境:适合I/O密集型应用

缺点:

1不适合CPU密集型应用,带来的主要挑战是由于js单线程运行事件过长,将会导致CPU不能释放,是的后续I/O无法发起解决方案:分解大型计算任务为多个小型的任务,是的运算能够适时释放,不阻塞I/O调用的发起
2.只支持单核CPU,不能充分利用CPU
3.可靠性低,一旦某个环节崩溃,整个系统都会崩溃
原因:单线程,单进程
解决方案:开多个进程,绑定多个端口

deno前景优势

因为deno毕竟刚出不久至于走向还要看后期的发展

Deno 试图提供一个独立的工具来快速编写复杂功能的脚本,它将始终是单个可执行文件。就像 Web 浏览器一样,它知道如何获取外部代码。在 Deno 中,单个文件可以定义任意复杂的行为,而无需任何其它工具。Ryan Dahl 认为过去他在设计 Node 时犯了一些错误,包括安全性、构建系统、package.json、node_modules、index.js等等,并表示 Node 存在的种种不足导致有许多严重 bug 问题且不可回避,当前 JavaScript 和周围的软件基础架构已经发生了巨大的变化,值得进行简化,于是他重新设计了 Deno 这门脚本语言。Rust API今天正式发布的 1.0 版本带来了命令行界面 CLI 1.0。Deno 本身并不是一个单体的程序,而是设计为 Rustcrate的集合,以允许在不同的层进行集成。Deno 中的 Rust crate deno_core 不依赖于 TypeScript 或 Tokio,它只是提供了操作和资源基础架构。也就是说,它提供了一种将 Rust 特性绑定到 JavaScript promise 的有组织方式。CLI 则完全建立在 deno_core 之上。rusty_v8 crate 提供高质量的 V8 C++ API 的 Rust 绑定。该 API 尝试尽可能与原始 C++ API 匹配,它是零成本的绑定,因为 Rust 中暴露的对象与在 C++ 中操作的对象完全相同。HTTP 服务器性能Deno 的 HTTP 服务器是采用 TypeScript 在原生 TCP socket 的顶层实现的,Node 的 HTTP 服务器使用 C 语言编写,并作为对 JavaScript 的高级绑定暴露。一直以来 Deno 拒绝将原生 HTTP 服务器绑定添加进来,因为这还需要优化 TCP socket 层,更常见的是优化 op 接口。Deno 是一个合适的异步服务器,每秒 25k 请求足以满足大多数目的,此外,由于普遍使用 Promise,Deno 需要有更好的尾部延迟。目前 Deno HTTP 服务器每秒处理约 25 000 个请求,最大延迟为 1.3 毫秒,与之相比,Node 程序每秒处理 34 000 个请求,最大延迟介于 2 到 300 毫秒之间。这样看来,作者认为 Deno 的 HTTP 服务器还有更多的性能优势,并表示希望在将来的版本中实现这一目标。插件/扩展Deno 1.0 还带来了一个新生的插件系统,用于通过自定义操作扩展 Deno 运行时。但是,此接口仍在开发中,并已标记为不稳定。此外,发布公告中还提及 Deno 稳定性与兼容性等内容,还介绍了接下来将会把 TSC 移植到 Rust,最终加速类型检查,提高从 TS 解析到 JS 性能的计划。

以上是有个人愚见,也有参考其他的文章欢迎指出不足,提出缺点 谢谢

deno部分参考链接的文章 www.ruanyifeng.com/blog/2020/0… deno的分析文章写的挺好的