微信搜索【前端全栈开发者】关注这个脱发、摆摊、卖货、持续学习的程序员的,第一时间阅读最新文章,会优先两天发表新文章。关注即可大礼包,准能为你节省不少钱!
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。
考虑以下具有导出的 hello 和 sum 函数的 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。也有一些第三方测试模块,包括Merlin和Ruhm,但这些模块在表面之下仍然使用 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 命令:
- 任何必需的运行时权限标志,例如
--allow-read,--allow-write或--allow-net。 - 可选的已安装脚本名称,带有
--name <scriptname>。 - 一个可选的安装根目录,使用
--root <path>。如果没有设置,Deno会将脚本安装到DENO_INSTALL_ROOT环境变量或$HOME/.deno/bin/中设置的路径。 - 模块路径或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目前没有提供 uninstall 或 remove 命令。移除脚本的唯一方法是手动从 .deno/bin/ 目录或任何安装它的地方删除生成的文件。
有关更多信息,请参见Deno Manual: Script Installer。
完整的Deno工具包?
Deno的工具是新的,有的还很初级,但是文档化的“标准”方法是有好处的。Node.js提供了众多的第三方选择,但这可能会导致选择麻痹或不断切换解决方案。你是否还在坚持使用同一个Node.js测试套件?
但是,请注意:随着Deno使用量的增加,这些内置工具可能会迅速发展。
原文:www.sitepoint.com
作者:Craig Buckler