Deno你一定要坚强的走下去, 变成哥斯拉. | 🏆 技术专题第一期 | 聊聊 Deno的一些事儿......

968 阅读8分钟

啊 好久没发文章了。赶上掘金Deno专题。那好嘛,搬上小板凳, 坐在我旁边,一起跟着Ryan大佬的视频, 记笔记记笔记。(我的工地散装英语,如果可以的话, 请您尽量看一遍原演讲视频.)


对于学习一门新的技术, 或者任何一个领域的新知识。我认为最开始要做的事不是急着去Getting Started. 而是要找到为什么. 也就是这门技术为什么会出现,它解决了什么历史问题。一般新的技术出现, 很大概率是对老技术的革新。但是迭代的目的也是为了解决问题。所以, 我决定先去找找这这俩问题的答案

  1. 为什么会出现deno
  2. deno解决了什么问题

而Ryan大佬在18年的演讲就说过了这个问题.

为什么会出现deno

要说到deno就不得不说一下node v8. deno有个slogan: A secure TypeScript runtime on V8. 所以我们要从deno第一次出现在大众的眼中出现开始说起。 这就要从18年Ryan Dahl在JSConf EU 2018上的一次演讲。在这个演讲里, 作为node的创造者, 当时他的工作重点在支持IO以及基于事件驱动的http server. 当然, 大家都知道结局,v8成功了。在2012年, 他认为或多或少的已经完成了他当初对自己设立下的目标----一个对用户友好的, 非阻塞的框架,并且有以下的几个特性:

  1. 支持了多种协议
  2. 跨平台
  3. 一个相对小但是稳定的api
  4. 一个在成长的生态系统,也就是今天的npm

当时他对高性能的服务器产生了兴趣。(可能是原生较好的支持异步编程让go进入了他的视野, 所以当时一开始打算用go写这个新的项目)Go是服务器很好的语言。他没有使用node。同时吹了一波动态语言的优点。简而言之就是, 动态语言在科学计算,这种快速出结果的场景, 动态语言更有优势。而对于大型服务器这种,稍有不慎就会翻车的场景, 用静态语言构建相对比较适合。

重点来了,然后就进入到了v8存在什么设计问题,并且这部分问题因为现在的体量导致了fix起来很难。

  • Regret: not sticking with promise | 没有把promise在一开始的时候加进去

    • 在2009年的时候已经有promise的机制, 而在2010年2月又从node中移除
    • promise 是必要的抽象对于async/await(如果保留了promise, 那么async/await的出现会不会更早, 也就不会存在当时面试题里的callback hell问题了, 泪目)
    • node中对promises的统一使用可能会加速出现最终的标准化async / await的出现.
    • 在今天node的很多async的api还是实现的得很糟糕因为promise没有早一点出现
  • Regret: Security

    • v8引擎本身是一个很好的安全沙箱, 但是node程序本身可以调用操作系统, 这是一个很大的权限, 特别是对于服务器
    • 是否已进一步考虑过如何针对某些应用程序进行维护, node可能存在其他语言无法提供的良好安全性保证
    • 举个栗子: linter工具本身不应该存在访问你的电脑和网络的权限
  • Regret: The Build System(GYP) ? (不是很理解)

    • GYP: 编写引用c语言库的模块时会使用GYP编译该库, 然后链接到node
    • 构建系统非常的困难但是也非常的重要
    • v8引擎(chrome)开始的时候使用的是GYP
    • chrome放弃了GYP使用GN. 现在node是GYP唯一的用户
    • GYP不是一个很差的内部接口, 在node内部用于暴露给任何试图绑定到v8引擎的用户.
    • 这是一个很可怕的体验对于用来说. 这是一个非json, python将它适配成了json. node周围存在几个wrapper其中之一是node.jip, 这只是一层又一层不必要的复杂性。
  • Regret: package.json

    • isaac, in npm, invented package.json(for the most part.)
    • 当我们用require()引入一个包的时候, node回去找package.json下的main字段, 找到文件入口
    • 最终,我将npm包含在node分发服务中,这使其成为事实上的标准
    • 不幸的是,因此模块有一个集中的(甚至是私有控制的)存储库
    • 允许package.json上升到“模块”作为文件目录的概念, 但是这不是一个严格而必须的抽象. 并且这个概念并不存在于web.
    • package.json现在包含了太多不必要的信息. license/repository/description. 这些都是不必要的噪音.
    • 如果在导入时仅使用了相关文件和URL,则提供的文件路径将定义版本,无需在dependencies重新列出。(但是我很不解啊, go的module不也是通过一个.mod文件然后列出来的.两者的区别是什么?)
  • Regret: node_modules

    • 它极大地增加了模块解析算法的复杂度。
    • 本来可以通过设置一个$NODE_PATH来避免所有包都在项目文件夹下的node_modules里
    • node的行为与浏览器的处理方式不大相同, 对于module. 浏览器的行为就是遇到script节点, 然后就去加载. 而不是像node一样把所有的包下到本地再run.
    • 并且现在没办法修改这个机制, 因为一旦改动可能会影响到很多用户
  • Regret: require("module") without the extension ".js"

    • 不必要的省略导致了不明确
    • 不是浏览器js的工作方式。 您不能在脚本标记src属性中省略“ .js”
    • 模块加载器必须在多个位置查询文件系统,以猜测用户的意图.(node对于require的行为模式,先找当前文件夹 =》 再去当前项目的node_modules里边找)
  • Regret: index.js

    • 以为它很可爱(?), 因为我们有index.html, 默认访问一个地址, 如果只是 / 那么就会去找该服务器下的index.html, 这是设计index作为入口的初衷
    • 它使模块加载系统复杂化
    • 在require()支持的package.json之后,它变得特别不必要. package.json有main字段, 定义了模块的入口.

node出现的问题几乎都在怎么管理用户代码上。 而产生这个问题的原因是当时设计v8他的目标是处理io与基于event的http服务器上。module系统是在之后加上去的。

deno 的目标, 也是它想去解决的问题

然后进入了deno第一次正式的介绍和大众见面.

(18年介绍的时候, 当时说是还是一个原型。而今天已经出1.x版本了。大家完全可以去尝试。happy coding deno.land/)

以下是deno的主要特性:

  • Security

    • 利用javascript是安全的沙箱这一事实
      • 默认情况下一个脚本应该运行在没有任何的网络和文件读写权限的环境下
      • 用户可以选择给予脚本响应的权限通过: --allow-net/ --allow-write
      • 这种机制允许用户允许不被信任的工具(例如: linter)
    • 不允许将任意原生函数绑定到v8
      • 所有系统调用均通过消息传递完成(protobuf序列化)
      • 恰好有两个原生函数:send和recv
      • 这既简化了设计,又使系统更易于审计
  • 简化模块化系统

    • 不尝试与现有node模块兼容
    • 通过相对地址或者绝对地址导入模块.
    import { test } from 'http://unpkg.com/deno_testing@0.0.5/testing.ts';
    import { log } from './util.ts';
    
    • 导入必须提供扩展名
    • 远程URL会在首次加载时获取并缓存,只有用户显式的使用--reload参数时,才会重新去获取资源.
    • 可以通过指定非默认的缓存目录来提供vender
  • Typescript 编译器内置到deno中

    • ts很棒
      • 它提供了一种实用的可选类型的语言
      • 允许代码从快速启动的项目到大型的项目无缝连接
    • deno hook到ts编译器,以进行模块解析和构建工件的增量缓存
    • 未修改的ts文件不应该重新编译
    • 正常的js代码可以run在deno中
    • 它应该使用v8快照来快速启动.
  • Misc

    • 遇到没有handled的promise进程立即死亡
    • 支持顶层的await
    • 与浏览器功能重叠的功能会进行兼容

总结

距离Ryan的演讲已经过去两年, 底层的语言也从之前说的Go转向了Rust. 以及之前作出了Deno 将停止在内部代码中继续使用 TypeScript的决定

说说我的看法。 一波演讲看下来。从说node的不足,到推出deno来fix掉这些问题。node.js很成功,前端的发展离不开node.js。 但是从现在往回看,确实是存在一些当初可以避免的问题。但是历史就是历史。我们可能存在两个v8运行时么?不应该吧。技术服务于产品. 如果deno能做的, node也能做。那么作为使用者, 切换deno的动力应该是在于deno更好用?还是更容易的切换到deno?或者更安全?或者对于ts内部支持很棒?在接下来对deno继续深入了解与尝试也许会找到答案。现在很多在node上的lib也开始在deno出自己的lib。这或许是一个信号, 我们都用行动投票。

期待这只小恐龙可以找到自己路, 然后变成一只哥斯拉.

Ryan演讲地址: www.youtube.com/watch?v=M3B…!

蜻蜓队长 蜻蜓队长!蜻蜓队长! 说搅屎棍的出门左转谢谢🙏

最后, 周末愉快.

🏆 技术专题第一期 | 聊聊 Deno的一些事儿......