我每周都会探索新的项目,很少有像Deno这样引起我注意的项目。

什么是Deno?
如果你熟悉Node.js,流行的服务器端JavaScript生态系统,那么Deno就像Node。除了在许多方面有深刻的改进。
让我们从快速列出我最喜欢Deno的功能开始。
- 它是基于JavaScript语言的现代特性的
- 它有一个广泛的标准库
- 它的核心是TypeScript,这在很多方面都带来了巨大的优势,包括一流的TypeScript支持(你不需要单独编译TypeScript,Deno会自动完成)。
- 它拥抱ES模块
- 它没有包管理器
- 它有一个一流的
await - 它作为一个内置的测试工具
- 它的目标是尽可能地与浏览器兼容,例如通过提供一个内置的
fetch和全局window对象。
我们将在本指南中探讨所有这些功能。
在你使用Deno并学会欣赏它的特性后,Node.js将看起来像个老东西。
特别是因为Node.js的API是基于回调的,因为它是在承诺和async/await之前写的。在Node中没有任何改变,因为这样的改变将是巨大的,所以我们只能使用回调或承诺API调用。
Node.js非常棒,并将继续成为JavaScript世界中事实上的标准。但我认为我们会逐渐看到Deno被更多人采用,因为它有一流的TypeScript支持和现代标准库。
Deno可以负担得起所有用现代技术编写的东西,因为没有后向兼容性需要维护。当然,不能保证十年后Deno也会发生同样的情况,会出现新的技术,但这就是目前的现实。
为什么是Deno?为什么是现在?
Deno几乎是2年前由Node.js的原创者Ryan Dahl在JSConf EU宣布的。观看YouTube上的演讲视频,它非常有趣,如果你参与Node.js和一般的JavaScript,它是必须要看的。
每个项目经理都必须做出决定。Ryan对Node的一些早期决定感到后悔。另外,技术也在发展,今天的JavaScript与2009年Node开始时的情况完全不同。想想现代ES6/2016/2017的功能,等等。
所以他开始了一个新的项目,以创建某种第二波的JavaScript驱动的服务器端应用程序。
我之所以现在而不是当年写这篇指南,是因为技术需要大量时间来成熟。而我们终于达到了Deno 1.0(1.0应该在2020年5月13日发布),Deno的第一个版本正式宣布稳定。
这似乎只是一个数字,但1.0意味着在Deno 2.0之前不会有重大的突破性变化,当你潜心研究一项新技术时,这是一个大问题--你不希望学习一些东西,然后让它变化太快。
你应该学习Deno吗?
这是个大问题。
学习像Deno这样的新东西是一个很大的努力。我的建议是,如果你现在开始学习服务器端JS,而你还不知道Node,也从未写过任何TypeScript,我会从Node开始。
从来没有人因为选择Node.js而被解雇(套用一句常见的话)。
但是,如果你喜欢TypeScript,在你的项目中不依赖大量的npm包,而且你想在任何地方使用await ,嘿,Deno可能是你要找的东西。
它能取代Node.js吗?
不会。Node.js是一个巨大的、成熟的、令人难以置信的、得到良好支持的技术,它将保持几十年。
一流的TypeScript支持
Deno是用Rust和TypeScript编写的,这两种语言今天确实在快速发展。
特别是用TypeScript编写意味着我们可以得到TypeScript的很多好处,即使我们可能选择用普通的JavaScript编写代码。
而且用Deno运行TypeScript代码不需要编译步骤--Deno会自动为你编译。
你并不是被迫用TypeScript编写,但Deno的核心是用TypeScript编写的,这一点非常重要。
首先,越来越大比例的JavaScript程序员喜欢TypeScript。
其次,你使用的工具可以推断出许多用TypeScript编写的软件的信息,比如Deno。
这意味着,当我们在VS Code中编码时,例如,它显然与TypeScript紧密结合,因为两者都是在MicroSoft开发的,我们可以在写代码时获得类型检查等好处,以及高级IntelliSense功能。换句话说,编辑器可以以一种非常有用的方式帮助我们。
与Node.js的相似和不同之处
由于Deno基本上是一个Node.js的替代品,所以直接比较两者是很有用的。
相似性。
- 两者都是基于V8 Chromium引擎开发的
- 两者都很适合用JavaScript开发服务器端
不同之处。
- Node是用C++和JavaScript编写的。Deno是用Rust和TypeScript编写的。
- Node有一个官方的软件包管理器,叫做
npm。Deno没有,而是让你从URL导入任何ES模块。 - Node使用CommonJS的语法来导入包管理器。Deno使用ES模块,是官方的方式。
- Deno在其所有的API和标准库中使用现代ECMAScript特性,而Node.js使用基于回调的标准库,并且没有计划升级它。
- Deno通过权限提供了一个沙盒安全层。一个程序只能访问由用户设置为旗帜的可执行文件的权限。一个Node.js程序可以访问用户可以访问的任何东西
- 长期以来,Deno一直设想将一个程序编译成一个可执行文件,你可以在没有外部依赖的情况下运行,就像Go一样,但它仍然不是一个东西。这将是一个游戏规则的改变。
没有软件包管理器
没有软件包管理器,必须依靠URL来托管和导入软件包,这有利有弊。我非常喜欢它的优点:它非常灵活,我们可以创建包,而不需要在像npm这样的存储库中发布它们。
我认为某种包管理器会出现,但目前还没有正式的东西出来。
Deno网站为第三方软件包提供代码托管(从而通过URL发布):https://deno.land/x/
安装Deno
说得够多了!让我们来安装Deno。
最简单的方法是使用Homebrew。

一旦这样做了,你就可以访问deno 命令了。下面是你使用deno --help ,可以得到的帮助。
flavio@mbp~> deno --help
deno 0.42.0
A secure JavaScript and TypeScript runtime
Docs: https://deno.land/std/manual.md
Modules: https://deno.land/std/ https://deno.land/x/
Bugs: https://github.com/denoland/deno/issues
To start the REPL, supply no arguments:
deno
To execute a script:
deno run https://deno.land/std/examples/welcome.ts
deno https://deno.land/std/examples/welcome.ts
To evaluate code in the shell:
deno eval "console.log(30933 + 404)"
Run 'deno help run' for 'run'-specific flags.
USAGE:
deno [OPTIONS] [SUBCOMMAND]
OPTIONS:
-h, --help
Prints help information
-L, --log-level <log-level>
Set log level [possible values: debug, info]
-q, --quiet
Suppress diagnostic output
By default, subcommands print human-readable diagnostic messages to stderr.
If the flag is set, restrict these messages to errors.
-V, --version
Prints version information
SUBCOMMANDS:
bundle Bundle module and dependencies into single file
cache Cache the dependencies
completions Generate shell completions
doc Show documentation for a module
eval Eval script
fmt Format source files
help Prints this message or the help of the given subcommand(s)
info Show info about cache or info related to source file
install Install script as an executable
repl Read Eval Print Loop
run Run a program given a filename or url to the module
test Run tests
types Print runtime TypeScript declarations
upgrade Upgrade deno executable to newest version
ENVIRONMENT VARIABLES:
DENO_DIR Set deno's base directory (defaults to $HOME/.deno)
DENO_INSTALL_ROOT Set deno install's output directory
(defaults to $HOME/.deno/bin)
NO_COLOR Set to disable color
HTTP_PROXY Proxy address for HTTP requests
(module downloads, fetch)
HTTPS_PROXY Same but for HTTPS
Deno命令
注意帮助中的SUBCOMMANDS 部分,它列出了我们可以运行的所有命令。我们有哪些子命令?
bundle将一个项目的模块和依赖关系捆绑到一个文件中cache缓存依赖项completions生成shell完成度doc显示一个模块的文档eval评估一段代码,比如说。deno eval "console.log(1 + 2)"fmt一个内置的代码格式化器(类似于Go中的 )。gofmthelp打印这个信息或给定的子命令的帮助info显示关于缓存的信息或与源文件有关的信息install将脚本安装为可执行文件repl读取-评估-打印-循环(默认)。run运行一个给定文件名或模块网址的程序test运行测试types打印运行时TypeScript的声明upgrade升级 到最新的版本deno
你可以运行deno <subcommand> help ,以获得该命令的特定附加文档,例如deno run --help 。
正如帮助中所说,我们可以使用这个命令来启动一个REPL(Read-Execute-Print-Loop),使用deno ,而不需要任何其他选项。

这与运行deno repl 是一样的。
你使用这个命令的一个更常见的方式是执行一个包含在TypeScript文件中的Deno应用。
你可以运行TypeScript (.ts) 文件,或者JavaScript (.js) 文件。
如果你不熟悉TypeScript,不用担心:Deno是用TypeScript编写的,但你可以用JavaScript编写你的 "客户端 "应用程序。
如果你愿意的话,我的TypeScript教程将帮助你快速掌握TypeScript。
你的第一个Deno应用程序
让我们第一次运行一个Deno应用程序。
我觉得相当神奇的是,你甚至不需要写一行字--你可以从任何URL运行一个命令。
Deno下载程序,编译它,然后运行它。

当然,从互联网上运行任意代码的做法一般不值得推荐。在这种情况下,我们是从Deno的官方网站上运行它,另外Deno有一个沙盒,可以防止程序做任何你不想允许的事情。稍后会有更多这方面的内容。
这个程序非常简单,只是一个console.log() 的调用。
console.log('Welcome to Deno 🦕')
如果你用浏览器打开deno.land/std/example…URL,你会看到这个页面。

很奇怪,对吗?你可能会期待一个TypeScript文件,而我们却有一个网页。原因是Deno网站的Web服务器知道你在使用浏览器,并为你提供一个更友好的页面。
例如,使用wget 下载同一个UR,它请求的是text/plain ,而不是text/html 。

如果你想再次运行这个程序,它现在已经被Deno缓存了,它不需要再次下载它。

你可以用--reload 标志强制重新加载原始源代码。

deno run 有很多不同的选项,在 中没有列出。相反,你需要运行 来显示它们。deno --help deno run --help
flavio@mbp~> deno run --help
deno-run
Run a program given a filename or url to the module.
By default all programs are run in sandbox without access to disk, network or
ability to spawn subprocesses.
deno run https://deno.land/std/examples/welcome.ts
Grant all permissions:
deno run -A https://deno.land/std/http/file_server.ts
Grant permission to read from disk and listen to network:
deno run --allow-read --allow-net https://deno.land/std/http/file_server.ts
Grant permission to read whitelisted files from disk:
deno run --allow-read=/etc https://deno.land/std/http/file_server.ts
USAGE:
deno run [OPTIONS] <SCRIPT_ARG>...
OPTIONS:
-A, --allow-all
Allow all permissions
--allow-env
Allow environment access
--allow-hrtime
Allow high resolution time measurement
--allow-net=<allow-net>
Allow network access
--allow-plugin
Allow loading plugins
--allow-read=<allow-read>
Allow file system read access
--allow-run
Allow running subprocesses
--allow-write=<allow-write>
Allow file system write access
--cached-only
Require that remote dependencies are already cached
--cert <FILE>
Load certificate authority from PEM encoded file
-c, --config <FILE>
Load tsconfig.json configuration file
-h, --help
Prints help information
--importmap <FILE>
UNSTABLE:
Load import map file
Docs: https://deno.land/std/manual.md#import-maps
Specification: https://wicg.github.io/import-maps/
Examples: https://github.com/WICG/import-maps#the-import-map
--inspect=<HOST:PORT>
activate inspector on host:port (default: 127.0.0.1:9229)
--inspect-brk=<HOST:PORT>
activate inspector on host:port and break at start of user script
--lock <FILE>
Check the specified lock file
--lock-write
Write lock file. Use with --lock.
-L, --log-level <log-level>
Set log level [possible values: debug, info]
--no-remote
Do not resolve remote modules
-q, --quiet
Suppress diagnostic output
By default, subcommands print human-readable diagnostic messages to stderr.
If the flag is set, restrict these messages to errors.
-r, --reload=<CACHE_BLACKLIST>
Reload source code cache (recompile TypeScript)
--reload
Reload everything
--reload=https://deno.land/std
Reload only standard modules
--reload=https://deno.land/std/fs/utils.ts,https://deno.land/std/fmt/colors.ts
Reloads specific modules
--seed <NUMBER>
Seed Math.random()
--unstable
Enable unstable APIs
--v8-flags=<v8-flags>
Set V8 command line options. For help: --v8-flags=--help
ARGS:
<SCRIPT_ARG>...
script args
Deno代码示例
除了我们上面运行的那个,Deno网站还提供了一些其他的例子,你可以去看看:https://deno.land/std/examples/。
在写这篇文章的时候,我们可以发现。
cat.ts打印作为参数提供的文件列表中的内容catj.ts打印内容和作为参数提供的文件列表chat/一个聊天的实现colors.ts一个例子curl.tscurl的一个简单实现,打印作为参数指定的URL的内容echo_server.ts一个TCP回声服务器gist.ts一个向gist.github.com发布文件的程序test.ts一个测试套件的样本welcome.ts一个简单的console.log语句(上面我们运行的第一个程序)。xeval.ts允许你对收到的任何一行标准输入运行任何TypeScript代码。曾经被称为deno xeval,但后来从官方命令中删除。
你的第一个Deno应用程序(真实的)
让我们来写一些代码。
你使用deno run https://deno.land/std/examples/welcome.ts 运行的第一个Deno应用是别人写的应用,所以你没有看到任何关于Deno代码的样子。
我们将从Deno官方网站上列出的默认示例应用程序开始。
import { serve } from 'https://deno.land/std/http/server.ts'
const s = serve({ port: 8000 })
console.log('http://localhost:8000/')
for await (const req of s) {
req.respond({ body: 'Hello World\n' })
}
这段代码从http/server 模块中导入了serve 函数。看到了吗?我们不需要先安装它,而且它也不像Node模块那样存储在你的本地机器上。这就是为什么Deno的安装如此之快的原因之一。
从https://deno.land/std/http/server.ts ,导入的是模块的最新版本。你可以使用@VERSION ,像这样导入一个特定的版本。
import { serve } from 'https://deno.land/std@v0.42.0/http/server.ts'
在这个文件中,serve 函数是这样定义的。
/**
* Create a HTTP server
*
* import { serve } from "https://deno.land/std/http/server.ts";
* const body = "Hello World\n";
* const s = serve({ port: 8000 });
* for await (const req of s) {
* req.respond({ body });
* }
*/
export function serve(addr: string | HTTPOptions): Server {
if (typeof addr === 'string') {
const [hostname, port] = addr.split(':')
addr = { hostname, port: Number(port) }
}
const listener = listen(addr)
return new Server(listener)
}
我们继续实例化一个服务器,调用serve() 函数,传递一个带有port 属性的对象。
然后我们运行这个循环来响应来自服务器的每个请求。
for await (const req of s) {
req.respond({ body: 'Hello World\n' })
}
注意,我们使用了await 关键字,而不需要把它包装成一个async 函数,因为Deno实现了顶层的await。
让我们在本地运行这个程序。我假设你使用VS Code,但你可以使用任何你喜欢的编辑器。
我建议安装来自justjavac 的Deno扩展(在我尝试的时候还有一个同名的扩展,但是已经废弃了--将来可能会消失)。

该扩展将为VS Code提供一些实用工具和好东西,以帮助你编写你的应用程序。
现在在一个文件夹中创建一个app.ts 文件并粘贴上述代码。

现在用deno run app.ts 来运行它。

Deno会下载它所需要的所有依赖项,首先下载我们导入的那个文件。
deno.land/std/http/se…文件本身就有几个依赖项。
import { encode } from '../encoding/utf8.ts'
import { BufReader, BufWriter } from '../io/bufio.ts'
import { assert } from '../testing/asserts.ts'
import { deferred, Deferred, MuxAsyncIterator } from '../async/mod.ts'
import {
bodyReader,
chunkedBodyReader,
emptyReader,
writeResponse,
readRequest,
} from './_io.ts'
import Listener = Deno.Listener
import Conn = Deno.Conn
import Reader = Deno.Reader
而这些都是自动导入的。
但在最后,我们有一个问题。

发生了什么?我们有一个权限拒绝的问题。
让我们来谈谈沙盒。
Deno沙盒
我之前提到,Deno有一个沙盒,可以防止程序做任何你不想允许的事情。
这意味着什么呢?
Ryan在Deno介绍的谈话中提到的一件事是,有时你想在Web浏览器之外运行一个JavaScript程序,但又不允许它在你的系统上访问任何它想访问的东西。或者使用网络与外部世界交谈。
没有什么能阻止一个Node.js应用程序获取你的SSH密钥或你系统上的任何其他东西并将其发送到服务器上。这就是为什么我们通常只从受信任的来源安装Node包,但如果我们使用的某个项目被黑了,反过来其他人也被黑了,我们怎么能知道?
Deno试图复制与浏览器实现的相同的权限模型。除非你明确允许,否则在浏览器中运行的任何JavaScript都不能在你的系统中做不正当的事情。
回到Deno,如果一个程序想要访问网络,就像前面的例子一样,那么我们需要给它许可。
我们可以通过在运行命令时传递一个标志来做到这一点,在这种情况下,--allow-net 。
deno run --allow-net app.ts

该程序现在正在8000端口上运行一个HTTP服务器。

其他标志允许Deno解锁其他功能。
--allow-env允许环境访问--allow-hrtime允许高分辨率的时间测量--allow-net=<allow-net>允许网络访问--allow-plugin允许加载插件--allow-read=<allow-read>允许文件系统读取访问--allow-run允许运行子进程--allow-write=<allow-write>允许文件系统写访问--allow-all允许所有权限(与 相同)-A
net,read 和write 的权限可以是细化的。例如,你可以允许从一个特定的文件夹中阅读,使用--allow-read=/dev
格式化代码
我非常喜欢Go的其中一点是Go编译器附带的gofmt 命令。所有的Go代码看起来都一样。每个人都使用gofmt 。
JavaScript程序员习惯于运行Prettier,而deno fmt 实际上是在幕后运行的。
假设你有一个格式不好的文件,像这样。

你运行deno fmt app.ts ,它就会自动格式化,同时在缺少的地方加上分号。

标准库
尽管这个项目还很年轻,但Deno的标准库非常广泛。
它包括。
archivetar归档实用程序async异步实用程序bytes处理字节片的辅助工具datetime日期/时间解析encoding对各种格式进行编码/解码flags解析命令行标志fmt格式化和打印fs文件系统APIhash密码库httpHTTP服务器ioI/O库log日志实用程序mime对多部分数据的支持nodeNode.js兼容层path路径操作wswebsockets
另一个Deno的例子
让我们看看另一个Deno应用程序的例子,来自Deno的例子。 cat:
const filenames = Deno.args
for (const filename of filenames) {
const file = await Deno.open(filename)
await Deno.copy(file, Deno.stdout)
file.close()
}
这就把Deno.args 的内容分配给了filenames 变量,这个变量包含了发给命令的所有参数。
我们遍历它们,对于每个参数,我们使用Deno.open() 来打开文件,我们使用Deno.copy() 来打印文件的内容到Deno.stdout 。最后我们关闭该文件。
如果你用以下方式运行这个
deno run https://deno.land/std/examples/cat.ts
程序被下载和编译,但由于我们没有指定任何参数,所以什么也没有发生。
现在试试
deno run https://deno.land/std/examples/cat.ts app.ts
假设你在同一个文件夹里有前一个项目的app.ts 。
你会得到一个权限错误。

因为Deno默认不允许对文件系统的访问。使用--allow-read=./ ,授予对当前文件夹的访问权。
deno run --allow-read=./ https://deno.land/std/examples/cat.ts app.ts

Deno有一个Express/Hapi/Koa/*吗?
是的,肯定有。请看像这样的项目
例子:使用Oak建立一个REST API
我想做一个简单的例子,说明如何使用Oak构建一个REST API。Oak很有趣,因为它的灵感来自于Koa,即流行的Node.js中间件,由于这个原因,如果你以前使用过,就会觉得非常熟悉。
我们要建立的API非常简单。
我们的服务器将在内存中存储一个带有姓名和年龄的狗的列表。
我们想。
- 增加新的狗
- 列出狗
- 获得关于某只狗的详细信息
- 从列表中删除一只狗
- 更新一只狗的年龄
我们将在TypeScript中做到这一点,但没有什么能阻止你在JavaScript中编写API--你只需删除类型。
创建一个app.ts 文件。
让我们先从Oak中导入Application 和Router 对象。
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
然后我们得到环境变量PORT和HOST。
const env = Deno.env.toObject()
const PORT = env.PORT || 4000
const HOST = env.HOST || '127.0.0.1'
默认情况下,我们的应用程序将在localhost:4000上运行。
现在我们创建Oak应用程序并启动它。
const router = new Router()
const app = new Application()
app.use(router.routes())
app.use(router.allowedMethods())
console.log(`Listening on port ${PORT}...`)
await app.listen(`${HOST}:${PORT}`)
现在,应用程序的编译工作应该很顺利。
运行
deno run --allow-env --allow-net app.ts
Deno将下载依赖项。

然后在4000端口上监听。
接下来你运行这个命令时,Deno会跳过安装部分,因为这些包已经被缓存了。

在文件的顶部,让我们定义一个狗的接口,然后我们声明一个狗对象的初始dogs 阵列。
interface Dog {
name: string
age: number
}
let dogs: Array<Dog> = [
{
name: 'Roger',
age: 8,
},
{
name: 'Syd',
age: 7,
},
]
现在让我们真正实现API。
我们已经准备好了一切。在你创建了路由器之后,让我们添加一些函数,当这些端点之一被击中时,这些函数将被调用。
const router = new Router()
router
.get('/dogs', getDogs)
.get('/dogs/:name', getDog)
.post('/dogs', addDog)
.put('/dogs/:name', updateDog)
.delete('/dogs/:name', removeDog)
看到了吗?我们定义
GET /dogsGET /dogs/:namePOST /dogsPUT /dogs/:nameDELETE /dogs/:name
让我们逐一实现这些功能。
从GET /dogs 开始,它返回所有狗的列表。
export const getDogs = ({ response }: { response: any }) => {
response.body = dogs
}

接下来,我们可以通过名字来检索一只狗。
export const getDog = ({
params,
response,
}: {
params: {
name: string
}
response: any
}) => {
const dog = dogs.filter((dog) => dog.name === params.name)
if (dog.length) {
response.status = 200
response.body = dog[0]
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}

下面是我们如何添加一只新的狗。
export const addDog = async ({
request,
response,
}: {
request: any
response: any
}) => {
const body = await request.body()
const dog: Dog = body.value
dogs.push(dog)
response.body = { msg: 'OK' }
response.status = 200
}

注意,我现在用const body = await request.body() 来获取正文的内容,因为name 和age 的值是以JSON形式传递的。
这里是我们如何更新一只狗的年龄。
export const updateDog = async ({
params,
request,
response,
}: {
params: {
name: string
}
request: any
response: any
}) => {
const temp = dogs.filter((existingDog) => existingDog.name === params.name)
const body = await request.body()
const { age }: { age: number } = body.value
if (temp.length) {
temp[0].age = age
response.status = 200
response.body = { msg: 'OK' }
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}

以及这里是我们如何从我们的列表中删除一只狗。
export const removeDog = ({
params,
response,
}: {
params: {
name: string
}
response: any
}) => {
const lengthBefore = dogs.length
dogs = dogs.filter((dog) => dog.name !== params.name)
if (dogs.length === lengthBefore) {
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
return
}
response.body = { msg: 'OK' }
response.status = 200
}

这里是完整的示例代码。
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
const env = Deno.env.toObject()
const PORT = env.PORT || 4000
const HOST = env.HOST || '127.0.0.1'
interface Dog {
name: string
age: number
}
let dogs: Array<Dog> = [
{
name: 'Roger',
age: 8,
},
{
name: 'Syd',
age: 7,
},
]
export const getDogs = ({ response }: { response: any }) => {
response.body = dogs
}
export const getDog = ({
params,
response,
}: {
params: {
name: string
}
response: any
}) => {
const dog = dogs.filter((dog) => dog.name === params.name)
if (dog.length) {
response.status = 200
response.body = dog[0]
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
export const addDog = async ({
request,
response,
}: {
request: any
response: any
}) => {
const body = await request.body()
const { name, age }: { name: string; age: number } = body.value
dogs.push({
name: name,
age: age,
})
response.body = { msg: 'OK' }
response.status = 200
}
export const updateDog = async ({
params,
request,
response,
}: {
params: {
name: string
}
request: any
response: any
}) => {
const temp = dogs.filter((existingDog) => existingDog.name === params.name)
const body = await request.body()
const { age }: { age: number } = body.value
if (temp.length) {
temp[0].age = age
response.status = 200
response.body = { msg: 'OK' }
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
export const removeDog = ({
params,
response,
}: {
params: {
name: string
}
response: any
}) => {
const lengthBefore = dogs.length
dogs = dogs.filter((dog) => dog.name !== params.name)
if (dogs.length === lengthBefore) {
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
return
}
response.body = { msg: 'OK' }
response.status = 200
}
const router = new Router()
router
.get('/dogs', getDogs)
.get('/dogs/:name', getDog)
.post('/dogs', addDog)
.put('/dogs/:name', updateDog)
.delete('/dogs/:name', removeDog)
const app = new Application()
app.use(router.routes())
app.use(router.allowedMethods())
console.log(`Listening on port ${PORT}...`)
await app.listen(`${HOST}:${PORT}`)
了解更多
Deno的官方网站是deno.land
API文档可在doc.deno.land和deno.land/typedoc/ind…。
awesome-denogithub.com/denolib/awe…
还有一些随机的小插曲
- Deno提供了一个内置的
fetch实现,与浏览器中的实现相匹配。 - Deno有一个与Node.js stdlib的兼容层,正在进行中。