@std 标准库
Deno 官方维护的标准库发布在 JSR 上,以 @std/ 命名空间组织,涵盖文件操作、HTTP、加密、测试、格式化等常用功能,所有模块均有完整类型定义和稳定版本号:
| 包名 | 功能 | 常用导出 |
|---|---|---|
@std/path | 路径操作 | join, resolve, extname, basename |
@std/fs | 文件系统 | walk, ensureDir, copy, exists |
@std/http | HTTP 工具 | serveDir, serveFile, STATUS_CODE |
@std/crypto | 加密工具 | toHashString, crypto |
@std/assert | 断言(测试用) | assertEquals, assertThrows |
@std/testing | 测试工具 | describe, it, beforeAll |
@std/datetime | 日期时间 | format, parse, dayOfYear |
@std/csv | CSV 解析 | parse, stringify |
@std/encoding | 编解码 | encodeBase64, decodeBase64 |
@std/collections | 集合工具 | groupBy, chunk, distinct |
@std/path — 路径操作
import { join, resolve, extname, basename, dirname } from "jsr:@std/path";
// 跨平台路径拼接
const fullPath = join("/home/user", "projects", "app.ts");
// "/home/user/projects/app.ts"
console.log(extname("app.ts")); // ".ts"
console.log(basename("/foo/bar.ts")); // "bar.ts"
console.log(dirname("/foo/bar.ts")); // "/foo"
// 获取当前文件目录(ESM 中 __dirname 不可用)
const __dirname = dirname(new URL(import.meta.url).pathname);
@std/fs — 文件系统操作
import { walk, ensureDir, copy, exists } from "jsr:@std/fs";
// 确保目录存在(不存在则创建)
await ensureDir("./output/reports");
// 检查文件/目录是否存在
if (await exists("./config.json")) {
console.log("配置文件存在");
}
// 递归遍历目录(walk 返回 AsyncGenerator)
for await (const entry of walk("./src", { exts: [".ts"] })) {
if (entry.isFile) {
console.log(entry.path);
}
}
// 复制文件
await copy("./src/template.html", "./dist/index.html");
Web 标准 API:fetch
Deno 实现了与浏览器完全兼容的 fetch API,包括完整的 Request、Response、Headers 对象:
// 基本 GET 请求
const res = await fetch("https://api.example.com/data");
const json = await res.json();
// POST 请求,携带 JSON body 和自定义 Headers
const response = await fetch("https://api.example.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
},
body: JSON.stringify({ name: "Alice", email: "alice@example.com" }),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const user = await response.json();
// Request 对象
const req = new Request("https://api.example.com/data", {
method: "GET",
headers: new Headers({ "X-Custom": "value" }),
});
const res2 = await fetch(req);
Web Streams API
Deno 完整实现了 WHATWG Web Streams API,支持流式数据处理,无需将大文件全部载入内存:
// 流式下载大文件
const response = await fetch("https://example.com/large-file.zip");
if (response.body) {
const reader = response.body.getReader();
let bytesReceived = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;
bytesReceived += value.length;
console.log(`已接收: ${bytesReceived} 字节`);
}
}
// 使用 TransformStream 处理流
const { readable, writable } = new TransformStream({
transform(chunk, controller) {
// 将每个字节转为大写(假设是文本)
controller.enqueue(chunk.map((b: number) => b >= 97 && b <= 122 ? b - 32 : b));
}
});
// 链式管道
response.body?.pipeTo(writable);
Crypto API(SubtleCrypto)
Deno 实现了 Web Crypto API,提供加密、哈希、签名等功能,与浏览器中的 crypto.subtle 完全兼容:
// SHA-256 哈希
async function sha256(message: string): Promise<string> {
const encoder = new TextEncoder();
const data = encoder.encode(message);
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
}
console.log(await sha256("Hello Deno"));
// 生成 HMAC 签名
async function signHMAC(key: string, message: string): Promise<string> {
const enc = new TextEncoder();
const cryptoKey = await crypto.subtle.importKey(
"raw", enc.encode(key),
{ name: "HMAC", hash: "SHA-256" },
false, ["sign"]
);
const sig = await crypto.subtle.sign("HMAC", cryptoKey, enc.encode(message));
return Array.from(new Uint8Array(sig))
.map(b => b.toString(16).padStart(2, "0")).join("");
}
// 生成加密随机 UUID
const id = crypto.randomUUID(); // "550e8400-e29b-41d4-a716-446655440000"
// 生成安全随机字节
const bytes = new Uint8Array(32);
crypto.getRandomValues(bytes);
URL 与 URLSearchParams
// URL 解析
const url = new URL("https://api.example.com/users?page=2&limit=10");
console.log(url.hostname); // "api.example.com"
console.log(url.pathname); // "/users"
console.log(url.searchParams.get("page")); // "2"
console.log(url.searchParams.get("limit")); // "10"
// 构建查询字符串
const params = new URLSearchParams({
q: "deno tutorial",
lang: "zh",
page: "1",
});
console.log(params.toString());
// "q=deno+tutorial&lang=zh&page=1"
const apiUrl = `https://api.example.com/search?${params}`;
实战:纯 Web API 构建 HTTP 客户端
使用 Deno 原生 Web API 构建一个完整的、有重试逻辑的 HTTP 客户端,无需任何第三方库:
// http-client.ts — 纯 Web API HTTP 客户端
interface RequestOptions {
method?: string;
headers?: Record<string, string>;
body?: unknown;
retries?: number;
timeout?: number; // ms
}
async function request<T>(url: string, opts: RequestOptions = {}): Promise<T> {
const { method = "GET", headers = {}, body, retries = 3, timeout = 10000 } = opts;
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeout);
for (let i = 0; i < retries; i++) {
try {
const res = await fetch(url, {
method,
headers: { "Content-Type": "application/json", ...headers },
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal,
});
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
}
clearTimeout(timer);
return await res.json() as T;
} catch (err) {
if (i === retries - 1) throw err;
// 指数退避:1s, 2s, 4s...
await new Promise(r => setTimeout(r, 1000 * 2 ** i));
}
}
throw new Error("Unreachable");
}
// 使用示例
interface User { id: number; name: string; email: string; }
const users = await request<User[]>("https://jsonplaceholder.typicode.com/users");
console.log(users[0].name);
// deno run --allow-net http-client.ts
本章小结:Deno 对 Web API 标准的完整实现是其最大亮点之一。fetch、Streams、Crypto、URL 这些在浏览器中熟悉的 API,在 Deno 中无需任何 polyfill 即可直接使用。这意味着大量前端逻辑可以直接在 Deno 中复用,前后端代码共享成为现实。@std 标准库则提供了文件、路径、CSV 等服务端常用功能,整洁稳定,有完整类型定义。