Deno 1.42:使用 JSR 改进依赖管理
我们对 Deno 的愿景是简化编程,其中一个重要方面就是管理依赖项。尽管 npm 已成为最成功的开源注册表,但在其上使用和发布模块已变得越来越复杂。
基于 npm 的成功,JSR 提供了一个现代的、TypeScript 优先的、跨平台兼容的注册表,并已完全集成到 Deno 中。
Deno v1.42 通过deno publish
和 deno add
子命令提供了更强大的依赖管理功能,它们可以从 JSR 和 npm 发布和安装模块。此外,此版本还提供了改进的 Node/npm 兼容性、多项 LSP 改进、更快的启动时间(以及其他性能优势)等功能。
如果您已安装 Deno,请在您的终端中升级到 1.42 版本:
deno upgrade
如果您尚未安装 Deno,可以使用以下命令之一安装,或通过许多其他方式安装。
MacOS / Linux 安装
curl -fsSL https://deno.land/install.sh | sh
Windows 安装
irm https://deno.land/install.ps1 | iex
以下是 Deno 1.42 的新功能概览:
- JSR、
deno publish
和deno add
- Node.js 和 npm 兼容性
deno task
deno lint --fix
- 更简单的
deno run --check
- 即将到来的
deno install
更改 - 语言服务器改进
- 性能
- V8 12.3 和 TypeScript 5.4.3
DENO_FUTURE=1
环境变量
deno publish
和 deno add
JSR、JSR 是一个适用于现代 JavaScript 和 TypeScript 包的全新开源注册表。阅读我们构建 JSR 的原因。JSR 使用起来非常愉快。它消除了分发 TypeScript 和 JavaScript 的所有麻烦。我们相信您一定会喜欢它。
在 1.42 版本中,Deno 增加了对 JSR 的一流支持。这意味着无需任何额外工具,您就可以使用和发布模块到 JSR。
有两个新的子命令。首先是 deno add
。它的工作方式与 npm add
类似,但默认用于 JSR 包。例如,如果您想从 JSR 使用 @std/assert
,只需运行:
deno add @std/assert
这将添加一个导入映射条目,让您可以在代码中轻松导入:
import { assertEquals } from "@std/assert";
assertEquals(1, 2);
请注意,deno add
也支持使用 npm:
前缀添加 npm 包。
对于模块作者来说,deno publish
正如您所期望的,它会发布到 JSR。您可以在此处阅读所有相关内容。
JSR 也完全集成到 Deno 的 LSP 和 VS Code 扩展中。即使使用 TypeScript,go-to-definition 也能正常工作。JSR 包的智能感知功能应该也能完美运行。
我们非常乐意听取您对这些新功能的反馈。
Node.js 和 npm 兼容性
此版本在使 Deno 与 Node.js 兼容方面进行了大量改进:
async_hooks
模块现在支持EventEmitterAsyncResource
AsyncLocalStorage.enterWith()
API #22994 #22740child_process.spawn()
在stdio
配置中正确处理null
#23048crypto
模块正稳步完善。在此版本中,我们添加了getRandomValues()
、subtle
、getCipherInfo()
、publicKey()
、createPublicKey()
API,并在多个 API 中添加了对更多曲线的支持。这些更改应能解除ssh2
、web-push
、octokit
等流行包的使用限制。#22882 #22891 #23028fs
获得了对 Windows “junctions”、FsWatcher.ref()
、FsWatcher.unref()
和fs.statfs()
API 的支持。#22987 #22294http
模块现在导出validateHeaderName()
和validateHeaderValue()
API,并且ServerResponse
现在正确支持设置 HTTP 方法。#22630 #22616http2
获得了对createServer()
API 的基本支持。#22708现在支持
module.isBuiltin()
#22817process.arch
现在支持"riscv64"
process.argv0
现在已正确设置process.version
已更新为返回 Node.js 的最新 LTS 版本v20.11.1
process.setSourceMapsEnabled
现已可用,但为无操作(no-op)punycode
模块工作正常 #22847string_decoder.StringDecoder()
与 Node.js 行为一致 #22933timers.setImmediate
与 Node.js API 和行为一致 #22808现在支持
util.styleText
#22758worker_threads
模块经过重大改造。它现在正确支持 ES 模块和 CommonJS。以下 API 现已支持:parentPort
、workerData
、isMainThread
、threadId
、receiveMessageOnPort()
、ref()
、unref()
。Worker 现在同步设置,并在空闲时自动终止。#22841 #20794 #22950 #22647 #22884 #22815 #22766 #22778
以及与 npm 兼容性相关的几项改进:
用户代码现在可以从
node_modules/
目录正确导入 CommonJS 文件现在支持内部条件导出(以
#
开头的导出,例如#crypto
)在类型检查期间,CSS 文件可以从 npm 包中正确解析
此外,设置 node_modules/
目录的性能也得到了改进——在 Deno v1.42 中,您可以看到高达 1.7 倍的速度提升。
deno task
deno task
中已支持所有以 #!/usr/bin/env -S
开头的 shebang 的跨平台功能。
给定一个 script.ts
文件和 deno.json
:
#!/usr/bin/env -S deno run
console.log("Hello there!");
{
"tasks": {
"hi": "./script.ts"
}
}
现在,即使在 Windows 机器上,运行此任务也有效:
> pwd
C:\Users\david\dev\my_project
> deno task hi
Hello there!
退出状态变量
shell 现在支持使用 $?
获取上次运行命令的退出代码。
{
"tasks": {
// outputs 10
"output": "deno eval 'Deno.exit(10)' || echo $?"
}
}
改进的重定向支持
现在已实现输入重定向和更多文件描述符重定向。
{
"tasks": {
// redirect file.txt to the stdin of gzip
"input-redirect": "gzip < file.txt",
// redirect stdout to stderr
"stdout-err": "deno run main.ts >&2",
// redirect stderr to stdout
"stderr-out": "deno run main.ts 2>&1"
}
}
任务描述
如果您使用 JSONC 文件,现在可以通过注释为任务添加描述。
{
"tasks": {
// Start development server
"dev": "deno run --watch main.ts",
/**
* Run tests with coverage and output HTML report
*/
"coverage": "deno test --coverage **/*_test.ts && deno coverage --html"
}
}
$ deno task
- dev
// Start development server
deno run --watch main.ts
- coverage
// Run tests with coverage and output HTML report
deno test --coverage **/*_test.ts && deno coverage --html
deno lint --fix
已实现基础设施,可以在命令行上通过快速修复自动修复 lint 规则,并在编辑器中进行操作。
例如,给定以下代码:
window.onload = () => console.log("Hi there!");
deno lint
现在输出如下:
> deno lint
error[no-window]: window is deprecated and scheduled for removal in Deno 2.0
--> main.ts:1:1
|
1 | window.onload = () => console.log("Hi there!");
| ^^^^^^
= hint: Instead, use `globalThis`
docs: https://lint.deno.land/rules/no-window
Found 1 problem (1 fixable via --fix)
Checked 1 file
请注意文本 (1 fixable via --fix)
。让我们试试看:
> deno lint --fix
Checked 1 file
> cat main.ts
globalThis.onload = () => console.log("Hi there!");
> deno lint
Checked 1 file
目前,这仅适用于三个 lint 规则,但列表将随着时间增长。
--watch-exclude=...
有时在使用 --watch
标志时,您可能不希望某些文件触发重启。现在可以通过 --watch-exclude
标志实现此功能。
# exclude file1.ts and file2.ts from being watched
deno run --watch --watch-exclude=file1.ts,file2.ts main.ts
您也可以排除模式,但请记住用引号括起来,以防止您的 shell 在将参数发送到 Deno 之前展开它们。
# exclude any .js file from being watched
deno run --watch --watch-exclude='*.js' main.ts
jsr
标签和 verbatim-module-syntax
lint 规则
包含 name
、version
和 exports
字段的 deno.json 文件现在会自动选择加入 jsr
lint 规则标签。
此标签包含以下规则:
no-slow-types
verbatim-module-syntax
(可通过--fix
修复)
no-slow-types
lint 规则是 JSR 特有的,您可以在 jsr.io 上阅读相关内容。verbatim-module-syntax
lint 规则强制要求 import
和 export
声明仅在其在类型位置使用时才将其标识符定义为仅类型。这对于确保发布在 jsr.io 上的代码在更多场景中工作至关重要。您可以在 TypeScript 5.0 发布说明中阅读有关逐字模块语法的信息。
应用程序执行过程中不再进行类型检查
以前,如果您使用 --check
标志运行 deno run
,Deno 可能会在遇到静态无法分析的动态导入或启动 worker 时,在执行过程中进行类型检查。
此功能带来了很大的维护负担,对 JSR 提出了一些挑战,并可能导致正在运行的应用程序在执行过程中失败的不良行为。因此,初始类型检查之后不再进行类型检查(强调:deno run --check main.ts
仍然在执行任何模块之前进行类型检查)。
如果需要,建议您改用 deno check
子命令来对这些模块进行类型检查。
deno install
更改
即将到来的 deno install
允许您轻松安装和分发可执行代码。
$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
✅ Successfully installed file_server.
$ file_server
Listening on http://127.0.0.1:4507
我们收到了反馈,虽然此命令很有用,但许多用户期望它能将依赖项“安装”到项目本地——就像之前引入的 deno add
一样。
为了更好地符合预期,deno install
在 Deno 2 中将更改为将脚本安装到项目本地。也就是说,deno install
将成为 deno add
的别名。
当前行为仍将通过 -g
/ --global
标志支持,以告知 Deno 您希望全局安装脚本。
$ deno install --global --allow-net --allow-read https://deno.land/std/http/file_server.ts
✅ Successfully installed file_server.
如果您省略 -g
/ --global
标志,Deno 现在将警告您并建议使用它。
语言服务器改进
自 v1.37 以来,我们的 LSP 已支持 npm:
规范符的补全。在 v1.42 中,我们不仅增加了对 jsr:
规范符的支持,还支持包名和版本的补全。
import "jsr:@std/a";
// "jsr:@std/archive";
// "jsr:@std/assert"; ✔️
// "jsr:@std/async";
// "jsr:@std/data-structures";
// "jsr:@std/datetime";
// ...
import "jsr:@std/assert@";
// "jsr:@std/assert@0.220.1"; ✔️
// "jsr:@std/assert@0.219.1";
// "jsr:@std/assert@0.219.0";
// "jsr:@std/assert@0.218.2";
// "jsr:@std/assert@0.218.1";
// ...
其他改进和修复:
- 在 JSR 导入悬停文本中包含注册表 URL。
- 不警告从 .js 到 .d.ts 文件的本地文件“重定向”。
- 不将符号重命名应用于供应商远程模块。
- 对包规范符导入映射键应用尾随斜杠扩展。
性能
此版本整体性能得到了多项改进,其中最显著的是:
更快的启动时间: Linux 上的启动时间提高了 10%。引导初始化现在在快照时预热,并减少了内存分配。
更高效的 setTimeout
和 setInterval
: 定时器经过了重大重写。创建一百万个定时器大约需要 1.4 秒,而 Deno 1.41 中需要 5.9 秒,内存使用量也减少了高达 70%。我们还有一些优化工作将在未来几个月内进行。
V8 12.3 和 TypeScript 5.4.3
Deno 1.42 附带了 V8 12.3 和 TypeScript 5.4.3。值得注意的更改包括支持 Set
方法和支持 Iterator Helpers。
以下现在可用:
- Iterator.prototype.map(mapperFn)
- Iterator.prototype.filter(filtererFn)
- Iterator.prototype.take(limit)
- Iterator.prototype.drop(limit)
- Iterator.prototype.flatMap(mapperFn)
- Iterator.prototype.reduce(reducer [,initialValue])
- Iterator.prototype.toArray()
- Iterator.prototype.forEach(fn)
- Iterator.prototype.some(fn)
- Iterator.prototype.every(fn)
- Iterator.prototype.find(fn)
- Iterator.from(object)
- Set.prototype.intersection(other)
- Set.prototype.union(other)
- Set.prototype.difference(other)
- Set.prototype.symmetricDifference(other)
- Set.prototype.isSubsetOf(other)
- Set.prototype.isSupersetOf(other)
- Set.prototype.isDisjointFrom(other)
DENO_FUTURE=1
环境变量
Deno v1.42 添加了一个新的环境变量 DENO_FUTURE=1
,它将启用期待已久、多次延迟的 Deno 2 中的更改。
目前 DENO_FUTURE=1
启用以下更改:
- 移除
window
全局对象 - 移除以下
Deno
API:Deno.Buffer
、Deno.close
、Deno.copy
、Deno.File
、Deno.FsFile.prototype.rid
、Deno.fstat
、Deno.fstatSync
、Deno.ftruncate
、Deno.ftruncateSync
、Deno.flock
、Deno.flockSync
、Deno.funlock
、Deno.funlockSync
、Deno.iter
、Deno.iterSync
、Deno.metrics
、Deno.readAll
、Deno.readAllSync
、Deno.read
、Deno.readSync
、Deno.resources
、Deno.seek
、Deno.seekSync
、Deno.shutdown
、Deno.writeAll
、Deno.writeAllSync
、Deno.write
、Deno.writeSync
在后续版本中,我们将添加更多 Deno 2 中将发生的更改,包括对 node_modules/
目录处理方式的更改。特别是在 DENO_FUTURE
下启用 BYONM。
如果您想为即将发布的主要 Deno 2 版本做好代码的未来兼容性准备,您可以在 shell 或 CI 环境中设置 DENO_FUTURE=1
环境变量。
感谢我们的贡献者!
没有我们社区的帮助,我们就无法构建 Deno!无论是通过在我们的社区 Discord 服务器中回答问题,还是报告错误,我们都非常感谢您的支持。特别是,我们要感谢以下对 Deno 1.42 做出贡献的人:Dimitris Apostolou、Don Jayamanne、Eric Long、Kenta Moriuchi、Nano Miratus、Sol Boucher、Viktor Marinho、cui fliter、guangwu、mash-graz、mimikun、tuhana、ud2 和 Łukasz Czerniawski。
您想加入 Deno 贡献者的行列吗?请查看我们的贡献文档,下次再见到您出现在贡献者名单上。
信不信由你,上面列出的更改仍然没有告诉您 1.42 中所有改进的地方。您可以在 GitHub 上查看 Deno 1.42 中合并的完整拉取请求列表。
感谢您关注我们的 1.42 版本,我们希望您喜欢使用 Deno 进行构建!
🍋 Fresh 2.0 即将到来。
我们的下一个主要 Fresh 版本将更简单,具有更具组合性、类似 Express 的 API。在此处阅读更多信息。