写技术文章时,代码片段很容易变成孤立的证据。读者看见一个函数,却不知道它从哪里被调用;看见一个配置,却不知道它服务于哪条路径。代码本身没有错,但上下文丢了,理解成本就会被转移给读者。

更好的方式,是让文章里的代码像一个很小的项目一样被浏览。读者可以先看入口文件,再切到路由、缓存、说明文档。这样代码不是被拆碎展示,而是保留了结构。

下面这个内嵌代码浏览器展示了一个极小的请求处理流程。它没有依赖前端框架,只用 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 负责隐藏状态细节。

这种展示方式适合三类内容。

  • 需要解释多文件协作的小功能。
  • 需要让读者比较几个实现版本的文章。
  • 需要展示配置、入口、测试之间关系的教程。

它也有边界。文章里的代码浏览器应该保持小而完整,不要把整套项目塞进去。真正的大项目更适合链接到仓库;博客里只保留最能解释观点的切片。

我会把它当成一种写作工具:当一个片段已经解释不清楚结构时,就给读者一个可以切换文件的上下文。