第 07 章:标准库
第 07 章:标准库
7.1 标准库概述
Deno 标准库(@std)是一组经过审核、测试完善的官方模块,可通过 JSR 或 deno.land 引入。
标准库模块一览
| 模块 | 说明 | 导入方式 |
|---|---|---|
@std/path | 路径操作 | jsr:@std/path |
@std/fs | 文件系统操作 | jsr:@std/fs |
@std/http | HTTP 服务器 | jsr:@std/http |
@std/fmt | 格式化输出(颜色等) | jsr:@std/fmt |
@std/flags | 命令行参数解析 | jsr:@std/flags |
@std/async | 异步工具 | jsr:@std/async |
@std/json | JSON 工具 | jsr:@std/json |
@std/encoding | 编码/解码 | jsr:@std/encoding |
@std/assert | 断言工具 | jsr:@std/assert |
@std/collections | 集合操作 | jsr:@std/collections |
@std/log | 日志系统 | jsr:@std/log |
@std/yaml | YAML 解析 | jsr:@std/yaml |
@std/toml | TOML 解析 | jsr:@std/toml |
@std/csv | CSV 解析 | jsr:@std/csv |
@std/media-types | MIME 类型 | jsr:@std/media-types |
@std/uuid | UUID 生成 | jsr:@std/uuid |
@std/crypto | 加密工具 | jsr:@std/crypto |
7.2 @std/path — 路径操作
路径操作是最常用的模块之一,跨平台处理文件路径。
常用函数
import { join, resolve, basename, dirname, extname, normalize, relative, isAbsolute } from "jsr:@std/path";
// 路径拼接
console.log(join("/home", "user", "docs")); // /home/user/docs
console.log(join("/home/user", "../etc", "hosts")); // /home/etc/hosts
// 获取绝对路径
console.log(resolve("src", "main.ts")); // /current/dir/src/main.ts
// 获取文件名
console.log.basename("/home/user/file.ts")); // file.ts
// 获取目录名
console.log.dirname("/home/user/file.ts")); // /home/user
// 获取扩展名
console.log(extname("file.ts")); // .ts
console.log(extname("file.tar.gz")); // .gz
// 路径规范化
console.log(normalize("/home//user/../etc/./hosts")); // /home/etc/hosts
// 相对路径
console.log(relative("/home/user", "/home/user/docs/file.ts")); // docs/file.ts
// 判断绝对路径
console.log(isAbsolute("/home/user")); // true
console.log.isAbsolute("relative/path")); // false
POSIX 与 Windows 路径
import { posix, windows } from "jsr:@std/path";
// 显式使用 POSIX 路径(Linux/macOS)
console.log(posix.join("/home", "user")); // /home/user
// 显式使用 Windows 路径
console.log.windows.join("C:\\Users", "user")); // C:\Users\user
7.3 @std/fs — 文件系统
文件操作
import { ensureDir, ensureFile, exists, copy, move, emptyDir, walk } from "jsr:@std/fs";
import { readTextFile, writeTextFile } from "jsr:@std/io";
// 检查文件是否存在
if (await exists("./config.json")) {
console.log("配置文件存在");
}
// 确保文件存在(不存在则创建)
await ensureFile("./data/records.json");
// 确保目录存在(不存在则创建)
await ensureDir("./data/logs");
// 复制文件
await copy("./source.txt", "./dest.txt");
await copy("./src-dir", "./dest-dir", { overwrite: true });
// 移动/重命名
await move("./old-name.ts", "./new-name.ts");
// 清空目录
await emptyDir("./tmp");
遍历目录
import { walk } from "jsr:@std/fs";
// 遍历所有文件
for await (const entry of walk("./src")) {
console.log(entry.path, entry.isFile ? "文件" : "目录");
}
// 过滤文件类型
for await (const entry of walk("./src", { exts: [".ts", ".tsx"] })) {
console.log("TypeScript 文件:", entry.path);
}
// 限制深度
for await (const entry of walk("./src", { maxDepth: 2 })) {
console.log(entry.path);
}
// 排除目录
for await (const entry of walk("./src", { skip: [/node_modules/, /\.git/] })) {
console.log(entry.path);
}
7.4 @std/http — HTTP 服务器
import { serve } from "jsr:@std/http";
// 简单的 HTTP 服务器
serve((req: Request) => {
const url = new URL(req.url);
if (url.pathname === "/") {
return new Response("Hello, Deno!", {
headers: { "content-type": "text/plain; charset=utf-8" },
});
}
if (url.pathname === "/json") {
return Response.json({ message: "Hello", time: new Date().toISOString() });
}
return new Response("Not Found", { status: 404 });
}, { port: 8000 });
console.log("服务器运行在 http://localhost:8000");
7.5 @std/fmt — 格式化输出
终端颜色
import { bold, red, green, yellow, blue, bgRed, bgGreen } from "jsr:@std/fmt/colors";
console.log(bold("粗体文本"));
console.log(red("红色文本"));
console.log(green("绿色文本"));
console.log(yellow("黄色文本"));
console.log(blue("蓝色文本"));
console.log(bgRed(red("红底红字")));
console.log(bold(green("粗体绿色")));
// 组合使用
console.log(bold(red("错误:")) + " 文件不存在");
console.log(bold(green("成功:")) + " 任务完成");
表格输出
import { Table } from "jsr:@std/cli/unstable-table";
const table = new Table([
["名称", "年龄", "城市"],
["Alice", "30", "北京"],
["Bob", "25", "上海"],
["Charlie", "35", "深圳"],
]);
console.log(table.toString());
// ┌─────────┬──────┬──────┐
// │ 名称 │ 年龄 │ 城市 │
// ├─────────┼──────┼──────┤
// │ Alice │ 30 │ 北京 │
// │ Bob │ 25 │ 上海 │
// │ Charlie │ 35 │ 深圳 │
// └─────────┴──────┴──────┘
7.6 @std/flags — 命令行参数解析
import { parseArgs } from "jsr:@std/cli/parse-args";
// 解析命令行参数
const args = parseArgs(Deno.args, {
boolean: ["help", "version", "verbose"],
string: ["output", "config"],
default: { output: "out.json", verbose: false },
alias: { h: "help", v: "version", o: "output" },
});
// 运行:deno run script.ts --help --output=result.json --verbose
console.log(args);
// {
// help: true,
// version: false,
// verbose: true,
// output: "result.json",
// config: undefined,
// _: []
// }
CLI 工具实战
import { parseArgs } from "jsr:@std/cli/parse-args";
const args = parseArgs(Deno.args, {
boolean: ["help"],
string: ["format"],
default: { format: "json" },
alias: { h: "help" },
});
if (args.help) {
console.log(`
用法:tool [选项] <文件>
选项:
-h, --help 显示帮助
--format <格式> 输出格式(json/csv/text)
示例:
tool --format csv data.txt
`);
Deno.exit(0);
}
console.log(`处理文件:${args._[0]},格式:${args.format}`);
7.7 @std/async — 异步工具
常用工具
import { delay, deadline, debounce, retry, pooled } from "jsr:@std/async";
// 延迟
await delay(1000); // 等待 1 秒
// 设置超时
const data = await deadline(fetch("https://api.example.com"), 5000);
// 如果 5 秒内未完成,抛出 TimeoutError
// 防抖
const debouncedLog = debounce((msg: string) => {
console.log(msg);
}, 300);
debouncedLog("hello");
debouncedLog("world"); // 只会执行这次
// 重试
const result = await retry(async () => {
const res = await fetch("https://api.example.com/data");
if (!res.ok) throw new Error("请求失败");
return res.json();
}, { maxAttempts: 3, delay: 1000 });
Pool — 并发控制
import { pooled } from "jsr:@std/async";
const urls = [
"https://api.example.com/1",
"https://api.example.com/2",
"https://api.example.com/3",
"https://api.example.com/4",
"https://api.example.com/5",
];
// 最多同时 3 个请求
const results = await pooled(
urls.map(url => () => fetch(url).then(r => r.json())),
{ concurrency: 3 }
);
console.log(results);
7.8 @std/encoding — 编码工具
import { encodeBase64, decodeBase64 } from "jsr:@std/encoding/base64";
import { encodeHex, decodeHex } from "jsr:@std/encoding/hex";
// Base64 编码/解码
const encoded = encodeBase64("Hello, Deno!");
console.log(encoded); // SGVsbG8sIERlbm8h
const decoded = new TextDecoder().decode(decodeBase64(encoded));
console.log(decoded); // Hello, Deno!
// Hex 编码/解码
const hex = encodeHex(new TextEncoder().encode("Hello"));
console.log(hex); // 48656c6c6f
7.9 @std/collections — 集合操作
import { distinct, chunk, groupBy, sortBy, intersection, difference } from "jsr:@std/collections";
// 去重
console.log(distinct([1, 2, 2, 3, 3, 3])); // [1, 2, 3]
// 分块
console.log(chunk([1, 2, 3, 4, 5], 2)); // [[1, 2], [3, 4], [5]]
// 分组
const users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "user" },
{ name: "Charlie", role: "admin" },
];
const grouped = groupBy(users, (u) => u.role);
// { admin: [{...}, {...}], user: [{...}] }
// 排序
const sorted = sortBy([3, 1, 4, 1, 5], (n) => n);
console.log(sorted); // [1, 1, 3, 4, 5]
// 交集
console.log(intersection([1, 2, 3], [2, 3, 4])); // [2, 3]
// 差集
console.log(difference([1, 2, 3], [2, 3, 4])); // [1]
7.10 @std/jsonc 与 @std/yaml
JSONC(带注释的 JSON)
import { parse } from "jsr:@std/jsonc";
const jsonc = `
{
// 这是注释
"name": "my-app",
"version": "1.0.0" // 行尾注释
}
`;
const config = parse(jsonc);
console.log(config); // { name: "my-app", version: "1.0.0" }
YAML
import { parse, stringify } from "jsr:@std/yaml";
// 解析 YAML
const yamlText = `
server:
host: localhost
port: 8000
database:
url: postgres://localhost:5432/mydb
`;
const config = parse(yamlText);
console.log(config.server.port); // 8000
// 生成 YAML
const data = { name: "test", items: [1, 2, 3] };
console.log(stringify(data));
// name: test
// items:
// - 1
// - 2
// - 3
7.11 标准库版本管理
使用导入映射
// deno.json
{
"imports": {
"@std/path": "jsr:@std/path@^0.224",
"@std/fs": "jsr:@std/fs@^0.224",
"@std/http": "jsr:@std/http@^0.224",
"@std/fmt": "jsr:@std/fmt@^0.224",
"@std/async": "jsr:@std/async@^0.224",
"@std/assert": "jsr:@std/assert@^0.224"
}
}
// 使用导入映射后的简洁写法
import { join } from "@std/path";
import { serve } from "@std/http";
import { bold, red } from "@std/fmt/colors";
7.12 本章小结
| 模块 | 核心功能 | 最常用场景 |
|---|---|---|
@std/path | 路径操作 | 跨平台文件路径处理 |
@std/fs | 文件系统 | 目录创建、文件遍历 |
@std/http | HTTP 服务器 | 快速搭建 API 服务 |
@std/fmt | 格式化 | 终端彩色输出 |
@std/flags | 参数解析 | CLI 工具开发 |
@std/async | 异步工具 | 超时、重试、防抖 |
@std/encoding | 编码 | Base64、Hex |
@std/collections | 集合操作 | 去重、分组、排序 |
📖 扩展阅读
下一章:第 08 章:Web API → 了解 Deno 内置的 Web 标准 API。