专栏首页全栈修仙之路了不起的 Deno 入门篇

了不起的 Deno 入门篇

一、Deno 简介

Deno 是一个 JavaScript/TypeScript 的运行时,默认使用安全环境执行代码,有着卓越的开发体验。Deno 含有以下功能亮点:

  • 默认安全。外部代码没有文件系统、网络、环境的访问权限,除非显式开启。
  • 支持开箱即用的 TypeScript 的环境。
  • 只分发一个独立的可执行文件(deno)。
  • 有着内建的工具箱,比如一个依赖信息查看器(deno info)和一个代码格式化工具(deno fmt)。
  • 有一组经过审计的 标准模块,保证能在 Deno 上工作。
  • 脚本代码能被打包为一个单独的 JavaScript 文件。

Deno 是一个跨平台的运行时,即基于 Google V8 引擎的运行时环境,该运行时环境是使用 Rust 语言开发的,并使用 Tokio 库来构建事件循环系统。Deno 建立在 V8、Rust 和 Tokio 的基础上,它的架构如下:

(图片来源:https://deno.land/manual/contributing/architecture)

1.1 Rust

Rust 是由 Mozilla 主导开发的通用、编译型编程语言。设计准则为 “安全、并发、实用”,支持函数式、并发式、过程式以及面向对象的编程风格。Deno 使用 Rust 语言来封装 V8 引擎,通过 libdeno 绑定,我们就可以在 JavaScript 中调用隔离的功能。

1.2 Tokio

Tokio 是 Rust 编程语言的异步运行时,提供异步事件驱动平台,构建快速,可靠和轻量级网络应用。利用 Rust 的所有权和并发模型确保线程安全。Tokio 构建于 Rust 之上,提供极快的性能,使其成为高性能服务器应用程序的理想选择。在 Deno 中 Tokio 用于并行执行所有的异步 IO 任务。

1.3 V8

V8 是一个由 Google 开发的开源 JavaScript 引擎,用于 Google Chrome 及 Chromium 中。V8 在运行之前将JavaScript 编译成了机器代码,而非字节码或是解释执行它,以此提升性能。更进一步,使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript 程序与 V8 引擎的速度媲美二进制编译。在 Deno 中,V8 引擎用于执行 JavaScript 代码。

二、安装 Deno

Deno 能够在 macOS、Linux 和 Windows 上运行。Deno 是一个单独的可执行文件,它没有额外的依赖。你可以通过以下方式来安装它:

  • 使用 Shell (macOS 和 Linux):
curl -fsSL https://deno.land/x/install/install.sh | sh
  • 使用 PowerShell (Windows):
iwr https://deno.land/x/install/install.ps1 -useb | iex
  • 使用 Scoop (Windows):
scoop install deno
choco install deno
brew install deno
  • 使用 Cargo (Windows,macOS,Linux):
cargo install deno

Deno 也可以手动安装,只需从 github.com/denoland/deno/releases 下载一个 zip 文件。它仅包含一个单独的可执行文件。在 macOS 和 Linux 上,你需要为它设置执行权限。当你成功安装之后,可以通过执行 deno --version 命令来查看已安装的 Deno 版本:

$ deno --version
deno 1.0.0
v8 8.4.300
typescript 3.9.2

2.1 deno_install

在安装过程中,如果遇到问题的话,大家可以试试 justjavac(迷渡)大神提供的安装脚本 —— deno_install。该脚本通过单行命令将 Deno 安装到系统中(国内加速)。

2.1.1 安装最新版

使用 Shell:

curl -fsSL https://x.deno.js.cn/install.sh | sh

使用 PowerShell:

iwr https://x.deno.js.cn/install.ps1 -useb -outf install.ps1; .\install.ps1
# iwr https://x.deno.js.cn/install.ps1 -useb | iex
2.1.2 安装某个特定版本

使用 Shell:

curl -fsSL https://x.deno.js.cn/install.sh | sh -s v0.41.0

使用 PowerShell:

iwr https://x.deno.js.cn/install.ps1 -useb -outf install.ps1; .\install.ps1 v0.41.0

更多详细的信息可以浏览 x.deno.js.cn 站点。

2.2 deno-cli

deno-cli 命令行界面提供了一组集成功能,让你可以沉浸在 Deno 的专有开发环境中。以下是 Deno 1.0.0 版本支持的所有子命令:

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 given version

2.3 REPL

在命令中输入 deno 命令,你就会启动一个 REPL(Read-Execute-Print-Loop):

$ deno
Deno 1.0.0
exit using ctrl+d or close()
> 1 + 2
3
> const name = "semlinker";
undefined
> console.log(name);
semlinker
undefined

2.4 VSCode Deno extension

相信很多小伙伴都在使用 VSCode IDE 进行前端开发,对于学习和开发 Deno 的开发者来说,一定不能错过 justjavac(迷渡) 大神开发的 Visual Studio Code Deno extension

2.4.1 未安装 Deno extension

如果我们写 from "./hello.ts" 这样的语句,在 VSCode 中将会出现波浪号的错误信息。因为默认情况下,TypeScript 项目不需要添加 .ts 扩展名。

ts(2691): An import path cannot end with a ‘.ts’ extension. Consider importing ‘./hello’ instead.

Deno 允许从 URL 中导入模块,但是 TypeScript 并不支持从 URL 中导入模块。

ts(2307): Cannot find module ‘https://deno.land/x/std/log/mod'.

2.4.2 已安装 Deno extension

Deno 将远程导入(imports)缓存在 DENO_DIR 环境变量指定的特殊目录中。如果未指定 DENO_DIR,则默认为系统的缓存目录。

该插件可以将远程导入(remote imports)解析为本地路径。

(本章节图片来源:https://marketplace.visualstudio.com/items?itemName=justjavac.vscode-deno)

了解 VSCode Deno extension 更多的详细信息,可以阅读 justjavac(迷渡) 大佬 我为 VS Code 开发了一个 Deno 插件 这篇文章。

三、Deno 初体验

3.1 welcome demo

相信一些读者安装完 Deno 已经迫不及待了,现在我们立马来体验一下 Deno 应用程序。首先打开你熟悉的命令行,然后在命令行输入以下命令:

$ deno run https://deno.land/std/examples/welcome.ts
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Welcome to Deno ?

通过观察以上输出,我们可以知道当运行 deno run https://deno.land/std/examples/welcome.ts 命令之后,Deno 会先从 https://deno.land/std/examples/welcome.ts URL 地址下载 welcome.ts 文件,该文件的内容是:

console.log("Welcome to Deno ?");

当文件下载成功后,Deno 会对 welcome.ts 文件进行编译,即编译成 welcome.ts.js 文件,然后再通过 V8 引擎来执行编译生成的 JavaScript 文件。需要注意的是,如果你在命令行重新运行上述命令,则会执行缓存中已生成的文件,并不会再次从网上下载 welcome.ts 文件。

$ deno run https://deno.land/std/examples/welcome.ts
Welcome to Deno ?

那如何证明再次执行上述命令时, Deno 会优先执行缓存中编译生成的 JavaScript 文件呢?这里我们要先介绍一下 deno info 命令,该命令用于显示有关缓存或源文件相关的信息:

$ deno info
DENO_DIR location: "/Users/fer/Library/Caches/deno"
Remote modules cache: "/Users/fer/Library/Caches/deno/deps"
TypeScript compiler cache: "/Users/fer/Library/Caches/deno/gen"

在上述的输出信息中,我们看到了 TypeScript compiler cache 这行记录,很明显这是 TypeScript 编译器缓存的目录,进入该目录后,通过一层层的查找,我们最终在 examples 目录下找到了 welcome.ts.js 文件:

➜  examples ls
welcome.ts.js     welcome.ts.js.map welcome.ts.meta

打开目录中 welcome.ts.js 文件,我们可以看到以下内容:

"use strict";
console.log("Welcome to Deno ?");
//# sourceMappingURL=file:///Users/fer/Library/Caches/deno/gen/https/deno.land/std/examples/welcome.ts.js.map

下面我们来修改该文件,在文件中添加一行输出信息 console.log("Hello Semlinker, from Cache");,具体如下:

"use strict";
console.log("Hello Semlinker, from Cache");
console.log("Welcome to Deno ?");
//# sourceMappingURL=file:///Users/fer/Library/Caches/deno/gen/https/deno.land/std/examples/welcome.ts.js.map

接着我们在命令行中重新执行以下命令:

$ deno run https://deno.land/std/examples/welcome.ts
Hello Semlinker, from Cache
Welcome to Deno ?

那么现在问题又来了,如何强制刷新缓存,即重新编译 TypeScript 代码呢?针对这个问题,在运行 deno run 命令时,我们需要添加 --reload 标志,来告诉 Deno 需要重新刷新指定文件:

$ deno run --reload https://deno.land/std/examples/welcome.ts
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Welcome to Deno ?

除了 --reload 标志之外,Deno run 命令还支持很多其他的标志,感兴趣的读者可以运行 deno run --help 命令来查看更多的信息。

3.2 TCP echo server

前面我们已经介绍了如何运行官方的 welcome 示例,下面我们来介绍如何使用 Deno 创建一个简单的 TCP echo 服务器。首先我们创建一个 learn-deno 项目,然后在该项目下新建一个 quickstart 目录,接着新建一个 echo_server.ts 文件并输入以下代码:

const listener = Deno.listen({ port: 8080 });
console.log("listening on 0.0.0.0:8080");
for await (const conn of listener) {
  Deno.copy(conn, conn);
}

for await…of 语句会在异步或者同步可迭代对象上创建一个迭代循环,包括 String,Array,Array-like 对象(比如 arguments 或者 NodeList),TypedArray,Map, Set 和自定义的异步或者同步可迭代对象。 for await…of 的语法如下: > for await (variable of iterable) { > statement > } >

输入完以上代码之后,相信很多读者会跟我一样,直接在命令行运行以下命令:

➜  quickstart deno run ./echo_server.ts 
Compile file:///Users/fer/LearnProjects/learn-deno/quickstart/echo_server.ts
error: Uncaught PermissionDenied: network access to "0.0.0.0:8080", run again with the --allow-net flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
    at Object.listen ($deno$/ops/net.ts:51:10)
    at Object.listen ($deno$/net.ts:152:22)
    at file:///Users/fer/LearnProjects/learn-deno/quickstart/echo_server.ts:1:23

很明显是权限错误,从错误信息中,Deno 告诉我们需要设置 --allow-net 标志,以允许网络访问。为什么会这样呢?这是因为 Deno 是一个 JavaScript/TypeScript 的运行时,默认使用安全环境执行代码。下面我们添加 --allow-net 标志,然后再次运行 echo_server.ts 文件:

➜  quickstart deno run --allow-net ./echo_server.ts
listening on 0.0.0.0:8080

当服务器成功运行之后,我们使用 nc 命令来测试一下服务器的功能:

➜  ~ nc localhost 8080
hell semlinker
hell semlinker

介绍完如何使用 Deno 创建一个简单的 TCP echo 服务器,我们再来介绍一下如何使用 Deno 创建一个简单的 HTTP 服务器。

3.3 HTTP Server

与 TCP Server 一样,在 quickstart 目录下,我们新建一个 http_server.ts 文件并输入以下内容:

import { serve } from "https://deno.land/std@v0.50.0/http/server.ts";

const PORT = 8080;
const s = serve({ port: PORT });

console.log(` Listening on <http://localhost>:${PORT}/`);

for await (const req of s) {
  req.respond({ body: "Hello Semlinker\\n" });
}

友情提示:在实际开发过程中,你可以从 https://deno.land/std 地址获取所需的标准库版本。示例中我们显式指定了版本,当然你也可以不指定版本,比如这样:https://deno.land/std/http/server.ts

在上述代码中,我们导入了 Deno 标准库 http 模块中 serve 函数,然后使用该函数快速创建 HTTP 服务器,该函数的定义如下:

// std/http/server.ts
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 函数接收一个参数,其类型是 string | HTTPOptions,其中 HTTPOptions 接口的定义如下:

/** Options for creating an HTTP server. */
export type HTTPOptions = Omit<Deno.ListenOptions, "transport">;

export interface ListenOptions {
    /** The port to listen on. */
    port: number;
    /** A literal IP address or host name that can be resolved to an IP address.
     * If not specified, defaults to `0.0.0.0`. */
    hostname?: string;
}

当输入的参数类型是字符串时,serve 函数会使用 : 冒号对字符串进行切割,获取 hostname 和 port,然后包装成对象赋值给 addr 参数,接着使用 addr 参数继续调用 listen 函数进一步创建 listener 对象,最终调用 new Server(listener) 创建 HTTP 服务器。

创建完 HTTP 服务器,我们来启动该服务器,打开命令行输入以下命令:

➜  quickstart deno run --allow-net ./http_server.ts 
Compile file:///Users/fer/LearnProjects/learn-deno/quickstart/http_server.ts
 Listening on <http://localhost>:8080/

接着打开浏览器,在地址栏上输入 http://localhost:8080/ 地址,之后在当前页面中会看到以下内容:

Hello World\n

四、调试 Deno

Deno 支持 V8 Inspector Protocol。使用 Chrome Devtools 或其他支持该协议的客户端(比如 VSCode)能够调试 Deno 程序。要启用调试功能,用 --inspect--inspect-brk 选项运行 Deno,对应的选项描述如下:

--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

--inspect 选项允许在任何时间点连接调试器,而 --inspect-brk 选项会等待调试器连接,在第一行代码处暂停执行。

4.1 Chrome Devtools

让我们用 Chrome 开发者工具来调试一个简单的程序,我们将使用来自 stdfile_server.ts,这是一个简单的静态文件服务。

使用 --inspect-brk 选项,在第一行代码处暂停执行。

$ deno run --inspect-brk --allow-read --allow-net https://deno.land/std@v0.50.0/http/file_server.ts
Debugger listening on ws://127.0.0.1:9229/ws/1e82c406-85a9-44ab-86b6-7341583480b1
Download https://deno.land/std@v0.50.0/http/file_server.ts
Compile https://deno.land/std@v0.50.0/http/file_server.ts
...

打开 chrome://inspect,点击 Target 旁边的 Inspect

进一步了解更详细的调试说明,可访问 https://deno.land/manual/tools/debugger URL 地址。

4.2 VSCode

Deno 可以在 VSCode 中调试。插件的官方支持正在开发中 https://github.com/denoland/vscode_deno/issues/12,当然我们也可以通过手动提供 launch.json 配置,来连接调试器:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Deno",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}",
      "runtimeExecutable": "deno",
      "runtimeArgs": ["run", "--inspect-brk", "-A", "<entry_point>"],
      "port": 9229
    }
  ]
}

注意:将 <entry_point> 替换为实际的脚本名称。

下面让我们来尝试一下调试本地源文件,创建 server.ts

import { serve } from "https://deno.land/std@v0.50.0/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" });
}

<entry_point> 改为 server.ts,然后运行。

(图片来源:https://deno.land/manual/tools/debugger)

(图片来源:https://deno.land/manual/tools/debugger)

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:http://www.semlinker.com/复制
如有侵权,请联系 yunjia_community@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 【Deno】597- 了不起的 Deno 入门教程

    Deno 是一个 JavaScript/TypeScript 的运行时,默认使用安全环境执行代码,有着卓越的开发体验。Deno 含有以下功能亮点:

    pingan8787
  • 【Deno】600- 了不起的 Deno 实战教程

    对 Deno 还不了解的读者,建议先阅读本人 “了不起的 Deno 入门教程” 这篇文章。

    pingan8787
  • 了不起的 Deno 实战教程

    相信接触过 Node.js 的读者对 Express、Hapi、Koa 这些 Web 应用开发框架都不会陌生,在 Deno 平台中如果你也想做 Web 应用开发...

    阿宝哥
  • 了不起的 Deno 实战教程

    对 Deno 还不了解的读者,建议先阅读本人 “了不起的 Deno 入门教程” 这篇文章。

    山月
  • 用最低调的功能,炫最高调的Deno

    微信群里 JJC 大佬发出了一个链接,我在 PC 端打开便是上面图中所示。凡尔赛?莫非是 Deno 的新特性?怀着对技术的热情和好奇,我先搜索了一下,原来--“...

    胡琦
  • Deno 运行时入门教程:Node.js 的替代品

    这几天假期,我学习了一下 Deno。它是 Node.js 的替代品。有了它,将来可能就不需要 Node.js 了。

    ruanyf
  • Deno 入门指南

    2018 年时,一篇 如何看待 ry 的项目 deno 的 issue 被中文刷屏的事件? 的文章成功引起了我对 Deno 的注意,cnode 有一篇文章严厉斥...

    用户1250838
  • 了不起的 TypeScript 入门教程

    想学习 TypeScript 的小伙伴看过来,本文将带你一步步学习 TypeScript 入门相关的十四个知识点,详细的内容大纲请看下图:

    阿宝哥
  • 15个很有趣的开源项目推荐

    新年快乐,愉快的假期中总是不自觉的打开电脑?。开源的世界每天都会有各种惊喜,下面是我们整理的15个有趣的开源项目,希望当中有您喜欢的。

    腾讯新闻前端团队
  • 【学不动了系列】之 Deno 入门 什么是Deno安装DenoDeno运行时(Runtime)Deno标准库第三方模块

    希望大家不要被标题吓到,纯属为了吸引眼球?。。根据笔者这两天的学习感受,Deno 比 Node 更容易入门,如果你有 Node 的基础那更简单了,很多东西都是可...

    MudOnTire
  • CloudBase Framework丨第一个 Deno 部署工具是如何打造的?

    云端一体化部署工具 CloudBase Framework (简称 CBF)自开源发布以来迭代迅速,不仅支持 Vue、React 等前端框架,也支持 Nuxt ...

    腾讯云开发TCB
  • WebAssembly 是 Deno 的好搭档

    备受期待的 Deno 项目 终于发布了 1.0 版本!Deno 是由 Node.js 的创始人 Ryan Dahl 创建的,旨在解决他所说的“我为 Node.j...

    深度学习与Python
  • Deno 1.0,来了解一下

    编者按:本文译者李松峰,资深技术图书译者,翻译出版过40余部技术及交互设计专著,现任360奇舞团Web前端开发资深专家,360前端技术委员会委员、W3C AC代...

    前端劝退师
  • Deno 1.0,来了解一下

    经过近两年的等待,官方正式宣布Deno 1.0将于5月13日发布。如今,API已经冻结,倒计时开始。

    山月
  • Deno TCP Echo Server 是怎么运行的

    在 “了不起的 Deno 入门教程” 这篇文章中,我们介绍了如何使用 Deno 搭建一个简单的 TCP echo server,本文将使用该示例来探究 TCP ...

    山月
  • 150. 精读《Deno 1.0 你需要了解的》

    Deno 将于 2020-05-13 发布 1.0,如果你还有上面的疑惑,可以和我一起通过 Deno 1.0: What you need to know 这篇...

    黄子毅
  • Node.js 如何应对来自 Ryan Dahl 的 Deno 的挑战

    开源JavaScript运行时Node.js上周发布了第15版。经历了11年个年头,Node.js一如既往地受欢迎,但是在2020年,一个竞争对手横空出世。De...

    五月君
  • “Deno 在手,天下我有”,极速获取今日热榜

    本周,被@justjavac 巨佬的各个热搜榜项目吸睛了,抱着对技术的三分钟热情以及对优秀代码的学习心切,我又开始了新的代码拷贝旅程。二话不说,先git clo...

    胡琦

扫码关注云+社区

领取腾讯云代金券