强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 07 章:标准库

第 07 章:标准库

7.1 标准库概述

Deno 标准库(@std)是一组经过审核、测试完善的官方模块,可通过 JSR 或 deno.land 引入。

标准库模块一览

模块说明导入方式
@std/path路径操作jsr:@std/path
@std/fs文件系统操作jsr:@std/fs
@std/httpHTTP 服务器jsr:@std/http
@std/fmt格式化输出(颜色等)jsr:@std/fmt
@std/flags命令行参数解析jsr:@std/flags
@std/async异步工具jsr:@std/async
@std/jsonJSON 工具jsr:@std/json
@std/encoding编码/解码jsr:@std/encoding
@std/assert断言工具jsr:@std/assert
@std/collections集合操作jsr:@std/collections
@std/log日志系统jsr:@std/log
@std/yamlYAML 解析jsr:@std/yaml
@std/tomlTOML 解析jsr:@std/toml
@std/csvCSV 解析jsr:@std/csv
@std/media-typesMIME 类型jsr:@std/media-types
@std/uuidUUID 生成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/httpHTTP 服务器快速搭建 API 服务
@std/fmt格式化终端彩色输出
@std/flags参数解析CLI 工具开发
@std/async异步工具超时、重试、防抖
@std/encoding编码Base64、Hex
@std/collections集合操作去重、分组、排序

📖 扩展阅读


下一章第 08 章:Web API → 了解 Deno 内置的 Web 标准 API。