前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >什么是Deno?跟Node.js有何区别?

什么是Deno?跟Node.js有何区别?

作者头像
ConardLi
发布于 2020-03-02 08:26:30
发布于 2020-03-02 08:26:30
1.8K40
代码可运行
举报
文章被收录于专栏:code秘密花园code秘密花园
运行总次数:0
代码可运行

原文:What’s Deno, and how is it different from Node.js?(https://blog.logrocket.com/what-is-deno/)

Node.js的作者Ryan Dahl,过去一年半的时间都在打造一个新的JavaScript运行环境Deno来解决Node的一些内在问题。

不过不要误会,得益于JavaScript庞大的社区生态和使用范围,Node是一个非常不错的JavaScript运行环境。然而,Dahl 也承认在Node的某些方面他应该考虑得更全面一些,比如:安全性,模块机制,依赖管理等。

在他的计划中,他并不会去预想Deno在短时间内能够发展成一个多大规模的平台。当然咯,把时间调回2009年,JavaScript还是人人都能取笑的一个有些怪异的小语言,也木有现在这么多语言特性。

什么是Deno,以及它的主要特性是哪些?

Deno是基于Google V8引擎构建的安全的TypeScript运行环境。下面是构建Deno的一些物料:

Rust(Deno的核心模块使用Rust编写,Node的核心模块是用C++实现的)

Tokio(Rust实现的异步编程框架)

TypeScript(Deno对JavaScript和TypeScript都支持开箱即用)

V8(Google出品JavaScript运行时,主要用在Chrome和Node中)

接下来看看Deno提供了哪些特性。

安全性(权限管理)

Deno最重要的特性就是安全性。

相较于Node,Deno默认使用沙箱环境执行代码,这意味着运行环境没有操作以下模块权限:

文件系统

网络

执行其他的脚本

系统环境变量

让我们瞅一眼Deno的权限系统是如何工作滴。

  1. (async () => {
  2. const encoder = new TextEncoder();
  3. const data = encoder.encode('Hello world\n');
  4. await Deno.writeFile('hello.txt', data);
  5. await Deno.writeFile('hello2.txt', data);
  6. })();

这个脚本分别创建了两个名为hello.txt和hello2.txt的文件,并在其中写入Hello world。但是这段代码运行在沙箱环境中,所以是没有文件系统的操作权限滴。

还有一点值得注意,在上面的脚本中我们使用Deno命名空间来操作文件,而不像在Node中使用fs模块。Deno命名空间提供了超多基础方法。不过使用Deno命名空间会导致我们的代码失去了对浏览器的兼容性,这个问题我们晚点再聊。

使用下面的命令执行上述脚本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ deno run write-hello.ts

执行之后,我们会收到下面的提示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Deno requests write access to "/Users/user/folder/hello.txt". Grant? [a/y/n/d (a = allow always, y = allow once, n = deny once, d = deny always)]

实际上,基于上面创建文件的脚本我们会收到两次来自沙箱环境的权限提示。不过如果我们选择allow always选项,就只会被询问一次啦。

如果我们选了deny,会抛出一个PermissionDenied的错误,如果我们没写错误处理逻辑的话,进程在此时就被终止啦。

如果我们用下面的命令来执行脚本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ deno run --allow-write write-hello.ts

会在没有提示的情况下创建这两个文件。

Deno针对文件系统的命令行标志位,除了--allow-write,还有--allow-net/--allow-env/--allow-run,分别用来开启针对网络、系统环境变量和操作子进程的权限。

模块机制

Deno使用浏览器一样的方式,通过URL来加载模块。很多人第一次见到在服务端的import语句中见到URL会感到有点困惑,但对我来说这还蛮好理解的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

你觉得通过URL来引入模块会有啥大不了的吗?答案其实蛮简单的:通过使用URL来加载模块,Deno就可以避免引入一个类似npm的中心化系统来发布package,npm最近受到了很多吐槽。

通过URL来引入代码,可以让包的作者们使用自己最喜爱的方式来维护和发布自己的代码。再也不会有package.json和node_modules了。

当我们启动应用之后,Deno会下载所有被引用的文件,并将它们缓存到本地。一旦引用被缓存下来,Deno就不会再去下载它们了,除非我们使用-- relaod标志位去触发重新下载。

还有几个问题值得我们讨论一哈:

万一存放引用的站点挂了咋办?

由于没有了一个中心化的包管理站点,那些存放模块的站点可能因为各种各样的原因挂掉。如果在开发甚至生产环境出现这种情况是非常危险滴!

我们在上一节提到,Deno会缓存好已下载的模块。由于缓存是存放在我们的本地磁盘的,Deno的作者建议将这些缓存提交到代码仓库里。这样一来,即使存放引用的站点挂了,开发者们还是可以使用已经下载好的模块(只不过版本是被锁住的啦)。

Deno会把缓存存储在环境变量$DENO_DIR所指定的目录下,如果我们不去设置这个变量,它会指向系统默认的缓存目录。我们可以把$DENO_DIR指定我们的本地仓库,然后把它们提交到版本管理系统中(比如:git)

只能使用URL来引用模块吗?

总是敲URL显得有点XX,还好,Deno提供了两种方案来避免我们成为XX。

第一种,你可以在本地文件中将已经引用的模块重新export出来,比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export { test, assertEquals } from "https://deno.land/std/testing/mod.ts";

假如上面这个文件叫local-test-utils.ts。现在,如果我们想再次使用test或者assertEquals方法,只需要像下面这样引用它们:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { test, assertEquals } from './local-test-utils.ts';

看得出来,是不是通过URL来引用它们并不是最重要的啦。

第二种方案,建一个引用映射表,比如像下面这样一个JSON文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
   "imports": {
      "http/": "https://deno.land/std/http/"
   }
}

然后把它像这样import到代码里:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { serve } from "http/server.ts";

为了让它生效,我们还需要通过--importmap标志位让Deno来引入import映射表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ deno run --importmap=import_map.json hello_server.ts

如何进行版本管理?

版本管理必须由包作者来支持,这样在client端可以通过在URL中设置版本号来下载:https://unpkg.com/liltest@0.0.5/dist/liltest.js。

浏览器兼容性

Deno有计划做到兼容浏览器。从技术上讲,在使用ES module的前提下,我们不需要使用任何类似webpack的打包工具就能在浏览器上运行Deno代码。

不过呢,你可以使用类似Babel这样的工具可以把代码转化成ES5版本的JavaScript,这样可以兼容那些不支持所有最新语言特性的低版本浏览器中,带来的后果就是最终文件里有很多不是必须的冗余代码,增大代码的体积。

结果取决于我们的主要目的是啥。

支持TypeScript开箱即用

不需要任何配置文件就能在Deno中轻易地使用TypeScript。当然咯,你也可以编写纯JavaScript代码,并使用Deno去执行它。

总结

Deno,作为一个新的TypeScript和JavaScript的运行环境,是一个非常有趣的技术项目,并且至今已经稳定发展了一段时间。但是距离在生产环境中去使用它还有比较长的一段路要走。

通过去中心化(或者翻译成分布式?)的机制,把JavaScript生态系统从npm这样中心化的包管理系统中解放了出来。

Dahl希望在这个夏天快结束的时候能够发布1.0版本,所以如果你对Deno未来的新进展感兴趣的话,可以给它个star。

最后还有一个日志系统的广告,大家可以去原文查看。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 code秘密花园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
4 条评论
热度
最新
这个范例,不能体现InheritedWidget的意义吧?依然使用的是_CountState的setState方式,这里依然是整体对CountWidget进行rebuild,那是不是使用InheritedWidget并没什么确切的意义。
这个范例,不能体现InheritedWidget的意义吧?依然使用的是_CountState的setState方式,这里依然是整体对CountWidget进行rebuild,那是不是使用InheritedWidget并没什么确切的意义。
33点赞举报
InheritedWidget主要用来做数据共享,帮助Widget树中的子widget拿到顶层父widget中的数据。如果你要关注widget的局部更新推荐你阅读 这篇文章https://cloud.tencent.com/developer/article/1650568
InheritedWidget主要用来做数据共享,帮助Widget树中的子widget拿到顶层父widget中的数据。如果你要关注widget的局部更新推荐你阅读 这篇文章https://cloud.tencent.com/developer/article/1650568
回复回复点赞举报
谢谢,后来仔细看完InheritedWidget的源码,的确它仅仅只是方便向下传递数据,和局部刷新关联不大。
谢谢,后来仔细看完InheritedWidget的源码,的确它仅仅只是方便向下传递数据,和局部刷新关联不大。
回复回复点赞举报
查看全部3条回复
推荐阅读
编辑精选文章
换一批
使用InheritedWidget来进行状态管理
之前我写过一篇文章使用Provider来进行状态管理,介绍了在Flutter中如何通过Provider来进行状态管理,今天我们来介绍状态管理的另外一种方式——InheritedWidget。实际上,Provider的底层也是通过InheritedWidget来实现的。
拉维
2022/03/28
4530
【源码分析】系列之 InheritedWidget
为了使源码系列的文章不那么枯燥,文章中会有很多流程图,流程图比纯文字更直观,一图胜千言。
老孟Flutter
2021/01/28
1.1K0
从零开始的Flutter之旅: Provider
虽然InheritedWidget可以提供共享数据,并且通过getElementForInheritedWidgetOfExactType来解除didChangeDependencies的调用,但还是没有避免CountWidget的重新build,并没有将build最小化。
Rouse
2020/06/24
7530
从零开始的Flutter之旅: Provider
Flutter | 数据共享
InheritedWidget 是 Flutter 中非常重要的一个功能型组件,它提供了一种数据在 widget 树中从上到下传递的方式。例如在根 Widget 中通过 InheritedWidget 共享了一个数据,那么我们就可以在任意的子 Widget 中获取改共享的数据;
345
2022/02/11
1.4K0
Flutter | 数据共享
flutter-状态管理2-inheritedWidget的使用例子
2.创建子Widget,依赖InheritedWidget的数据.(这里创建两个Widget,一个StatefulWidget,一个StatelessWidget)
前端小tips
2021/11/28
7960
flutter-状态管理2-inheritedWidget的使用例子
# 使用InheritedWidget传递数据
上面例子你看到,每个DataTransferWidget的构造函数都依赖父widget的data,如果还有第4层,第5层...等嵌套的话,data要不停的通过构造函数传递,甚是麻烦。
用户1175783
2019/09/23
9300
# 使用InheritedWidget传递数据
Flutter 组件集录 | InheritedWidget 共享数据
在 Flutter 应用开发中,数据的跨节点共享是一个非常重要的事。下面通过一个例子说明一下:
张风捷特烈
2024/03/08
2990
Flutter 组件集录 | InheritedWidget 共享数据
Flutter漫说:组件生命周期、State状态管理及局部重绘的实现(Inherit)
flutter的生命周期其实有两种:StatefulWidget和StatelessWidget。
BennuCTech
2021/12/10
1.6K0
Flutter漫说:组件生命周期、State状态管理及局部重绘的实现(Inherit)
FlutterDojo设计之道—状态管理之路(四)
当Child Widget想要跨Widget拿到其它Widget的数据时,通常就需要使用构造函数,将数据一层层传递到Child Widget,这显然不是一个好的解决方案,不仅让Widget之间有了很大的耦合,也产生很多的冗余数据。
用户1907613
2020/09/08
5130
FlutterDojo设计之道—状态管理之路(四)
flutter系列之:flutter架构什么的,看完这篇文章就全懂了
Flutter是google开发的一个跨平台的UI构建工具,flutter目前最新的版本是3.0.5。使用flutter你可以使用一套代码搭建android,IOS,web和desktop等不同平台的应用。做到一次编写到处运行的目的。
程序那些事
2022/08/15
1.1K0
「 flutter 必知必会 」详细解析数据共享 InheritedWidget 完整使用
「 flutter 必知必会 」贴心解析:状态管理与数据共享 InheritedWidget 完整使用方案,为你铺平大前端学习之路
圆号本昊
2021/09/24
7370
「 flutter 必知必会 」详细解析数据共享 InheritedWidget 完整使用
flutter系列之:构建Widget的上下文环境BuildContext详解
我们知道Flutter中有两种Widget,分别是StatelessWidget和StatefulWidget,StatelessWidget中有一个build方法来创建对应的Widget,虽然StatefulWidget中没有对应的build方法,但是和StatefulWidget对应的State中也有同样的build方法。
程序那些事
2022/08/26
5330
2021 年值得期待的 Flutter 数据流管理方案
不像 Redux 在 React 中独占鳌头,Flutter 的数据流管理方案层出不穷,本文旨在介绍在2021年值得使用的 Flutter 数据流管理方案,除了大家都比较熟悉的 InheritedWidget 和 provider, 还有 Remi Rousselet 新推出的、令人十分期待的 Riverpod。希望读者对Flutter 已经有一定的基础,并且了解声明式UI。下面就一起开始吧 1. 什么状态才需要使用数据流管理方案? 对于声明式的 UI 而言,UI = f(state),f 是 build
QQ音乐前端团队
2021/03/29
2K0
Flutter 如何跨组件传递数据
InheritedWidget 是 Flutter 中非常重要的一个功能型 Widget,它可以高效的将数据在Widget 树中向下传递、共享,这在一些需要在 Widget 树中共享数据的场景中非常方便,如 Flutter 中,正是通过 InheritedWidget 来共享应用主题( Theme )和 Locale (当前语言环境)信息的。
网罗开发
2021/02/26
2.9K0
Flutter 如何跨组件传递数据
Flutter 组件集录 | InheritedNotifier 内置状态管理组件
在上一篇 《Flutter 知识集锦 | 监听与通知 ChangeNotifier》 中,我们介绍了 ChangeNotifier 对象通知监听者的能力。并通过一个简单的模拟下载进度案例,介绍了它的使用方式:
张风捷特烈
2023/11/02
3310
Flutter 组件集录 | InheritedNotifier 内置状态管理组件
【源码篇】Flutter Provider的另一面(万字图文+插件)
此事说来话短,我这不准备写解析Provider源码的文章,肯定要写这框架的使用样例啊,然后再哔哔源码呀!在写demo样例的时候,新建那俩三个文件、文件夹和必写的模板代码,这让我感到很方啊,这不耽误我时间嘛!然后就撸了这个插件,相对而言,多花了几百倍的时间。。。
小呆呆666
2021/05/31
1.5K1
【源码篇】Flutter GetX深度剖析 | 我们终将走出自己的路(万字图文)
这是电影《哪吒》里申公豹说的一句话,也是贯彻整部电影的一个主题;或许这句话引起了太多人的共鸣:35岁职场危机,大厂卡本科学历,无房无车结婚难等等,所以,这句话也经常被人提起。
小呆呆666
2021/07/14
4.5K0
flutter使用InheritedWidget进行父子组件通信
在使用flutter开发过程中有些时候需要在父子组件之间进行通讯,我们可以借助InheritedWidget来实现。实现步骤如下:
挥刀北上
2021/01/15
1.8K0
flutter使用InheritedWidget进行父子组件通信
Flutter跨平台移动端开发丨WillPopScope、InheritedWidget、Theme
通过 InheritedWidget 数据可以在 Widget 树中从上向下共享与传递,组件之间也可实现跨级传递数据
码脑
2019/05/25
1.4K0
FlutterDojo设计之道—状态管理之路(五)
可以发现,在使用InheritedWidget来实现数据管理的方式中,有几个东西是必须的。
用户1907613
2020/09/08
4130
推荐阅读
相关推荐
使用InheritedWidget来进行状态管理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验