Deno 和 Node.js 区别

🌙
手机阅读
本文目录结构

与 Node.js 的比较

Deno 和 Node.js 都是基于 Google V8 JavaScript 引擎 构建的运行时。

它们都具有内部事件循环,并提供了用于运行脚本和各种系统实用程序的命令行界面。

项目 Node.js Deno
API 引用方式 模块导入 全局对象
模块系统 同时支持 CommonJSES Module 使用 ES Module 作为默认模块系统,不支持 require()
安全 默认无限制,但是可以设置 默认全限制,需要显式指定文件、网络和环境权限。允许控制文件系统和网络访问,以运行沙盒代码。
Typescript 通过第三方支持(如ts-node) 原生默认支持
包管理 npm+node_modules 原生支持, Deno 同时承担了运行时和包管理器的角色
异步操作 默认回调,并支持 Promise 默认 Promise,Deno 没有历史包袱,所以可以使用最新的方式
包分发 npmjs.com任意git仓库 import url,使用 URL 来加载本地或远程依赖项,类似于 browsers。
工具箱 通过第三方支持 (gulp/eslint/babel 原生支持一些工具

内置 API 引用方式不同

node 模块导入

node 内置 API 通过模块导入的方式引用,例如:

const fs = require("fs");
fs.readFileSync("./data.txt");

deno 全局对象

而 deno 则是一个全局对象 Deno 的属性和方法:

Deno.readFileSync("./data.txt");

查看 deno 有哪些方法

我们可以通过 repl 看一下:

denodeno repl

进入 repl 后,输入 Deno 回车(相当于查看 Deno 类,不理解类和示例的请自己补习下),

我们可以看到:

{
 Buffer: [Function: Buffer],
 readAll: [AsyncFunction: readAll],
 readAllSync: [Function: readAllSync],
 writeAll: [AsyncFunction: writeAll],
 writeAllSync: [Function: writeAllSync],
 build: {
  target: "x86_64-pc-windows-msvc",
  arch: "x86_64",
  os: "windows",
  vendor: "pc",
  env: "msvc"
 },
 chmodSync: [Function: chmodSync],
 chmod: [AsyncFunction: chmod],
 chownSync: [Function: chownSync],
 chown: [AsyncFunction: chown],
 customInspect: Symbol(Deno.symbols.customInspect),
 inspect: [Function: inspect],
 copyFileSync: [Function: copyFileSync],
 copyFile: [AsyncFunction: copyFile],
 ...
}

https://a.axihe.com/edu/deno/powershell_pHVWP4tLng.png

模块系统

模块系统是 deno 和 node 差别最大的地方,也是 deno 和 node 不兼容的地方。

  • node 采用的是 CommonJS 规范,
  • deno 采用的 ES Module 的浏览器实现。

ES Module 的浏览器实现

ES Module 大家都熟,但其浏览器实现可能大家还不是很熟悉:

<body>
  <!-- 注意这里一定要加上 type="module" -->
  <script type="module">
    // 从 URL 导入
    import Vue from "https://unpkg.com/vue@2.6.11/dist/vue.esm.browser.js";
    // 从相对路径导入
    import * as utils from "./utils.js";
    // 从绝对路径导入
    import "/index.js";

    // 不支持
    import foo from "foo.js";
    import bar from "bar/index.js";
    import zoo from "./index"; // 没有 .js 后缀
  </script>
</body>

deno 的模块规范

deno 完全遵循 es module 浏览器实现,所以 deno 也是如此:

// 支持
import * as fs from "https://deno.land/std/fs/mod.ts";
import { deepCopy } from "./deepCopy.js";
import foo from "/foo.ts";
import "http://deno.axihe.com/demo/hello.ts";

// 不支持
import foo from "foo.ts";
import bar from "./bar"; // 必须指定扩展名

最大的不同:

  • 可以通过 import url 直接引用线上资源;
  • 资源不可省略扩展名和文件名。

安全

Node 默认有很多权限,

Deno 默认屏蔽所有可能危险的权限,需要指定。

对程序来说,写项目基本没有区别,可以 deno run -A xxx 即可

兼容浏览器 API

Deno 的设计,通过与浏览器 API 保持一致,来减少大家的认知。

概念上兼容,模块系统,从上面介绍看出 deno 是完全遵循浏览器实现的;

默认安全,当然也不是自己创造的概念,w3c 早已做出浏览器权限的规定,我们在做小程序的时候尤为明显,需要获取各种权限;

对于异步操作返回 Promise;

使用 ArrayBuffer 处理二进制;

等等…

存在 window 全局变量

console.log(window === this, window === self, window === globalThis);

实现了 WindowOrWorkerGlobalScope 的全部方法

具体方法列表,我们可以参考:lib.deno.shared_globals.d.ts 和 lib.deno.window.d.ts

// 请求方法
fetch("https://baidu.com");

// base64 转化
let encodedData = btoa("Hello, world"); // 编码
let decodedData = atob(encodedData); // 解码

// 微任务
queueMicrotask(() => {
  console.log(123);
});

// 等等。..

总体而言,如果服务端和浏览器端存在相同概念,deno 就不会创造新的概念。

这一点其实 node 也在做,新的 node 14.0 CHANGELOG 就也提及要实现 Universal JavaScript 和 Spec compliance and Web Compatibility 的思想,大趋势。

支持 Typescript

不管你喜欢与否,很多框架都上了 TS,国外的开发者,TS 的普及率已经非常广了,基本属于必学的了。

// index.ts
let str: string = "王境泽定律";
str = 132;

运行

> deno run index.ts
error TS2322: Type '123' is not assignable to type 'string'.

► file:///Users/Administrator/Desktop/index.ts:2:1

2 str = 123
  ~~~

没有 node_modules

deno 没有 node_modules,我们先看下面的例子

// index.js
import { white, bgRed } from "https://deno.land/std/fmt/colors.ts";
console.log(bgRed(white("hello world!")));

运行

> deno run index.js
Download https://deno.land/std/fmt/colors.ts
Compile https://deno.land/std/fmt/colors.ts
hello world!

我们看到其有 DownloadCompile 两个步骤。

并不会每次都有 DownloadCompile 两步的。

当你第二次再运行的时候,就会发现并不会再有 DownloadCompile 两个步骤了:

> deno run index.js
hello world!

更多的 Deno 可能会有的问题,参考 Deno 常见问题

参考

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了