如何使用Deno的内置工具

1,234 阅读5分钟

微信搜索【前端全栈开发者】关注这个脱发、摆摊、卖货、持续学习的程序员的,第一时间阅读最新文章,会优先两天发表新文章。关注即可大礼包,准能为你节省不少钱!

Deno和Node.js之间一个令人惊讶的区别是运行时内置的工具数量。除了Read-Eval-Print Loop(REPL)控制台之外,Node.js还需要第三方模块来处理大多数间接编码活动,比如测试和linting。Deno内置工具几乎提供了开箱即用所需的一切。

在开始之前,请注意:**Deno是新的!**请谨慎使用这些工具,有些可能不稳定,很少有配置选项。其他的工具可能会产生不良的副作用,比如递归处理每个子目录中的每个文件。最好从专门的项目目录中测试工具。

安装Deno

使用以下终端命令在macOS或Linux上安装Deno:

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

或从Windows Powershell:

iwr https://deno.land/x/install/install.ps1 -useb | iex

Deno手册中提供了更多安装选项。

输入 deno —version 以检查安装是否成功,显示V8 JavaScript引擎,TypeScript编译器和Deno本身的版本号。

升级Deno

deno upgrade

或升级到特定版本,例如v1.3.0:

deno upgrade --version 1.30.0

以下大多数工具在所有版本中都可用,但是更高版本可能具有更多功能和错误修复。

Deno 帮助

输入以下命令可以查看工具和选项的列表:

deno help

Eval-Print Loop (REPL)

和Node.js一样,可以通过在终端输入 deno 来访问repl表达式评估控制台。输入的每个表达式都返回一个结果或 undefined 的结果:

$ deno

Deno 1.3.0
exit using ctrl+d or close()
> const w = 'World';
undefined
> w
World
> console.log(`Hello ${w}!`);
Hello World!
undefined
> close()

$

通过使用光标键导航表达式历史记录,可以重新输入以前输入的表达式。

依赖检查

可以通过输入 deno info <module> 来查看所有模块的依赖关系树,其中 <module> 是一个入口脚本的path/URL。

考虑以下具有导出的 hellosum 函数的 lib.js 库代码:

// general library: lib.js

/**
 * 返回“Hello <name>!”字符串
 * @module lib
 * @param {string} name
 * @returns {string} Hello <name>!
 */
export function hello(name = 'Anonymous') {
  return `Hello ${ name.trim() }!`;
};

/**
 * 返回所有参数的总数
 * @module lib
 * @param {...*} args
 * @returns {*} total
 */
export function sum(...args) {
  return [...args].reduce((a, b) => a + b);
}

这些可以从同一目录下的主入口脚本 index.js 中使用:

// main entry script: index.js

// import lib.js modules
import { hello, sum } from './lib.js';

const
  spr = sum('Site', 'Point', '.com', ' ', 'reader'),
  add = sum(1, 2, 3);

// output
console.log( hello(spr) );
console.log( 'total:', add );

运行 deno run ./index.js 的结果:

$ deno run ./index.js

Hello SitePoint.com reader!
total: 6

可以使用 deno info ./index.js 检查 index.js 使用的依赖项:

$ deno info ./index.js

local: /home/deno/testing/index.js
type: JavaScript
deps:
file:///home/deno/testing/index.js
  └── file:///home/deno/testing/lib.js

类似地,可以检查任何模块URL所需的依赖关系,不过要注意模块在第一次使用时将被下载并缓存在本地。例如:

$ deno info https://deno.land/std/hash/mod.ts

Download https://deno.land/std/hash/mod.ts
Download https://deno.land/std@0.65.0/hash/mod.ts
Download https://deno.land/std@0.65.0/hash/_wasm/hash.ts
Download https://deno.land/std@0.65.0/hash/hasher.ts
Download https://deno.land/std@0.65.0/hash/_wasm/wasm.js
Download https://deno.land/std@0.65.0/encoding/hex.ts
Download https://deno.land/std@0.65.0/encoding/base64.ts
deps:
https://deno.land/std/hash/mod.ts
  └─┬ https://deno.land/std@0.65.0/hash/_wasm/hash.ts
    ├─┬ https://deno.land/std@0.65.0/hash/_wasm/wasm.js
    │ └── https://deno.land/std@0.65.0/encoding/base64.ts
    ├── https://deno.land/std@0.65.0/encoding/hex.ts
    └── https://deno.land/std@0.65.0/encoding/base64.ts

有关更多信息,请参见《 Deno手册:依赖检查器》

Linter (语法检查)

Deno提供了一个linter来验证JavaScript和TypeScript代码。这是一个不稳定的功能,需要使用 —unstable 标志,但使用时不会改变文件。

Linter 有助于发现不太明显的语法错误,并确保代码符合团队的标准。你可能已经在你的编辑器中或从命令行中使用了像ESLint这样的linter,但是Deno在任何安装了它的环境中提供了另一个选项。

要递归lint当前和子目录中的所有 .js.ts 文件,输入 deno lint —unstable

$ deno lint --unstable

(no-extra-semi) Unnecessary semicolon.
};
 ^
    at /home/deno/testing/lib.js:13:1

Found 1 problem

另外,你也可以指定一个或多个文件来限制linter。例如:

$ deno lint --unstable ./index.js
$

更多信息,请参见Deno Manual: Linter。它包含了一系列的规则,你可以在代码注释中添加这些规则来忽略或强制执行特定的语法。它包括一个规则列表,你可以添加到代码注释中,以忽略或强制执行特定的语法。

测试运行

Deno具有用于对JavaScript或TypeScript函数进行单元测试的内置测试运行程序。

测试定义在任何名为 <something>test 的文件中,扩展名为 .js.mjs.ts.jsx.tsx。它必须对 Deno.test 进行一次或多次调用,并传递一个测试名称字符串和一个测试函数。该函数可以是同步的或异步的,并且可以使用各种断言实用程序来评估结果。

使用名为 lib.test.js 的文件创建一个新的测试子目录:

// test lib.js library

// assertions
import { assertEquals } from 'https://deno.land/std/testing/asserts.ts';

// lib.js modules
import { hello, sum } from '../lib.js';

// hello function
Deno.test('lib/hello tests', () => {

  assertEquals( hello('Someone'), 'Hello Someone!');
  assertEquals( hello(), 'Hello Anonymous!' );

});

// sum integers
Deno.test('lib/sum integer tests', () => {

  assertEquals( sum(1, 2, 3), 6 );
  assertEquals( sum(1, 2, 3, 4, 5, 6), 21 );

});

// sum strings
Deno.test('lib/sum string tests', () => {

  assertEquals( sum('a', 'b', 'c'), 'abc' );
  assertEquals( sum('A', 'b', 'C'), 'AbC' );

});

// sum mixed values
Deno.test('lib/sum mixed tests', () => {

  assertEquals( sum('a', 1, 2), 'a12' );
  assertEquals( sum(1, 2, 'a'), '3a' );
  assertEquals( sum('an', null, [], 'ed'), 'annulled' );

});

要运行所有目录下的所有测试,输入 deno test,或者使用 deno test <dir> 运行存储在特定目录中的测试。例如:

$ deno test ./test

running 4 tests
test lib/hello tests ... ok (4ms)
test lib/sum integer tests ... ok (2ms)
test lib/sum string tests ... ok (2ms)
test lib/sum mixed tests ... ok (2ms)

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (11ms)

$

也可以指定 —filter 字符串或正则表达式以按名称限制测试。例如:

$ deno test --filter "hello" ./test

running 1 tests
test lib/hello tests ... ok (4ms)

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out (5ms)

通过传递 —failfast 选项,可以在第一次失败时停止运行时间更长的测试。

更多信息,请参见Deno Manual: Testing。也有一些第三方测试模块,包括MerlinRuhm,但这些模块在表面之下仍然使用 Deno.test

V8 Debugger

Deno提供了和Node.js一样的V8引擎和调试器。可以使用Chrome浏览器或VS Code连接到调试器,然后通过代码来查看变量和对象的变化。

要启动调试器,使用 —inspect--inspect-brk 运行脚本,在第一行停止。如果你需要从网络上的其他设备连接到调试器,添加它的IP地址和端口,或者使用 --inspect=0.0.0.0:9229 允许从任何地方连接。例如:

$ deno run --inspect-brk=0.0.0.0:9229 ./index.js

Debugger listening on ws://0.0.0.0:9229/ws/ceb123...
Debugger session started.

在新的Chrome标签中打开,然后 deno 脚本将显示为新的远程目标

注意:“Node专用DevTools”将不会连接到Deno的调试器,即使它们相似。

点击目标的inspect链接以启动DevTools。如果你使用过客户端调试,就会很熟悉。Sources选项卡是最有用的,可让你逐步执行代码:

有关更多信息,请参见Deno Manual: Debugger

代码格式化

内置的代码格式化器可以自动格式化JavaScript和TypeScript代码,方式与Prettier类似。Deno的格式化程序也是固执己见的,目前不可能配置选项。

要使用它,请输入 deno fmt 递归地格式化每个子目录中的每个文件。例如:

$ deno fmt

/home/deno/testing/index.js
/home/deno/testing/test/lib.test.js
/home/deno/testing/lib.js

另外,你可以格式化一个或多个单独的文件,例如 deno fmt ./index.js

如果你检查 lib.test.js 文件,你会看到格式化程序删除了一些空格并将字符串转换为使用双引号():

// hello function
Deno.test("lib/hello tests", () => {
  assertEquals(hello("Someone"), "Hello Someone!");
  assertEquals(hello(), "Hello Anonymous!");
});

可以通过添加 // deno-fmt-ignore 注释来忽略各个代码块。例如:

// deno-fmt-ignore
const bin = [
              1, 0, 0,
              0, 1, 0,
              0, 0, 1,
            ];

通过在代码顶部添加 // deno-fmt-ignore-file 注释,可以忽略整个文件。

有关更多信息,请参见Deno Manual: Code Formatter

警告!自动格式化可能会对JSDoc注释产生不利影响。

文档生成

Deno可以从源代码中的JSDoc注释生成文档,这些注释解释了一个函数的目的、参数和返回值。目前,Deno只会为导出函数的模块生成文档。例如:

$ deno doc ./lib.js

Defined in file:///home/deno/testing/lib.js:9:0

function hello(name)
  return "Hello <name>!" string
  @module lib
  @param {string} name
  @returns {string} Hello <name>!

Defined in file:///home/deno/testing/lib.js:21:0

function sum(...args)
  Returns total of all arguments
  @module lib
  @param {...*} args
  @returns {*} total

$

添加 —json 标志将以JSON格式输出文档。

有关更多信息,请参见Deno Manual: Documentation Generator

脚本打包

你的主脚本及其所有依赖项可以使用以下方法捆绑到一个文件中:

deno bundle <main-script> <output-script>

例如:

$ deno bundle ./index.js ./index.bundle.js

Bundle file:///home/deno/testing/index.js
Emit "./index.bundle.js" (3.13 KB)

然后可以执行生成的脚本:

$ deno run ./index.bundle.js

Hello SitePoint.com reader!
total: 6

将脚本分发给最终用户或将最终代码库部署到实时服务器时,这可能会很有用。

注意:捆绑时顶级await调用可能会失败,因此必须添加异步包装器函数。这是一个已知问题,将在将来的Deno版本中修复。

有关更多信息,请参见Deno Manual: Bundling

脚本安装程序

Deno脚本可以全局安装,这样就可以从文件系统的任何位置运行。它类似于安装全局的Node.js模块,但有些简单,更容易使用。

必须通过 deno install 命令:

  1. 任何必需的运行时权限标志,例如 --allow-read--allow-write--allow-net
  2. 可选的已安装脚本名称,带有 --name <scriptname>
  3. 一个可选的安装根目录,使用 --root <path>。如果没有设置,Deno会将脚本安装到 DENO_INSTALL_ROOT 环境变量或$HOME/.deno/bin/ 中设置的路径。
  4. 模块路径或URL。

上面的示例脚本可以通过以下方式安装:

$ deno install --name myscript ./index.js

✅ Successfully installed myscript
/home/deno/.deno/bin/myscript

将在 .deno/bin/ 目录中创建一个 myscript 文件,其内容如下:

#!/bin/sh
# generated by deno install
deno "run" "file:///home/deno/testing/index.js" "$@"

myscript 现在可以在系统上的任何位置运行。例如:

cd ~
$ myscript

Hello SitePoint.com reader!
total: 6

通过此过程,很容易告诉用户如何从已发布的URL安装应用程序。例如:

deno install --name myapp https://myserver.com/myapp.js
myapp

Deno目前没有提供 uninstallremove 命令。移除脚本的唯一方法是手动从 .deno/bin/ 目录或任何安装它的地方删除生成的文件。

有关更多信息,请参见Deno Manual: Script Installer

完整的Deno工具包?

Deno的工具是新的,有的还很初级,但是文档化的“标准”方法是有好处的。Node.js提供了众多的第三方选择,但这可能会导致选择麻痹或不断切换解决方案。你是否还在坚持使用同一个Node.js测试套件?

但是,请注意:随着Deno使用量的增加,这些内置工具可能会迅速发展。


原文:www.sitepoint.com
作者:Craig Buckler