Skip to content

Instantly share code, notes, and snippets.

@image72
Forked from futurist/从Node到Deno.md
Created March 8, 2023 11:19
Show Gist options
  • Select an option

  • Save image72/8cd975d4d582f036fb3de7ca53e6af7e to your computer and use it in GitHub Desktop.

Select an option

Save image72/8cd975d4d582f036fb3de7ca53e6af7e to your computer and use it in GitHub Desktop.

Revisions

  1. @futurist futurist revised this gist May 24, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -71,7 +71,7 @@ export * as server from "https://deno.land/[email protected]/http/server.ts";

    然后:`deno run --allow-net --unstable --importmap=import_map.json main.ts` 来引入。

    注意以上 `--unsatble` 参数,也就是deno目前其实并没有官方建议的包管理方式,只能等将来。并且浏览器标准中[Import Map](https://wicg.github.io/import-maps/)规范目前只是非官方草案状态,将来随时可能会发生变化。
    注意以上 `--unsatble` 参数是必须的,因为它模拟了浏览器标准的[Import Map](https://wicg.github.io/import-maps/)规范,但目前其状态是**非官方草案**,将来随时可能会发生变化。


    **关于缓存**
  2. @futurist futurist revised this gist May 23, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -71,7 +71,8 @@ export * as server from "https://deno.land/[email protected]/http/server.ts";

    然后:`deno run --allow-net --unstable --importmap=import_map.json main.ts` 来引入。

    注意以上 `--unsatble` 参数,也就是deno目前其实并没有官方建议的包管理方式,只能等将来。
    注意以上 `--unsatble` 参数,也就是deno目前其实并没有官方建议的包管理方式,只能等将来。并且浏览器标准中[Import Map](https://wicg.github.io/import-maps/)规范目前只是非官方草案状态,将来随时可能会发生变化。


    **关于缓存**

  3. @futurist futurist revised this gist May 23, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -388,7 +388,7 @@ $ /usr/bin/time -lp node hello.js

    Deno现有的库比Node少很多,常用的对应如下:

    - nodemon -> [demon](https://deno.land/x/denom)
    - nodemon -> [denon](https://deno.land/x/denon)
    - express -> [denotrain](https://deno.land/x/denotrain)
    - koa -> [oak](https://deno.land/x/oak)
    - hapi -> [pogo](https://deno.land/x/pogo)
  4. @futurist futurist revised this gist May 22, 2020. 1 changed file with 32 additions and 1 deletion.
    33 changes: 32 additions & 1 deletion 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -325,17 +325,48 @@ deno run -A -r --unstable https://deno.land/x/webview/examples/multiple.ts

    **执行时间:**

    > 冷启动本地导入模块并编译 `0.5s`,热启动 `100ms`,起50个Worker `0.5s`,给4个Worker发400条消息(round_robin) `200ms`,下图:
    > 冷启动本地导入模块并编译 `0.5s`,热启动 `100ms` 起50个Worker `0.5s`,给4个Worker发400条消息(round_robin) `200ms`,下图:
    ![Execute Time](//tosv.byted.org/obj/tech/images/1590134684467_fef25753367265cac0309d602f94240f.png)

    官方没有提供Node对比数据,我们就以运行一个`.js`文件(Deno此时为热启动)10次,做个简单的对比:(macOS 10.14, Node版本v12.16.3)

    ```sh
    $ echo 'console.log("Hello World!");' > hello.js

    $ time for i in {1..10}; do deno run hello.js; done
    real 0m0.362s
    user 0m0.171s
    sys 0m0.088s

    $ time for i in {1..10}; do node hello.js; done
    real 0m0.475s
    user 0m0.358s
    sys 0m0.108s
    ```

    **系统+用户时间**: Node `466ms`, Deno `259ms`,热启动Deno更快些。

    **内存占用:**

    > 冷启动本地导入模块并编译 `68M`,热启动 `20M`,起50个Worker `157M`,给4个Worker发400条消息(round_robin) `43M`,下图:
    ![Max Memory](//tosv.byted.org/obj/tech/images/1590134690520_b91cd43f5681f7c3773e0a3f98f89b31.png)

    官方没有提供Node对比数据,我们就以运行一个`.js`文件(Deno此时为热启动),统计一下RSS:(macOS 10.14, Node版本v12.16.3)

    ```sh
    $ echo 'console.log("Hello World!");' > hello.js

    $ /usr/bin/time -lp deno run hello.js
    ... ...
    16207872 maximum resident set size

    $ /usr/bin/time -lp node hello.js
    19189760 maximum resident set size
    ```
    **最大RSS**: Node `18.3M`,Deno `15.5M`,两者相差不大,Deno略小。


    **HTTP吞吐:**

  5. @futurist futurist revised this gist May 22, 2020. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -363,6 +363,9 @@ Deno现有的库比Node少很多,常用的对应如下:
    - hapi -> [pogo](https://deno.land/x/pogo)
    - commander -> [denomander](https://deno.land/x/denomander)
    - ejs -> [dejs](https://deno.land/x/dejs)
    - webpack -> 原生替代: `deno bundle myLib.ts myLib.bundle.js`
    - prettier -> 原生替代:`deno fmt`
    - `npm scripts` -> [denox](https://deno.land/x/denox) / [velociraptor](https://deno.land/x/velociraptor)

    另外纯JS库像 `lodash`, `moment`等库,理论上基本直接能用或做很少的工作就能用。

  6. @futurist futurist revised this gist May 22, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -325,7 +325,7 @@ deno run -A -r --unstable https://deno.land/x/webview/examples/multiple.ts

    **执行时间:**

    > 冷启动本地导入模块并编译 `0.5s`,热启动 `100s`,起50个Worker `0.5s`,给4个Worker发400条消息(round_robin) `200s`,下图:
    > 冷启动本地导入模块并编译 `0.5s`,热启动 `100ms`,起50个Worker `0.5s`,给4个Worker发400条消息(round_robin) `200ms`,下图:
    ![Execute Time](//tosv.byted.org/obj/tech/images/1590134684467_fef25753367265cac0309d602f94240f.png)

  7. @futurist futurist revised this gist May 22, 2020. 1 changed file with 45 additions and 3 deletions.
    48 changes: 45 additions & 3 deletions 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -295,9 +295,9 @@ Stream的实现, Node与标准几乎完全不同,Deno完全按标准实现了

    基本上Node使用C++扩展,而Deno使用[Rust]()

    与V8通信,Node使用[N-API](https://nodejs.org/docs/latest/api/addons.html),Deno内建了[通信机制](https://github.com/denoland/deno/blob/master/core/core.js#L184)
    与V8通信,Node使用[N-API](https://nodejs.org/docs/latest/api/addons.html),Deno内建了 [插件](https://github.com/denoland/deno/tree/master/test_plugin) [通信机制](https://github.com/denoland/deno/blob/master/core/core.js#L184)

    向系统扩展,Node使用[C++ Addons](https://nodejs.org/docs/latest/api/addons.html),Deno使用[Rust](https://deno.land/x/plugin_prepare)
    向系统扩展,Node使用[C++ Addons](https://nodejs.org/docs/latest/api/addons.html),Deno使用[Rust插件](https://deno.land/x/plugin_prepare)

    以下代码复制到命令行执行,可以感受一下Deno进行系统扩展的方便:

    @@ -309,7 +309,49 @@ deno run -A -r --unstable https://deno.land/x/webview/examples/multiple.ts

    因为Deno拥抱了浏览器生态与标准,所以浏览器中有但Node中无的东西基本都是Deno的优势,比如:[Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)

    具体可以参考[Deno文档](https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts)
    具体可以参考[Deno文档](https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts)

    另外Deno内置了 `window` 对象,这样做[同构应用(Isomorphic Application)](https://en.wikipedia.org/wiki/Isomorphic_JavaScript)方便不少。

    还有就是原生[TypeScript](https://www.typescriptlang.org/)支持,做大项目工程化,协作利器。

    ### - 性能差异

    主要分为运行时,网络I/O几个方面,详情可见[官网Benchmarks](https://deno.land/benchmarks),以及[Deno 1.0发版时关于性能的说明](https://deno.land/v1#http-server-performance),总体来说,如果特别关心性能,要考虑一下使用JS运行时是否真的合适。

    #### 启动执行

    执行时间官网只有Deno自身的数据,冷启动Deno要编译TS到JS,热启动是从缓存中直接执行JS,关键指标解读:

    **执行时间:**

    > 冷启动本地导入模块并编译 `0.5s`,热启动 `100s`,起50个Worker `0.5s`,给4个Worker发400条消息(round_robin) `200s`,下图:
    ![Execute Time](//tosv.byted.org/obj/tech/images/1590134684467_fef25753367265cac0309d602f94240f.png)


    **内存占用:**

    > 冷启动本地导入模块并编译 `68M`,热启动 `20M`,起50个Worker `157M`,给4个Worker发400条消息(round_robin) `43M`,下图:
    ![Max Memory](//tosv.byted.org/obj/tech/images/1590134690520_b91cd43f5681f7c3773e0a3f98f89b31.png)


    **HTTP吞吐:**

    - `deno_core_http_bench`是指在rust中使用`deno_core`模块,处理JS发出的请求
    - `hyper`是rust原生开发的http server

    > **QPS:** `deno_core_http_bench`最高 `91K`,hyper为 `76K``node_http``37K``deno_http`最低为 `27K`,其中Deno为Node的 `72%`,下图:
    ![HTTP Throughput](//tosv.byted.org/obj/tech/images/1590134700644_8ac96ffba08bf8e3e6f26b244d817837.png)

    **HTTP延迟:**

    > `node_http`延迟最高`2ms - 65ms`,波动非常大,`deno_http`一直稳定在`1ms - 3ms`之间,波动较小,`hyper`延时最小,下图:
    ![HTTP Latency](//tosv.byted.org/obj/tech/images/1590134706664_effecd94d53ef78b4acc2a113409bb24.png)


    ## * 第四部分:常用库

  8. @futurist futurist revised this gist May 21, 2020. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # 从Node到Deno
    # 从Node到Deno,你需要知道的

    ## * 第一部分:安装

    @@ -12,7 +12,7 @@
    原生Node包安装会需要 **root权限**,安装到 `/usr/local/bin`,然后每一个 `npm i -g` 全局安装都会需要 **root** 权限!

    **安装方法二**
    [nvm](https://github.com/nvm-sh/nvm),安装多个node版本到 `~/.nvm` 目录,同时需要修改 `.bashrc``.bash_profile` 来激活某个版本,严重拖慢启动`bash`启动速度
    使用[nvm](https://github.com/nvm-sh/nvm),安装多个node版本到 `~/.nvm` 目录,同时需要修改 `.bashrc``.bash_profile` 来激活某个版本,严重拖慢启动`bash`的速度

    **安装方法三**
    [全手动安装](https://www.jianshu.com/p/6d68038430f3),涉及到一堆环境变量的修改和位置依赖,弄不好容易变成坑。
    @@ -28,7 +28,7 @@

    ### B. Deno安装

    由于Deno只有一个可执行文件,安装就是下载它,1.0版本为**42M**,下载即安装。官方脚本默认安装位置:`~/.deno/bin/deno`,用任何方法安装都可以,只要你能运行得到。
    由于Deno只有一个可执行文件,[Deno官方安装](https://deno.land/#installation)其实就是下载它,1.0版本解压后为**42M**,下载即安装。官方脚本默认安装位置:`~/.deno/bin/deno`,用任何方法安装都可以,只要你能运行得到。

    涉及环境变量:
    - `DENO_DIR`(Deno主目录, 不设置的话默认为 `~/.deno`)
    @@ -94,7 +94,7 @@ Windows: `~/AppData/Local/deno`
    | **Linux** | **Node** | **Deno** |
    | ------------------------------: | :---------------------------- | :------------------------------ |
    | Processes | require('process') | Web Workers |
    | Syscalls | require('v8) | Ops |
    | Syscalls | require('v8) / Addons | Ops |
    | File descriptors (fd) | via `process.stdxx`, `fs.open` | [Resource ids (rid)] |
    | Scheduler | [libuv] | [Tokio] |
    | Userland: libc++ / glib / boost | https://www.npmjs.com | https://deno.land/std/ |
    @@ -149,7 +149,7 @@ const __dirname = path.dirname(import.meta.url)
    ```


    **注意:** `https://deno.land/std/node/module.ts` 模块使用了不稳定API,要用以下命令进行
    **注意:** `https://deno.land/std/node/module.ts` 模块使用了不稳定API,要用以下命令运行

    ```deno run --unstable --allow-read main.ts```

    @@ -299,10 +299,10 @@ Stream的实现, Node与标准几乎完全不同,Deno完全按标准实现了

    向系统扩展,Node使用[C++ Addons](https://nodejs.org/docs/latest/api/addons.html),Deno使用[Rust](https://deno.land/x/plugin_prepare)

    可以感受一下Deno扩展系统的方便
    以下代码复制到命令行执行,可以感受一下Deno进行系统扩展的方便

    ```sh
    $ deno run -A -r --unstable https://deno.land/x/webview/examples/multiple.ts
    deno run -A -r --unstable https://deno.land/x/webview/examples/multiple.ts
    ```

    ### - Deno有但Node无
  9. @futurist futurist revised this gist May 21, 2020. 1 changed file with 25 additions and 17 deletions.
    42 changes: 25 additions & 17 deletions 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -1,32 +1,43 @@
    # 从Node到Deno

    ## --- 第一部分:安装 ---
    ## * 第一部分:安装

    以MacOS系统为例,说明安装的不同

    ### A. Node安装

    涉及的文件:`node`, `npm`, `npx`, `node_modules` 文件夹

    涉及环境变量:`NODE_HOME` (主目录), `NODE_PATH` (全局模块目录), `NPM_CONFIG_PREFIX` (NPM目录), `NPM_CONFIG_CACHE` (NPM缓存), `NPM_CONFIG_REGISTRY` (NPM中心仓库)

    - **方法一**
    **安装方法一**
    原生Node包安装会需要 **root权限**,安装到 `/usr/local/bin`,然后每一个 `npm i -g` 全局安装都会需要 **root** 权限!

    - **方法二**
    **安装方法二**
    [nvm](https://github.com/nvm-sh/nvm),安装多个node版本到 `~/.nvm` 目录,同时需要修改 `.bashrc``.bash_profile` 来激活某个版本,严重拖慢启动`bash`启动速度。

    - **方法三**
    **安装方法三**
    [全手动安装](https://www.jianshu.com/p/6d68038430f3),涉及到一堆环境变量的修改和位置依赖,弄不好容易变成坑。

    涉及环境变量:
    - `NODE_HOME` (主目录)
    - `NODE_PATH` (全局模块目录)
    - `NPM_CONFIG_PREFIX` (NPM目录)
    - `NPM_CONFIG_CACHE` (NPM缓存)
    - `NPM_CONFIG_REGISTRY` (NPM中心仓库)
    - 还有很多...


    ### B. Deno安装

    由于Deno只有一个可执行文件,安装就是下载它,1.0版本为**42M**,下载即安装。官方脚本默认安装位置:`~/.deno/bin/deno`,用任何方法安装都可以,只要你能运行得到。

    涉及环境变量:`DENO_DIR`(Deno主目录, 不设置默认 `~/.deno`), `DENO_INSTALL_ROOT` (`deno install`命令的输出目录,不设置默认`~/.deno/bin`), `NO_COLOR` (是否启用控制台颜色), `HTTP_PROXY` & `HTTPS_PROXY` (代理)
    涉及环境变量:
    - `DENO_DIR`(Deno主目录, 不设置的话默认为 `~/.deno`)
    - `DENO_INSTALL_ROOT` (`deno install`命令的输出目录,不设置的话默认为`~/.deno/bin`)
    - `NO_COLOR` (是否启用控制台颜色)
    - `HTTP_PROXY` & `HTTPS_PROXY` (代理)


    ## --- 第二部分:模块 ---
    ## * 第二部分:模块

    ### A. Node

    @@ -76,12 +87,12 @@ Windows: `~/AppData/Local/deno`



    ## --- 第三部分:运行时 ---
    ## * 第三部分:运行时

    ### - Linux操作系统类比表

    | **Linux** | **Node** | **Deno** |
    | ------------------------------: | :------------------------------- | :------------------------------- |
    | ------------------------------: | :---------------------------- | :------------------------------ |
    | Processes | require('process') | Web Workers |
    | Syscalls | require('v8) | Ops |
    | File descriptors (fd) | via `process.stdxx`, `fs.open` | [Resource ids (rid)] |
    @@ -162,7 +173,7 @@ assertEquals("world", "world");
    ```


    #### (EventEmitter)[https://nodejs.org/docs/latest/api/events.html]
    #### [EventEmitter](https://nodejs.org/docs/latest/api/events.html)

    ```ts
    import EventEmitter, { on } from "https://deno.land/std/node/events.ts";
    @@ -188,7 +199,7 @@ Node示例代码:打印 `0x0102030405060708` 的`Uint64`值
    // buf 长度固定
    const buf = Buffer.from(new Uint8Array([1,2,3,4,5,6,7,8]));
    const d = new DataView(buf.buffer).getBigUint64(0);
    console.log(obj.length, ',', d);
    console.log(buf.length, ',', d);
    //output: 8, 72623859790382856n
    ```

    @@ -199,7 +210,7 @@ const buf = new Deno.Buffer();
    // buf.write 会改变 Buffer 的长度,向 buf 后追加数据
    await buf.write(new Uint8Array([1,2,3,4,5,6,7,8]));
    const d = new DataView(buf.bytes().buffer).getBigUint64(0);
    console.log(obj.length, ',', d);
    console.log(buf.length, ',', d);
    //output: 8, 72623859790382856n
    ```

    @@ -300,8 +311,7 @@ $ deno run -A -r --unstable https://deno.land/x/webview/examples/multiple.ts

    具体可以参考[Deno文档](https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts)


    ## --- 第四部分:常用库 ---
    ## * 第四部分:常用库

    Deno现有的库比Node少很多,常用的对应如下:

    @@ -317,5 +327,3 @@ Deno现有的库比Node少很多,常用的对应如下:
    更多的,可以在[官网搜索](https://deno.land/x)




  10. @futurist futurist created this gist May 21, 2020.
    321 changes: 321 additions & 0 deletions 从Node到Deno.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,321 @@
    # 从Node到Deno

    ## --- 第一部分:安装 ---

    以MacOS系统为例,说明安装的不同

    ### A. Node安装

    涉及的文件:`node`, `npm`, `npx`, `node_modules` 文件夹

    涉及环境变量:`NODE_HOME` (主目录), `NODE_PATH` (全局模块目录), `NPM_CONFIG_PREFIX` (NPM目录), `NPM_CONFIG_CACHE` (NPM缓存), `NPM_CONFIG_REGISTRY` (NPM中心仓库)

    - **方法一**
    原生Node包安装会需要 **root权限**,安装到 `/usr/local/bin`,然后每一个 `npm i -g` 全局安装都会需要 **root** 权限!

    - **方法二**
    [nvm](https://github.com/nvm-sh/nvm),安装多个node版本到 `~/.nvm` 目录,同时需要修改 `.bashrc``.bash_profile` 来激活某个版本,严重拖慢启动`bash`启动速度。

    - **方法三**
    [全手动安装](https://www.jianshu.com/p/6d68038430f3),涉及到一堆环境变量的修改和位置依赖,弄不好容易变成坑。

    ### B. Deno安装

    由于Deno只有一个可执行文件,安装就是下载它,1.0版本为**42M**,下载即安装。官方脚本默认安装位置:`~/.deno/bin/deno`,用任何方法安装都可以,只要你能运行得到。

    涉及环境变量:`DENO_DIR`(Deno主目录, 不设置默认 `~/.deno`), `DENO_INSTALL_ROOT` (`deno install`命令的输出目录,不设置默认`~/.deno/bin`), `NO_COLOR` (是否启用控制台颜色), `HTTP_PROXY` & `HTTPS_PROXY` (代理)


    ## --- 第二部分:模块 ---

    ### A. Node

    Node运行时按`node_modules`[查找算法](https://nodejs.org/api/modules.html#modules_accessing_the_main_module)查找`node_modules`,模块安装下载与依赖管理主要依靠`npm`,另外还有:`cnpm``pnpm`, `tnpm`, `bnpm`, `yarn`......

    `package.json`是模块管理入口文件,文件内容为`JSON`格式,依赖包存放在`dependencies`内。

    `npm install`是更新依赖包的命令。

    ### B. Deno

    没有独立的依赖管理工具,外部可以使用 `HTTP 协议` 来下载并缓存模块文件,社区中建议使用一个 `deps.ts` 文件来存放所有的外部文件,如下

    ```ts
    // deps.ts
    export * as server from "https://deno.land/[email protected]/http/server.ts";
    ```

    **以上用法并非官方!**,官方建议使用 `import_map.json`,但 **它是非稳定的!**

    ```json
    // import_map.json

    {
    "imports": {
    "http/": "https://deno.land/std/http/"
    }
    }
    // import { serve } from "http/server.ts";
    ```

    然后:`deno run --allow-net --unstable --importmap=import_map.json main.ts` 来引入。

    注意以上 `--unsatble` 参数,也就是deno目前其实并没有官方建议的包管理方式,只能等将来。

    **关于缓存**

    建议设置 `DENO_DIR` 环境变量,若此变量不为空则缓存目录为`$DENO_DIR`,否则会用系统缓存目录:

    macOS: `~/Library/Caches/deno`
    Windows: `~/AppData/Local/deno`

    缓存通常包含目录:`deps` (下载的依赖文件缓存,以内容hash命令) 和 `gen` (编译后的js生成物)

    删除上面两个文件即可达到清除缓存效果。




    ## --- 第三部分:运行时 ---

    ### - Linux操作系统类比表

    | **Linux** | **Node** | **Deno** |
    | ------------------------------: | :------------------------------- | :------------------------------- |
    | Processes | require('process') | Web Workers |
    | Syscalls | require('v8) | Ops |
    | File descriptors (fd) | via `process.stdxx`, `fs.open` | [Resource ids (rid)] |
    | Scheduler | [libuv] | [Tokio] |
    | Userland: libc++ / glib / boost | https://www.npmjs.com | https://deno.land/std/ |
    | /proc/\$\$/stat | [process.report] | [Deno.metrics()] |
    | man pages | [node docs] | [deno types] |

    [libuv]: https://github.com/libuv/libuv
    [Tokio]: https://github.com/tokio-rs/tokio
    [process.report]: https://nodejs.org/api/report.html
    [Resource ids (rid)]: https://deno.land/manual/contributing/architecture#resources
    [Deno.metrics()]: https://deno.land/manual/contributing/architecture#metrics
    [node docs]: https://nodejs.org/docs/latest/api/
    [deno types]: https://doc.deno.land/


    ### - API

    以下以Node经典API为例说明deno对应的用法。

    **注意:** Deno跟Node不是同一个东西,以下只是列出可以在功能上达到相似效果的一些用法,便于理解,可以参考,不可照搬,切记!

    #### require('my-module')

    Deno使用标准[ES6 Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules),而Node使用了[CommonJS2](https://github.com/webpack/webpack/issues/1114#issuecomment-105509929),虽然[13.2.0兼容了ES6 Modules](https://medium.com/@nodejs/announcing-core-node-js-support-for-ecmascript-modules-c5d6dc29b663),但两种方式混用的情况在前端领域很常见,非常不利于维护。

    **常见require在Deno的对应**

    ```js
    require.main -> import.meta.main
    __filename -> import.meta.url
    __dirname -> 核心无对应 (需借助外部模块实现)
    ```

    **一些Deno的[node polyfill](https://deno.land/std/node/)**

    ```ts
    import { createRequire } from "https://deno.land/std/node/module.ts";
    const require = createRequire(import.meta.url);
    // 加载原生模块polyfill
    // 可加载列表:https://deno.land/std/node#supported-builtins
    const path = require("path");
    // 可加载不带后缀模块,自动解析后缀/目录.
    const cjsModule = require("./my_mod");
    // 可兼容Node经典的node_modules查找算法
    const leftPad = require("left-pad");

    console.log(leftPad, cjsModule);
    console.log(path.join('root', 'xx.js'))

    // 实现上面的__dirname
    const __dirname = path.dirname(import.meta.url)
    ```


    **注意:** `https://deno.land/std/node/module.ts` 模块使用了不稳定API,要用以下命令进行:

    ```deno run --unstable --allow-read main.ts```

    另外还有以下独立模块不需加 `--unstable`:

    https://deno.land/std/path 对应于 [path模块](https://nodejs.org/docs/latest/api/path.html)

    https://deno.land/std/fs 对应于 [fs模块](https://nodejs.org/docs/latest/api/fs.html)

    https://deno.land/std/bytes 可实现`Buffer.concat()`

    https://deno.land/std/http 对应于 [http模块](https://nodejs.org/docs/latest/api/http.html)



    #### [Assertion](https://nodejs.org/docs/latest/api/assert.html)

    ```ts
    import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
    assertEquals("world", "world");
    ```


    #### (EventEmitter)[https://nodejs.org/docs/latest/api/events.html]

    ```ts
    import EventEmitter, { on } from "https://deno.land/std/node/events.ts";

    const testEmitter = new EventEmitter();
    testEmitter.on("event", () => {
    console.log("event fired");
    });
    testEmitter.emit('event');
    ```

    #### [Buffer](https://nodejs.org/docs/latest/api/buffer.html)

    注意Node的`Buffer`实现是在`ArrayBuffer`标准提出之前的,所以并不标准,`Deno.Buffer` 尽量向标准靠拢,两者有本质区别!某些API有相似之处。

    `Deno.Buffer`实现其实是基于`Go Buffer`(https://golang.org/pkg/bytes/#Buffer)的。

    > Deno.Buffer is NOT the same thing as Node's Buffer. Node's Buffer was created in 2009 before JavaScript had the concept of ArrayBuffers. It's simply a non-standard ArrayBuffer.
    Node示例代码:打印 `0x0102030405060708``Uint64`

    ```js
    // buf 长度固定
    const buf = Buffer.from(new Uint8Array([1,2,3,4,5,6,7,8]));
    const d = new DataView(buf.buffer).getBigUint64(0);
    console.log(obj.length, ',', d);
    //output: 8, 72623859790382856n
    ```


    ```ts
    // buf 长度可变
    const buf = new Deno.Buffer();
    // buf.write 会改变 Buffer 的长度,向 buf 后追加数据
    await buf.write(new Uint8Array([1,2,3,4,5,6,7,8]));
    const d = new DataView(buf.bytes().buffer).getBigUint64(0);
    console.log(obj.length, ',', d);
    //output: 8, 72623859790382856n
    ```

    以上只是做为Demo示例,说明Node中`Buffer`是定长内存块,而`Deno.Buffer`是可变长内存块,所以 `Deno` 有以下API而 Node 没有:

    ```ts
    buf.grow(n) //变长n字节
    buf.truncate(n) //保留n字节
    buf.reset() //相当于 buf.truncate(0)
    ```

    Node要增加只能通过拼接一个新的Buffer:
    ```js
    let newBuf = Buffer.concat(buf, Buffer.alloc(10));
    ```

    另外,由于历史包袱,Node现在的Buffer API看着非常乱!

    #### [Process](https://nodejs.org/docs/latest/api/process.html)

    对应的几个常用的代码:

    ```js
    process.argv -> Deno.execPath() + import.meta.url + Deno.args //注意Deno拆成了三部分
    process.abort() ->
    process.env -> Deno.env.toObject() // 需要--allow-env

    // 以下相同
    process.exit(1) -> Deno.exit(1)
    process.chdir(dir) -> Deno.chdir(dir)
    process.execPath() -> Deno.execPath()
    process.pwd() -> Deno.pwd()
    process.pid -> Deno.pid
    process.stderr -> Deno.stderr
    process.stdout -> Deno.stdout
    process.stdin -> Deno.stdin
    process.version -> Deno.version
    ```

    #### [Child_process](https://nodejs.org/docs/latest/api/child_process.html)

    Node会有`exec``spawn`,Deno只有`run`:

    ```js
    //Node
    const util = require('util');
    const exec = util.promisify(require('child_process').exec);
    const { stdout } = await exec('echo hello');
    console.log(`stdout: ${stdout}`);
    ```

    ```ts
    //Deno
    const p = Deno.run({
    cmd: ["echo", "hello"],
    stdout: 'piped',
    stderr: 'piped',
    });
    const outBuf = new Deno.Buffer()
    // p.stdout!是一个Deno.Reader
    await outBuf.readFrom(p.stdout!)
    const stdout = new TextDecoder().decode(outBuf.bytes().buffer)
    console.log(`stdout: ${stdout}`);
    ```

    可以看到Deno的代码量其实更大。

    #### [Stream](https://nodejs.org/docs/latest/api/stream.html)

    Stream的实现, Node与标准几乎完全不同,Deno完全按标准实现了一遍,两者对应如下:

    **Writable** 对应于 标准的[WritableStream](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream)

    **Readable** 对应于 标准的[ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)

    **Duplex and Transform Streams** 对应于 Deno的[TransformStream](https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts#TransformStream)

    不见得哪个更优秀,目前Node已有的大量基于Stream的库才是王道。


    ### - 扩展

    基本上Node使用C++扩展,而Deno使用[Rust]()

    与V8通信,Node使用[N-API](https://nodejs.org/docs/latest/api/addons.html),Deno内建了[通信机制](https://github.com/denoland/deno/blob/master/core/core.js#L184)

    向系统扩展,Node使用[C++ Addons](https://nodejs.org/docs/latest/api/addons.html),Deno使用[Rust](https://deno.land/x/plugin_prepare)

    可以感受一下Deno扩展系统的方便:

    ```sh
    $ deno run -A -r --unstable https://deno.land/x/webview/examples/multiple.ts
    ```

    ### - Deno有但Node无

    因为Deno拥抱了浏览器生态与标准,所以浏览器中有但Node中无的东西基本都是Deno的优势,比如:[Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)

    具体可以参考[Deno文档](https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts)


    ## --- 第四部分:常用库 ---

    Deno现有的库比Node少很多,常用的对应如下:

    - nodemon -> [demon](https://deno.land/x/denom)
    - express -> [denotrain](https://deno.land/x/denotrain)
    - koa -> [oak](https://deno.land/x/oak)
    - hapi -> [pogo](https://deno.land/x/pogo)
    - commander -> [denomander](https://deno.land/x/denomander)
    - ejs -> [dejs](https://deno.land/x/dejs)

    另外纯JS库像 `lodash`, `moment`等库,理论上基本直接能用或做很少的工作就能用。

    更多的,可以在[官网搜索](https://deno.land/x)