写技术文章时,代码片段很容易变成孤立的证据。读者看见一个函数,却不知道它从哪里被调用;看见一个配置,却不知道它服务于哪条路径。代码本身没有错,但上下文丢了,理解成本就会被转移给读者。
更好的方式,是让文章里的代码像一个很小的项目一样被浏览。读者可以先看入口文件,再切到路由、缓存、说明文档。这样代码不是被拆碎展示,而是保留了结构。
下面这个内嵌代码浏览器展示了一个极小的请求处理流程。它没有依赖前端框架,只用 HTML 和 CSS 做文件切换。重点不是炫技,而是让一篇文章能同时承载解释和代码结构。
mini-service
src/main.ts
import { createServer } from "node:http";
import { routeRequest } from "./router";
const server = createServer(async (request, response) => {
const result = await routeRequest(request);
response.writeHead(result.status, {
"content-type": "application/json; charset=utf-8",
});
response.end(JSON.stringify(result.body));
});
server.listen(3000, () => {
console.log("mini-service listening on http://localhost:3000");
});
src/router.ts
import type { IncomingMessage } from "node:http";
import { remember, read } from "./cache";
type RouteResult = {
status: number;
body: Record<string, unknown>;
};
export async function routeRequest(
request: IncomingMessage,
): Promise<RouteResult> {
if (request.url === "/health") {
return { status: 200, body: { ok: true } };
}
if (request.url === "/visits") {
const visits = remember("visits", (read("visits") ?? 0) + 1);
return { status: 200, body: { visits } };
}
return { status: 404, body: { error: "not_found" } };
}
src/cache.ts
const store = new Map<string, number>();
export function read(key: string): number | undefined {
return store.get(key);
}
export function remember(key: string, value: number): number {
store.set(key, value);
return value;
}
export function clear(): void {
store.clear();
}
README.md
# mini-service
一个用于文章演示的小服务。
## 路由
- GET /health 返回健康检查结果
- GET /visits 返回累计访问次数
## 为什么拆成三个文件
入口文件只负责启动服务。
router 负责描述行为。
cache 负责隐藏状态细节。
这种展示方式适合三类内容。
- 需要解释多文件协作的小功能。
- 需要让读者比较几个实现版本的文章。
- 需要展示配置、入口、测试之间关系的教程。
它也有边界。文章里的代码浏览器应该保持小而完整,不要把整套项目塞进去。真正的大项目更适合链接到仓库;博客里只保留最能解释观点的切片。
我会把它当成一种写作工具:当一个片段已经解释不清楚结构时,就给读者一个可以切换文件的上下文。