V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
WuJia
V2EX  ›  前端开发

5 分钟带你了解未来可能推翻 Node 的新轮子 Deno 1.0

  •  1
     
  •   WuJia ·
    wujiabk · 2020-06-05 11:07:00 +08:00 · 1456 次点击
    这是一个创建于 1639 天前的主题,其中的信息可能已经有所发展或是发生改变。
    关注微信公众号前端技术专栏,回复“资源”免费领取全套视频教程

    前言

    最近 Nodejs 作者 Ryan Dahl 发布了 Deno 1.0 正式版,圈子一下沸腾起来了。或许你早在两年前就听说了这个东西,但是也有人不知道这个东西是什么,干什么用的,所以今天我将为大家来简单的聊一下这个将来可能会推翻 Node 的新轮子。

    正文

    什么是 Deno ?

    Deno 是一个基于 v8 、rust 和 Tokio 的 Javascript/Typescript 的安全运行时。它在内部嵌入了一个 typescript 的编译器。可以将 typescript 编译成 js 然后运行在 v8 上,并通过 c++ libdeno 实现 js 与 rust 的通信交互,当然 deno 也可以直接运行 Javascript 代码。

    已经有了 Node,为什么作者还要写一个 Deno ?

    在过去的几年里,JS 标准引入了大量新的语法特性。影响最大的就是 Promis 和模块化。

    对于 Node 来说,这两个东西支持的都不是很理想。由于历史原因,Node.js 必须支持回调函数,导致异步接口会有 Promise 和回调函数两种写法;同时,Node.js 自己的模块 CommonJS 与 ES 模块化不兼容,这样就导致无法完全支持 ES 模块化。

    另一个原因就是 Node.js 的模块管理工具 Npm,逻辑越来越复杂;模块安装目录 npm_modules 非常庞杂,难以管理。Node.js 也几乎没有安全措施,用户只要下载了外部模块,就只好听任别人的代码在本地运行,进行各种读写操作。 然后 Node.js 的功能也不完整,导致外部工具层出不穷,让开发者疲劳不堪:webpack,babel,typescript 、eslint 、prettier.....

    So,由于上面这些原因,作者 Ryan Dahl 决定放弃 Node.js ,重新写一个替代品,来彻底解决这些问题。

    如何安装 Deno ?

    linux/mac

    curl -fsSL https://deno.land/x/install/install.sh | sh
    

    windows

    iwr https://deno.land/x/install/install.ps1 | iex
    

    详细可以参考官网查看:https://deno.land/

    安全性

    Deno 默认安全。相比之下,Node.js 默认拥有访问文件系统和网络的权限。 要在没有授权的情况下运行一个需要启动子进程的程序,比如:

    deno run file-needing-to-run-a-subprocess.ts
    

    运行后你会看到一条警示消息

    error: Uncaught PermissionDenied: access to run a subprocess, run again with the --allow-run flag
    

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

    • 环境
    • 网络
    • 文件系统读 /写
    • 运行子进程

    必须使用参数,显式打开权限才可以,参数分别如下:

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

    例如,要授予 Deno 对 /etc 目录的只读权限,可以这样:

    deno --allow-read=/etc
    

    模块机制

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

    import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
    

    通过使用 URL 来加载模块,Deno 就可以避免引入一个类似 npm 的中心化系统来发布 package,npm 最近受到了很多吐槽。 通过 URL 来引入代码,可以让包的作者们使用自己最喜爱的方式来维护和发布自己的代码。再也不会有 package.json 和 node_modules 了。 当我们启动应用之后,Deno 会下载所有被引用的文件,并将它们缓存到本地。一旦引用被缓存下来,Deno 就不会再去下载它们了,除非我们使用-- relaod 标志位去触发重新下载。

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

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

    export { test, assertEquals } from "https://deno.land/std/testing/mod.ts";
    

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

    import { test, assertEquals } from './utils.ts';
    

    另一种方式就是建一个引用映射表,比如像下面这样一个 JSON 文件:

    {
      "imports": {
         "http/": "https://deno.land/std/http/"
      }
    }
    

    然后 import 到代码里:

    import { serve } from "http/server.ts";
    

    最后为了让它生效,还需要通过--importmap 让 Deno 来引入 import 映射表:

    deno run --importmap=import_map.json hello_server.ts
    

    Deno 的命令

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

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

    Deno 的内部结构

    下面是 Deno 的部分目录结构图

    吴佳前端博客-deno

    上图中圈出来的三个文件夹分别是

    • js
    • libdeno
    • src

    分别对应 Deno 的 api 层、中间层、和实现层;其中 js 中主要是 typescript 的代码,包含 typescript 的编译器和 Deno 暴露给用户的 api 。libdeno 中主要是 c++代码,用来加载 v8 实例,实现 typescript 和 rust 的通信。src 文件中主要是 rust 的代码,是 Deno 功能的具体实现。例如用户使用 File 实例的 write 方法来写文件,实际上是 api 层( typescript )通过中间层( libdeno )将数据传输给实现层( rust ),最终写文件操作由 rust 去完成。Deno 结合了 Typescript/Javascript 的易用性和 rust 的系统语言能力。

    吴佳前端博客-deno

    此图可以清晰的表示 js 和 rust 之间的逻辑关系。

    总结

    就目前来看,Deno 还是一个比较新的东西,功能不稳定,周围生态还不够完整。

    So,还不能完全取代 Node.js ,建议先不要用于生产环境,但是现在已经是一个能够使用的工具了,有时间的话可以造造轮子,研究一下也不是不可的。

    微信公众号前端技术专栏
    2 条回复    2020-06-05 11:31:42 +08:00
    putaozhenhaochi
        1
    putaozhenhaochi  
       2020-06-05 11:18:40 +08:00 via Android
    move to /promote
    WuJia
        2
    WuJia  
    OP
       2020-06-05 11:31:42 +08:00
    @putaozhenhaochi 挺不错的,可以玩一玩。就是目前生态还不完整
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2032 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:55 · PVG 08:55 · LAX 16:55 · JFK 19:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.