- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Deno :它比 Node.js 更好吗?由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
Deno 是一个类似于 Node.js 的 JavaScript 和 TypeScript 运行时,基于 Rust 和 JavaScript V8 引擎构建。它由 Node.js 创始人 Ryan Dahl 创建,以弥补他在 2009 年最初设计和发布 Node.js 时所犯的错误.
Ryan's 有关 Node.js 的遗憾在 2018 年 JSConf EU 上著名的演讲 “我对 Node.js 遗憾的十件事” 有充分的记录。总而言之,他感叹缺乏对安全性的关注、通过 node_modules 解析模块、浏览器工作方式的各种偏差以及其他问题,他开始在 Deno 中修复这些错误.
在本文中,我们将讨论 Deno 的创建原因以及它与 Node.js 相比的优缺点。还将对 Deno 的怪癖(quirks)和功能做一个实用概述,以便您决定它是否适合于您的下一个项目.
Deno 做为一个独立的、自包含的二进制文件没有任何依赖。你可以通过多种方式安装 Deno,具体取决于你的操作系统。最简单的方法是下载并执行一个 shell 脚本,如下所示:
# Linux and macOS$ curl -fsSL https://deno.land/x/install/install.sh | sh# Windows PowerShell$ iwr https://deno.land/x/install/install.ps1 -useb | iex
一旦你为你的操作系统执行了适当的命令,Deno CLI 二进制文件将会下载到你的计算机。根据你选择的安装方法,你需要添加这个二进制文件位置到你的 PATH.
你可以在 Bash 中添加以下行到你的 $HOME/bash_profile 文件来执行此操作。你可能需要开启一个新的 shell 会话来使更改生效.
export DENO_INSTALL="$HOME/.deno" export PATH="$DENO_INSTALL/bin:$PATH"
运行以下命令,验证 Deno 的安装版本。如果这个 CLI 已经下载成功并且添加到您的 PATH,控制台应该会打印输出 Deno 版本信息.
$ deno --version deno 1.14.2 (release, x86_64-unknown-linux-gnu) v8 9.4.146.16 typescript 4.4.2
如果你的 Deno 版本已过时,可以通过 upgrade 子命令升级到最新的 release 版本.
$ deno upgradeLooking up latest versionFound latest version 1.14.2 Checking https://github.com/denoland/deno/releases/download/v1.14.2/deno-x86_64-unknown-linux-gnu.zip 31.5 MiB / 31.5 MiB (100.0%) Deno is upgrading to version 1.14.2 Archive: /tmp/.tmpfdtMXE/deno.zip inflating: denoUpgraded successfully
接下来,编写一个常用的 Hello world 程序来验证是否可以正常工作。可以为你的 Deno 项目创建一个目录并在该目录下创建一个 index.ts 文件放入以下代码:
function hello(str: string) { return `Hello ${str}!`; } console.log(hello("Deno"));
在 deno run 子命令后将文件名做为参数执行,如果输出 “Hello Deno!”,意味着你已经成功的安装了 Deno.
$ deno run index.ts Check file:///home/ayo/dev/deno/index.ts Hello Deno!
要了解 Deno CLI 提供的其它功能及选项,使用 --help 标志:
$ deno --help
Deno 相较于 Node.js 的一大卖点是它对 TypeScript 的一流支持.
正如你所看到的,除了安装 Deno CLI 之外,你不需要做任何的事情让它来工作。与其前身一样,使用 V8 引擎运行时来解析解释和执行 JavaScript 代码,但它还在其可执行文件中使用 TypeScript 编译器以实现对 TypeScript 的支持.
在后台,TypeScript 代码被检查和编译。生成的 JavaScript 代码会缓存在文件系统上的一个目录中,可以再次执行而无需从头编译。你可以使用 deno info 检查缓存目录位置和其它包含 Deno 管理文件的目录.
在使用 TypeScript 时 Deno 不需要任何配置,但如果你想调整 TypeScript 编译器解析代码的方式,你可以提供一个 JSON 文件指定 TypeScript 的编译选项。尽管 tsconfig.json 是用 TSC 编译时的一个常见选择方式,但是 Deno 团队建议使用 deno.json 因为其它特定于 Deno 的配置选项也可以放置在这里.
请注意 Deno 不支持所有的 TypeScript 编译选项。在 Deno 的文档中提供了一个完整的可用的的选项和它们的默认值。对于 Deno 的示例配置文件如下所示:
{ "compilerOptions": { "checkJs": true, "noImplicitReturns": true, "noUnusedLocals": true, "noUnusedParameters": true, "noUncheckedIndexedAccess": true } }
在撰写本文时,Deno 不会自动检测 deno.json 文件,因此必须通过 --config 标志指定它。然后,这个功能计划在未来的一个版本发布.
$ deno run --config deno.json index.ts
当 Deno CLI 遇到类型错误时,它会停止脚本编译并以非 0 状态码退出终止。你可以通过以下方式绕错错误:
在错误发生的地方使用 //@ts-ignore 或 //@ts-expect-error // @ts-nocheck 在一个文件的开始忽略所有的错误.
Deno 还提供了一个 --no-check 标志来完全禁用类型检查。这有助于防止 TypeScript 编译器在快速迭代问题时减慢你的速度.
$ deno run --no-check index.ts
Deno 以成为 JavaScript 和 TypeScript 的安全运行时而骄傲。它维护安全性部分的方式是通过权限功能完成的。为了演示权限功能在 Deno 中的工作方式,添加以下脚本到您的 index.ts 文件。这个脚本会从 disease.sh 获取最新的全球 Covid-19 统计数据.
async function getCovidStats() { try { const response = await fetch("https://disease.sh/v3/covid-19/all"); const data = await response.json(); console.table(data); } catch (err) { console.error(err); } } getCovidStats();
当你尝试执行脚本时,它应该显示 PermissionDenied 错误:
$ deno run index.ts PermissionDenied: Requires net access to "disease.sh", run again with the --allow-net flag # PermissionDenied:需要对 “disease.sh” 的网络访问,使用 --allow-net 标志再次运行。
上面的错误消息表明脚本没有给予网络访问权限,它建议在命令中包含 --allow-net 标志以授予访问权限.
$ deno run --allow-net index.ts ┌────────────────────────┬───────────────┐│ (idx) │ Values │├────────────────────────┼───────────────┤│ updated │ 1633335683059 ││ cases │ 235736138 ││ todayCases │ 32766 ││ deaths │ 4816283 ││ todayDeaths │ 670 ││ recovered │ 212616434 ││ todayRecovered │ 51546 ││ active │ 18303421 ││ critical │ 86856 ││ casesPerOneMillion │ 30243 ││ deathsPerOneMillion │ 617.9 ││ tests │ 3716763329 ││ testsPerOneMillion │ 473234.63 ││ population │ 7853954694 ││ oneCasePerPeople │ 0 ││ oneDeathPerPeople │ 0 ││ oneTestPerPeople │ 0 ││ activePerOneMillion │ 2330.47 ││ recoveredPerOneMillion │ 27071.26 ││ criticalPerOneMillion │ 11.06 ││ affectedCountries │ 223 │└────────────────────────┴───────────────┘
你可以提供一个以逗号分隔的主机名或 IP 地址的允许列表做为 --allow-net的参数,以便脚本仅可以访问指定的网站,而不是授予脚本访问所有网站的权限(如上所示)。如果脚本尝试链接不在允许列表中的列,Deno 将会阻止它的链接,并且脚本将会执行失败.
$ deno run --allow-net='disease.sh' index.ts
这个功能是 Deno 对 Node.js 的改进之一,任何脚本都可以通过网络访问任何资源。读取和写入文件系统也存在类似的权限。如果一个脚本需要执行任一任务,你需要分别指定 --allow-read 和 --allow-write 权限。两个标志允许你为脚本设置特定可访问的目录,以便文件系统的其它部分免受篡改。Deno 还提供了一个 --allow-all 标志,如果需要,可以为一个脚本开启所有的安全敏感功能.
Deno 的主要目标之一是尽可能与 Web 浏览器兼容。这反映在它使用 Web 平台 API,而不是为某些操作创建特定于 Deno 的 API。例如,我们在上一节中看到了 Fetch API 的实际应用。这是一个在浏览器中使用的确切 Fetch API,在必要时有一些偏差以说明 Deno 中独特的安全模型(这些更改大多无关紧要).
Deno 的在线文档中列出了所有已实现的浏览器 API.
Deno 管理依赖方式可能是它与 Node.js 的最大不同之处.
Node.js 使用 npm 或 yarn 之类的包管理器将第三方包从 npm 注册表下载到 node_modules 目录和 package.json 文件以跟踪项目的依赖关系。Deno 摒弃了这些机制,转而采用更加以浏览器为中心的方式来使用第三方包:URLs.
这里有一个使用 Deno web 应用程序框架 Oka 来创建基础 web server 的示例:
import { Application } from "https://deno.land/x/oak/mod.ts"; const app = new Application(); app.use((ctx) => { ctx.response.body = "Hello Deno!"; }); app.addEventListener("listen", ({ hostname, port, secure }) => { console.log(`Listening on: http://localhost:${port}`); }); await app.listen({ port: 8000 });
Deno 使用 ES 模块,与 Web 浏览器中使用的模块系统相同。只要引用的脚本(模块)导出方法或其它值,就可以从绝对路径或相对路径导入模块。值得注意的是,文件扩展名必须始终存在,无论您是从绝对路径还是相对路径导入.
虽然您可以从任何 URL 导入模块,但许多专门为 Deno 构建的第三方模块都通过 **deno.land/x** 进行缓存。每次发布模块的新版本时,它都会自动缓存在该位置并使其不可变,以便模块的特定版本内容保持不变.
假设您运行上一个片段中的代码。在这种情况下,它将下载模块及其所有依赖项并将它们缓存在本地 DENO_DIR 环境变量指定的目录中(默认应为 $HOME/.cache/deno)。下次程序运行时,将不会再次下载,因为所有依赖项都已缓存在本地。这类似于 Go 模块系统的工作方式.
$ deno run --allow-net index.ts Download https://deno.land/x/oak/mod.ts Warning Implicitly using latest version (v9.0.1) for https://deno.land/x/oak/mod.ts Download https://deno.land/x/oak@v9.0.1/mod.ts
对于生产应用程序,Deno 创建者建议检查您的依赖性已进入代码版本控制系统,以确保持续可用(即时模块的源代码不可用,无论处于何原因)。将 DENO_DIR 环境变量指向项目中的本地目录(例如 vendor),您可以将其提交给 Git.
例如,下面的命令会将脚本的所有依赖项下载到项目中的 vendor 目录中。随后,您可以提交该文件夹以在您的生产服务器中一次将其全部拉下。您还需要将 DENO_DIR 变量设置为从服务器上的 vendor 目录中读取,而不是重新下载它们.
$ DENO_DIR=$PWD/vendor deno cache index.ts # Linux and macOS$ $env:DENO_DIR="$(get-location)\vendor"; deno cache index.ts # Windows PowerShell
Deno 还支持对依赖项进行版本控制,以确保可重现的构建。目前,我们已经从 https://deno.land/x/oak/mod.ts 导入了 Oak。这始终会下载最新版本,将来可能与您的程序不兼容。当你第一次下载模块时,它还会导致 Deno 产生警告:
Warning Implicitly using latest version (v9.0.1) for https://deno.land/x/oak/mod.ts
最佳实践是引用一个特定版本,如下所示:
import { Application } from 'https://deno.land/x/oak@v9.0.1/mod.ts';
如果您在代码库的许多文件中引用一个模块,升级它可能会变得乏味,因为您必须在许多地方更新 URL。为了规避这个问题,Deno 团队建议将您的外部依赖项导入到一个集中的 deps.ts 文件中,然后重新导出它们。这是一个 deps.ts 示例文件,它从 Oak 库中导出我们需要的内容.
export { Application, Router } from "https://deno.land/x/oak@v9.0.1/mod.ts";
然后在您的应用程序代码中,您可以按如下方式导入它们:
import { Application, Router } from "./deps.ts";
此时,更新一个模块变得很简单,只需将 deps.ts 文件中的 URL 更改为指向新版本即可.
Deno 提供了标准库(stdlib)旨在成为 Go 标准库的松散端口(译者注:这里原句为 “aims to be a loose port of Go's standard library”)。标准中包含的模块由 Deno 团队审核并随着每一次 Deno release 而更新。提供标准库的目的是让您立即创建有用的 Web 应用程序,而不需要任何第三方包(这是 Node.js 生态系统中的规范).
你可能会发现一些有帮助的第三方模块,示例如下:
这是一个示例(取自 Deno 官方文档)它取自 Deno 标准库中的 HTTP 模块用于创建一个基本的 Web Server.
import { listenAndServe } from "https://deno.land/std@0.109.0/http/server.ts"; const addr = ":8080"; const handler = (request: Request): Response => { let body = "Your user-agent is:\n\n"; body += request.headers.get("user-agent") || "Unknown"; return new Response(body, { status: 200 }); }; console.log(`HTTP webserver running. Access it at: http://localhost:8080/`); await listenAndServe(addr, handler);
通过以下命令开启这个服务:
$ deno run --allow-net index.ts HTTP webserver running. Access it at: http://localhost:8080/
在不同终端,通过以下命令访问这个正在运行的服务.
$ curl http://localhost:8080 Your user-agent is: curl/7.68.0
请注意,标准库中的模块当前标记为不稳定(如版本号所示)。这意味着您不应该仅仅依赖它们来进行严肃的生产应用程序.
不可否认 Node.js 成功的主要原因是可以在项目下载使用大量的 NPM 包。如果你正在考虑切换到 Deno,你也许想知道是否要放弃所有你知道且喜爱的 NPM 包.
最简单的答案是 “不”。如果某些 NPM 包依赖于 Node.js API,您可能无法在 Deno 中使用它们(特别是如果 Deno 的 Node.js 兼容层不支持特定 API),但许多 NPM 包可以通过 CDN 在 Deno 中使用,例如 esm.sh 和 skypack.dev。这两个 CDN 都将 NPM 包作为 ES 模块提供,即使包的作者没有专门针对 Deno 进行设计,也可以随后在 Deno 脚本中使用这些包.
这是一个在 Deno 脚本中从 Skypack 到入 NPM 包的示例:
import dayjs from "https://cdn.skypack.dev/dayjs@1.10.7"; console.log(`Today is: ${dayjs().format("MMMM DD, YYYY")}`);
$ deno run index.ts Today is: October 05, 2021
为确保 Deno 可以发现与包关联的类型,请确保在使用 Skypack CDN 时在包 URL 的末尾添加 ?dts后缀。这会使 Skypack 设置 X-TypeScript-Types 标头,以便 Deno 可以自动发现与包关联的类型。Esm.sh 默认包含此标头,但您可以通过在包 URL 末尾添加 ?no-check 后缀来选择退出.
import dayjs from "https://cdn.skypack.dev/dayjs@1.10.7?dts";
Deno CLI 附带了几个有价值的工具,可以提高开发人员的使用体验。与 Node.js 一样,它带有一个 REPL(交互式解析器),您可以使用 deno repl 访问它.
$ deno replDeno 1.14.2 exit using ctrl+d or close() > 2+2 4
它还有一个内置的文件观察器,可以与它的几个子命令一起使用。例如,您可以使用 --watch 标志将 deno run 配置为在文件更改后自动重建和重新启动程序。在 Node.js 中,这个功能一般是通过一些第三方包来实现的,比如 nodemon.
$ deno run --allow-net --watch index.ts HTTP webserver running. Access it at: http://localhost:8080/ Watcher File change detected! Restarting! HTTP webserver running. Access it at: http://localhost:8080/
使用 Deno 1.6,您可以通过 compile 子命令将脚本编译为不需要安装 Deno 的独立可执行文件(您可以在 Node.js 中使用 pkg 执行相同操作)。您还可以通过--target 标志为其他平台(交叉编译)生成可执行文件。编译脚本时,您必须指定其运行所需的权限.
$ deno compile --allow-net --output server index.ts $ ./serverHTTP webserver running. Access it at: http://localhost:8080/
请注意,通过此过程生成的二进制文件非常庞大。在我的测试中,deno compile 为一个简单的 “Hello world” 程序生成了一个 83MB 的二进制文件。然而,Deno 团队目前正在努力减少文件大小以使其更易于管理.
发布 Deno 程序的另一种方法是通过 bundle 子命令将其打包到单个 JavaScript 文件中。该文件包含程序的源代码及其所有依赖项,可以通过 deno run 执行,如下所示:
$ deno bundle index.ts index.bundle.js Check file:///home/ayo/dev/demo/deno/index.js Bundle file:///home/ayo/dev/demo/deno/index.js Emit "index.bundle.js" (7.39KB) $ deno run --allow-net index.bundle.js HTTP webserver running. Access it at: http://localhost:8080/
Deno 附带的另外两个很棒的工具是内置的 linter (deno lint) 和 formatter (deno fmt)。在 Node.js 生态系统中,linting 和格式化代码通常分别由 ESLint 和 Prettier 处理.
使用 Deno 时,您不再需要安装任何东西或编写配置文件来获取 JavaScript、TypeScript 和其他支持的文件格式的 linting 和格式化.
Deno 内置了对 JavaScript 和 TypeScript 代码的单元测试支持。当您运行 deno test 时,它会自动检测任何以 _test.ts 或 .test.ts 结尾的文件(也支持其他文件扩展名)并在其中执行任何定义的测试.
要编写您的第一个测试,请创建一个 index_test.ts 文件并使用以下代码填充它:
import { assertEquals } from "https://deno.land/std@0.109.0/testing/asserts.ts"; Deno.test("Multiply two numbers", () => { const ans = 2 * 2; assertEquals(ans, 4); });
Deno 提供了用于创建单元测试的 Deno.test 方法。它将测试的名称作为其第一个参数。它的第二个参数是测试运行时执行的函数.
还有第二种风格接受一个对象而不是两个参数。除了测试名称和功能之外,它还支持其他属性来配置测试是否应该运行或如何运行.
Deno.test({ name: "Multiply two numbers", fn() { const ans = 2 * 2; assertEquals(ans, 4); }, });
assertEquals() 方法来自标准库中的测试模块,它提供了一种轻松检查两个值是否相等的方法.
继续运行测试:
$ deno testtest Multiply two numbers ... ok (8ms) test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (37ms)
选择编程语言或环境的主要考虑因素之一是它与编辑器和 IDE 的集成。在 Deno 1.6 中,内置语言服务协议(deno lsp) 被添加到运行时以提供以下功能:
以及任何支持语言服务协议 (LSP) 的编辑器的其他语言智能。你可以在 Deno 的在线文档中了解有关在编辑器中设置 Deno 支持的更多信息.
在本文中,我们考虑了 Deno 运行时的许多方面,以及它是对 Node.js 的升级的方式.
关于 Deno 及其生态系统还有很多话要说,但对于考虑将 Deno 用于新项目的 Node.js 开发人员来说,这应该是一个有用的介绍。Deno 第三方软件包的可用性较低是它明显不足的一个方面,因为它在现实世界中由于年龄太小而没有像 Node.js 那样经过实战测试(Deno 1.0 于 2020 年 5 月发布).
比较 Node.js 和 Deno 之间的性能可以发现,在大多数情况下,它们在同一个范围内,尽管在少数情况下 Node.js 表现出更出色的性能。随着 Deno 变得更加成熟,所测得的差异势必会有所改善.
在选择 Node.js 和 Deno 时,同样重要的是要记住,Deno 提供的一些好处也可以在第三方包的帮助下在 Node.js 中使用。因此,如果您对 Deno 只有一两点欣赏,那么您很可能在 Node.js 中也可获得类似的结果,尽管不是那么无缝.
译者:五月君 。
作者:ayooluwa-isaiah 。
https://blog.appsignal.com/2022/02/09/an-introduction-to-deno-is-it-better-than-nodejs.html 。
原文地址:https://mp.weixin.qq.com/s/FUIaBBv5-lc6OZcFDbc9Cg 。
最后此篇关于Deno :它比 Node.js 更好吗?的文章就讲到这里了,如果你想了解更多关于Deno :它比 Node.js 更好吗?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我用运行 Node node --debug app OR node --debug-brk app 它有反应 debugger listening on port 5858 Express serv
这个问题在这里已经有了答案: What is the difference between (int *i) and (int* i) in context of both C and C++? [
我有一个应用程序,它通过消息队列将数据库写入命令分派(dispatch)给工作人员(数量非常大),因此无法保证它们的接收顺序。 我有两个 Node ,例如“Account”和“Media”。在此假设的
有没有办法在调用 ts-node 时将选项传递给 Node ?我正在尝试在 Node 中使用一个实验性功能,如果它能与 ts-node 一起使用,那就太好了。 这就是我目前正在做的事情: ts-nod
我有一个容器化的Node应用程序,它在DigitalOcean服务器上运行。当我更新服务器上的应用程序时,该应用程序必须关闭一小段时间。为了能够更新应用程序并避免停机,我目前正在阅读零停机时间部署/蓝
我正在编写一个 Node.js 应用程序。我正在使用 request 和 Cheerio 加载一组 URL 并获取该网站的大量信息,现在假设我想要获取的只是标题: var urls = {"url_1
如果不弹出以下错误,我无法安装任何 Node.js 模块。错误代码引用package.json文件。如果知道为什么会发生这种情况,我们将不胜感激。 最佳答案 这些不是错误,它们只是警告。一切都应该如此
如果我运行(从我的项目目录中): supervisor javascripts/index.js 我得到:/usr/bin/env: Node :没有这样的文件或目录 如果我运行: node java
我已遵循使用 Node-Inspector 的所有步骤 但是当我打开应用程序时,我在控制台上看不到任何脚本或日志。 我的应用程序在端口 4000 上运行。我认为唯一可能发生冲突的是端口 8080 上的
我在android中使用rxjava2,有时会遇到这样的问题: Observable.fromArray( // maybe a list about photo url in SD
我目前正在使用 Node 光纤来编写同步服务器端代码。我主要通过 try-catch block 进行错误处理,但外部库或其他小部分异步代码中总是有可能发生错误。我正在考虑使用新的域功能来尝试将这些错
看起来node-debug是node-inspector周围的一个shell?分别什么时候应该使用? 最佳答案 如果您安装node-debug,您只能访问node-debug命令。 如果您安装node
我目前正在代理后面工作,该代理不允许我执行此命令的 HTTP GET 请求阶段: Node node-sass/scripts/build.js 请求阶段: gyp http GET https://
听说node js可以用在服务端。我以前用过jsp。 jsp页面内部的java代码对客户端是不可见的。如果 Node js 只是 javascript,那么它如何对客户端不可见? 最佳答案 首先,No
我正在为 Node native 插件从 node-waf 构建迁移到 node-gyp 构建系统。 node-gyp 说它支持多个目标版本,但我在使用 node-gyp 时找不到如何指定目标 Nod
给定一个 $node ,我正在尝试在以下两种输出该 $node 的方式之间做出决定。 要么 $output = theme('node', $node); 或 node_build_content($
如果package.json中的窗口A打开一个新窗口B,node-main如何访问它?这是我的代码: package.json { "main": "index.html",
我试图在我的 xml 中的特定节点 ( ) 之前插入一个注释节点。这是它的方法: function test(xmlResponse) { var parser = new DOMParse
我正在尝试做npm install wrtc使用 Node 版本 16.14.0 但这还没有完成。它在给npm error code 1所以我试图将 Node 版本更改为以前的 lts 14.19.0
当我在 Visual Studio 中运行 Node.js 应用程序时,我收到以下消息:DeprecationWarning: 'node --debug' 和 'node --debug-brk'
我是一名优秀的程序员,十分优秀!