|
| 1 | +--- |
| 2 | +title: Deno 使用实践与总结 |
| 3 | +categories: [web, deno] |
| 4 | +date: 2024-12-19 |
| 5 | +author: iugo |
| 6 | +last_modified_at: 2024-12-19 09:48+08:00 |
| 7 | +--- |
| 8 | + |
| 9 | +<details lang="zh" open> |
| 10 | +<summary>中文版本</summary> |
| 11 | +<div markdown="1"> |
| 12 | + |
| 13 | +## Deno 中的依赖管理 |
| 14 | + |
| 15 | +1. 直接使用 import 进行相对路径的文件引用. |
| 16 | +2. 直接使用 import 进行 HTTPS 绝对路径的文件引用. |
| 17 | + 2.1. 比如使用 deno.land 的包 (仅限公共包). |
| 18 | + 2.2. 比如使用 GitHub 的包 (raw.githubusercontent.com). |
| 19 | + 2.3. 如 <https://esm.sh/> |
| 20 | + 2.4. 如 <https://jspm.org/> |
| 21 | + 2.5. 如 <https://www.skypack.dev/> |
| 22 | + 2.6. 如 <https://www.jsdelivr.com/esm> |
| 23 | +3. 引用 npm 包. |
| 24 | +4. 引用 jsr 包. (仅限公共包). |
| 25 | + |
| 26 | +### jsr.io 包仓库 |
| 27 | + |
| 28 | +jsr.io 是 Deno 官方团队开发维护的一个包仓库, 可以同时发布为 Deno 和 Node.js 的包. |
| 29 | + |
| 30 | +如果没有 jsr.io, 如果一个包想要同时支持 Deno 和 Node.js, 那么需要维护两套代码. |
| 31 | + |
| 32 | +如果不想维护两套代码, 则可以构建时魔改代码, 但会受到许多约束: |
| 33 | + |
| 34 | +1. 转为 Node.js 包的时候移除 `.ts` 后缀名. |
| 35 | +2. 无法添加 deno 依赖. |
| 36 | +3. 无法添加 Node.js 依赖. |
| 37 | + |
| 38 | +jsr.io 的包可以同时支持 Deno 和 Node.js, 解决了上述痛点. |
| 39 | +但是 jsr.io 有两大问题: |
| 40 | + |
| 41 | +1. jsr.io 不支持 HTTP 绝对路径的文件引用. |
| 42 | +2. jsr.io (暂时) 不支持私有包. <https://github.com/jsr-io/jsr/issues/203> |
| 43 | + |
| 44 | +## Deno 运行时特点 |
| 45 | + |
| 46 | +### Deno 中的浮点误差 |
| 47 | + |
| 48 | +虽然 Deno 的一大核心是 V8 引擎, 但 Deno 的运行时针对浮点计算进行了特殊处理. |
| 49 | + |
| 50 | +比如我们要做下面的浮点运算: `1.1 * 100` |
| 51 | + |
| 52 | +- Deno 2.1.4 (since 1.9.2) -> `110` |
| 53 | +- Chrome 131 (since 90) -> `110.00000000000001` |
| 54 | +- Node.js v20.11.0 -> `110.00000000000001` |
| 55 | + |
| 56 | +Deno 的运行时似乎在刻意避免浮点误差. |
| 57 | + |
| 58 | +## Node.js 兼容性 |
| 59 | + |
| 60 | +Node.js 的生态非常庞大, Deno 想要扩大运行时市场份额, |
| 61 | +需要为在 Node.js 环境下开发的软件提供兼容性. |
| 62 | + |
| 63 | +在 Deno 2.x 版本中, Deno 已经尽量支持了许多 Node.js 的包. |
| 64 | + |
| 65 | +但是这种支持仍然有限: |
| 66 | + |
| 67 | +1. localAddress 参数没有效果. <https://github.com/denoland/deno/issues/24153> |
| 68 | +2. [更多兼容问题见 issue 列表](https://github.com/denoland/deno/labels/node%20compat) |
| 69 | +3. [Deno 支持不完善的 Node.js 功能](https://docs.deno.com/runtime/reference/node_apis/#partially-supported-modules) |
| 70 | +4. [Deno 暂不支持的 Node.js 功能](https://docs.deno.com/runtime/reference/node_apis/#unsupported-modules) |
| 71 | + |
| 72 | +## 原生 Deno API |
| 73 | + |
| 74 | +目前 Deno 提供的 API 仍有限, 比如有下面的问题: |
| 75 | + |
| 76 | +1. 网络请求时不支持选择网卡. <https://github.com/denoland/deno/issues/27376> |
| 77 | +2. 不支持 brotli 压缩. (但通过 Node.js 兼容包可实现) |
| 78 | + |
| 79 | +</div> |
| 80 | +</details> |
| 81 | + |
| 82 | +<details lang="en"> |
| 83 | +<summary>English Version</summary> |
| 84 | +<div markdown="1"> |
| 85 | + |
| 86 | +## Dependency Management in Deno |
| 87 | + |
| 88 | +1. Direct file imports using relative paths. |
| 89 | +2. Direct file imports using HTTPS absolute paths. |
| 90 | + 2.1. Using packages from deno.land (public packages only). |
| 91 | + 2.2. Using packages from GitHub (raw.githubusercontent.com). |
| 92 | + 2.3. From <https://esm.sh/> |
| 93 | + 2.4. From <https://jspm.org/> |
| 94 | + 2.5. From <https://www.skypack.dev/> |
| 95 | + 2.6. From <https://www.jsdelivr.com/esm> |
| 96 | +3. Importing npm packages. |
| 97 | +4. Importing jsr packages (public packages only). |
| 98 | + |
| 99 | +### jsr.io |
| 100 | + |
| 101 | +jsr.io is a package registry developed and maintained by the Deno official team, |
| 102 | +allowing packages to be published for both Deno and Node.js. |
| 103 | + |
| 104 | +Without jsr.io, supporting both Deno and Node.js would require maintaining two |
| 105 | +separate codebases. |
| 106 | + |
| 107 | +To avoid maintaining dual codebases, code could be transformed during build time, |
| 108 | +but with several constraints: |
| 109 | + |
| 110 | +1. Removing `.ts` extensions when converting to Node.js packages. |
| 111 | +2. Cannot add Deno dependencies. |
| 112 | +3. Cannot add Node.js dependencies. |
| 113 | + |
| 114 | +jsr.io packages can support both Deno and Node.js, solving these pain points. |
| 115 | +However, jsr.io has two major issues: |
| 116 | + |
| 117 | +1. jsr.io doesn't support HTTP absolute path imports. |
| 118 | +2. jsr.io (temporarily) doesn't support private packages. <https://github.com/jsr-io/jsr/issues/203> |
| 119 | + |
| 120 | +## Deno Runtime Characteristics |
| 121 | + |
| 122 | +### Floating Point Precision in Deno |
| 123 | + |
| 124 | +Although V8 engine is a core component of Deno, the runtime handles floating-point |
| 125 | +calculations differently. |
| 126 | + |
| 127 | +For example, let's consider this floating-point calculation: `1.1 * 100` |
| 128 | + |
| 129 | +- Deno 2.1.4 (since 1.9.2) -> `110` |
| 130 | +- Chrome 131 (since 90) -> `110.00000000000001` |
| 131 | +- Node.js v20.11.0 -> `110.00000000000001` |
| 132 | + |
| 133 | +Deno's runtime appears to deliberately avoid floating-point errors. |
| 134 | + |
| 135 | +## Node.js Compatibility |
| 136 | + |
| 137 | +With Node.js's vast ecosystem, Deno needs to provide compatibility for software |
| 138 | +developed in Node.js environment to expand its runtime market share. |
| 139 | + |
| 140 | +In Deno 2.x, many Node.js packages are supported. |
| 141 | + |
| 142 | +However, this support is still limited: |
| 143 | + |
| 144 | +1. localAddress parameter has no effect. <https://github.com/denoland/deno/issues/24153> |
| 145 | +2. [More compatibility issues in the issue list](https://github.com/denoland/deno/labels/node%20compat) |
| 146 | +3. [Partially supported Node.js features in Deno](https://docs.deno.com/runtime/reference/node_apis/#partially-supported-modules) |
| 147 | +4. [Currently unsupported Node.js features in Deno](https://docs.deno.com/runtime/reference/node_apis/#unsupported-modules) |
| 148 | + |
| 149 | +## Deno API |
| 150 | + |
| 151 | +Currently, Deno's API offerings are still limited, with issues such as: |
| 152 | + |
| 153 | +1. No support for network interface selection in network requests. <https://github.com/denoland/deno/issues/27376> |
| 154 | +2. No support for brotli compression. (though achievable through Node.js |
| 155 | + compatibility packages) |
| 156 | + |
| 157 | +</div> |
| 158 | +</details> |
0 commit comments