Deno 1.34:deno compile 支持 npm 包
在我们继续朝着 Deno 2 的开发之旅前进的过程中,这个小版本主要集中在提高与 npm 和 Node.js 的兼容性,增强整体的易用性和开发人员体验,并为未来的性能增强奠定基础。
此版本中最重要的更新包括三个备受期待的功能
除了上述功能外,还有许多其他值得一提的改进和错误修复
deno compile
支持 npm 包
自从 v1.6 以来,deno compile
允许您将项目编译成单个二进制可执行文件。这项开发已被证明对许多原因至关重要,因为它使开发人员能够
- 在所有主要平台上分发和执行二进制文件,而无需安装 Deno 或依赖项
- 将资产包含在可执行文件中,以提高可移植性
- 使用单个二进制文件简化部署
- 实现更快的启动时间
从那时起,我们一直在努力使 deno compile
更加有用,通过 添加对 web 工作者和动态导入的支持,以及今天,通过支持 npm 包。
以下是用 cowsay
创建单个二进制可执行文件的示例
$ cat main.ts
import { say } from "npm:[email protected]";
console.log(say({ text: "Hello from Deno!" }));
$ deno compile --allow-read main.ts
$ ./main
__________________
< Hello from Deno! >
------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
cowsay
是一个简单的示例,但您可以将 deno compile
用于更复杂的项目。让我们尝试 vite
$ deno compile --allow-read --allow-write --allow-env --allow-net npm:vite
$ ./vite
➜ Local: https://127.0.0.1:5173/
➜ Network: use --host to expose
➜ press h to show help
或者可能是 eslint
?
$ deno compile --allow-read --allow-write --allow-env --allow-net npm:eslint
$ cat .eslintrc.js
module.exports = {
"env": {
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
}
}
$ cat foo.js
function foo() {
}
$ ./eslint
/dev/foo.js
1:10 error 'foo' is defined but never used no-unused-vars
✖ 1 problem (1 error, 0 warnings)
使用 deno compile
创建 eslint
二进制文件与 npm install -g eslint
之间的区别在于,Deno 将 eslint
与其所有依赖项和配置一起打包到 deno
可执行文件中。这意味着生成的二进制文件确保其依赖项不会意外更改,并继续以相同的方式工作,而不会受到系统上其他依赖项的干扰。此外,我们的测试表明,从 deno compile
生成的二进制文件往往比使用本地缓存的依赖项执行同一程序启动速度更快。
还有更多工作需要完成以改进 deno compile
,包括最小化二进制文件的总大小,我们打算在即将发布的版本中解决此问题。
您对 deno compile
有具体反馈吗?告诉我们。
deno.json
和 CLI 标志中的通配符支持
通配符 现在在配置文件 deno.json
、deno task
和 CLI 参数中受支持,用于指定文件。通配符语法是跨平台的,因此您可以放心地在 Windows、macOS 和 Linux 上使用它。
在 **deno.json
** 中,您可以使用 *
匹配路径中的任意数量的字符,使用 ?
匹配单个字符,使用 **
匹配任意数量的目录
{
"fmt": {
"include": ["data/example?.txt"],
"exclude": ["testdata/**/*.ts"]
}
}
您也可以将通配符模式用作 **CLI 参数**。以下是用 deno fmt
的上述示例
$ deno fmt --exclude="testdata/**/*.ts" "data/example?.txt"
⚠️ 请注意,我们将通配符放在引号中,以防止 shell 展开它。
使用 **deno task
** 时,除了上面的通配符语法之外,您还可以使用方括号匹配一系列字符
{
"task": {
"files": "echo **/*.ts",
"data": "echo data[0-9].txt"
}
}
带有 IP 地址的 TLS 证书
最受欢迎的功能之一终于来了。您现在可以使用包含 IP 地址的 TLS 证书。
这对 Kubernetes Pod 之类的东西很有用,这些 Pod 通常使用 IP 地址而不是域名,以及对 DNS over HTTPS/TLS 的使用,它需要服务器的 IP 地址以避免对名称解析的循环依赖。
使用 Deno v1.34,任何使用 TLS 的 API 都可以使用 IP 地址。例如
const resp = await fetch("https://1.1.1.1");
console.log(await resp.text());
配置文件改进
为所有子命令排除文件或文件夹
以前,如果您想让 Deno 忽略每个子命令的文件或文件夹,您必须重复指定它
{
"fmt": {
"exclude": ["target/"]
},
"lint": {
"exclude": ["target/"]
},
"test": {
"exclude": ["target/"]
},
"bench": {
"exclude": ["target/"]
}
}
从这个版本开始,您可以使用顶级的 exclude
属性
{
"exclude": ["target/"]
}
感谢 @scarf005 实施此功能。
nodeModulesDir
属性
现在可以在 deno.json
文件中指定 nodeModulesDir
属性,以显式启用或禁用 Deno 使用 node_modules
目录。
{
"nodeModulesDir": true
}
如果您将 Deno 与 package.json 和 node_modules
目录一起使用,建议启用此设置,因为它将提供更好的体验。例如,启用它后,Deno 的语言服务器将使用本地 node_modules
目录进行缓存和解析包。
语言服务器改进
Deno 1.33 在语言服务器中引入了文档预加载,它在初始化时预加载工作区中的模块,以便 Deno 了解它们及其内容。
在某些情况下,默认的 1000 个文件系统条目限制要么太少要么太多,因此现在可以通过设置 deno.documentPreloadLimit
属性进行配置。
{
"deno.enable": true,
"deno.documentPreloadLimit": 2000
}
此外,语言服务器的内部 TypeScript 隔离的默认最大内存限制已增加到 3GB,以匹配 VS Code 中 TypeScript 的默认值。最后,可以在 VSCode 扩展中通过 deno.maxTsServerMemory
配置此限制
{
"deno.enable": true,
"deno.maxTsServerMemory": 3072
}
Deno API 更改
Deno.serve()
上个月,我们暗示我们计划稳定 Deno.serve()
API。然而,经过深思熟虑,我们决定将稳定推迟一个月,以便使这个 API 更具前向兼容性。
Deno.serve()
的签名已更改为返回 Deno.Server
的实例,而不是 Promise<void>
。Deno.Server
具有 finished
属性,它是一个 Promise
,当服务器关闭时(使用 AbortSignal
)解析。这为以编程方式控制服务器提供了更大的灵活性。
const ac = new AbortController();
const server = Deno.serve(
{ signal: ac.signal },
(_req) => new Response("Hello world"),
);
setTimeout(() => {
ac.abort();
}, 1000);
await server.finished;
console.log("Server has shut down");
此外,Deno.Server
具有 ref()
和 unref()
方法。您可以使用这些方法来控制服务器是否应保持进程处于活动状态。
Deno.createHttpClient()
此不稳定 API 现在公开了更多选项,允许对创建的客户端进行更精细的控制
const client = Deno.createHttpClient({
// Set maximum number of idle connections in the connection pool per host to 10.
poolMaxIdlePerHost: 10,
// Set a timeout for idle connection being kept alive to 10s. You can disable
// timeout all together by passing `false`.
poolIdleTimeout: 10_000,
// Configure if the client can use HTTP1.
http1: false,
// Configure if the client can use HTTP2.
http2: true,
});
const resp = await fetch("...", { client });
Deno.FileInfo
Deno.FileInfo
接口现在包含以下新的字段
Deno.FileInfo.isBlockDevice
Deno.FileInfo.isCharDevice
Deno.FileInfo.isFifo
Deno.FileInfo.isSocket
这些字段在 Linux 和 macOS 上可用。在 Windows 上,它们始终为 null
。
感谢 Hirotaka Tagawa 的贡献。
对 npm 和 Node 兼容性的改进
npm 支持还有一些值得注意的改进
deno vendor
处理 npm 指定符,并且在遇到它们时不再报错。deno task
在执行 package.json 文件中的脚本时,会运行pre
和post
脚本(如果存在),类似于 npm。感谢 Marvin Hagemeister 实现此功能。
我们还为一些内置的 Node.js API 提供了 polyfill
crypto.createDiffieHellman
crypto.createDiffieHellmanGroup
http.Server.unref
Module.runMain
performance.markResourceTiming
process.release
worker_threads
此外,以下 N-API 符号现在可以正常工作
napi_async_init
napi_async_destroy
napi_add_finalizer
V8 11.5 和 TypeScript 5.0.4
最后,Deno v1.34 附带 V8 11.5 和 TypeScript 5.0.4。
查看 Deno KV,我们的全球分布式数据库,用于 Deno Deploy,现已进入测试阶段