# @bylg/fetcher 中文文档

规范地址：https://npmcn.com/package/%40bylg/fetcher/

版本：0\.3\.3
npm 元数据更新时间：2026-11-03T18:48:21.504Z
中文译文更新时间：2026-11-08T21:28:51.854Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bylg/fetcher
原文对照：https://npmcn.com/package/%40bylg/fetcher/?lang=original
项目主页：https://github.com/Bailig/fetcher
源码仓库：https://github.com/Bailig/fetcher

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：23.9 kB，7 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：zod ^3\.20\.6 \|\| ^4\.0\.0
- 首次发布：2023-02-24T13:47:44.911Z
- 最新版本发布：2026-11-03T18:48:21.314Z
- 近 30 天下载量：2440（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：15（近 12 个月 1 个）

## 中文简介

一个小包裹 周围取和Zod。 它允许您预先定义标题和上下文,并有类型安全的反应.

## 安装

```sh
npm install @bylg/fetcher
```

也可以使用：`pnpm add @bylg/fetcher`、`yarn add @bylg/fetcher`、`bun add @bylg/fetcher`

## README

# BYLG 获取器

拜尔格 取取器是一个围绕取取取和Zod的小包裹. 它允许您预先定义标题和上下文,并有类型安全的反应.

一个FathererClient实例提供了两种方法,即取取取器和结合取取取器,分别用于定义取取取取器和结合取取取取器功能. 取取器功能可以是向远程服务器提出请求并返回打出响应的同步函数.

## 安装

```bash
npm install @bylg/fetcher
yarn add @bylg/fetcher
pnpm add @bylg/fetcher
```

Zod是一个同伴依赖,所以你也需要安装它.

```bash
npm install zod
yarn add zod
pnpm add zod
```

## 快速启动

您可以通过上下文和页眉来创建“ 获取者” 的新实例 。 然后可以使用取取器和结合取取取器方法分别定义和合并取取取器函数.

```ts
import { FetcherClient } from "@bylg/fetcher";
import { z } from "zod";

const f = new FetcherClient({
  ctx: z.string().url(), // Define the context schema
  headers: {
    Authorization: z.string().min(1), // Define the headers schema
  },
});

// Define a fetcher function
const getTodo = f.fetcher(({ ctx, headers, get, post }, id: string) => {
  const url = `${ctx}/todos/${id}`; // Use the context
  const schema = z.string(); // Define the response schema
  const options = {}; // Define the request options. Headers are automatically added.
  return get(url, schema, options);
});

// Define a fetcher function
const createTodo = f.fetcher(({ ctx, post }, content: string) => {
  const url = `${ctx}/todos`; // Use the context
  const schema = z.object({
    id: z.string(),
    content: z.string(),
  }); // Define the response schema
  const data = { content }; // Define the data to be sent in the request body
  const options = {}; // Define the request options. Headers are automatically added.
  return post(url, schema, data, options);
});

// Combine the fetcher functions
const createTodoFetcher = f.combineFetchers({
  getTodo,
  createTodo,
});

// Define the context and headers
// Alternatively, you can use a function that returns the context and headers
const todoFetcher = createTodoFetcher({
  ctx: "https://example.com", // The type of ctx is inferred from the context schema
  headers: { Authorization: "some-token" }, // The type of headers is inferred from the headers schema
});

// Call the fetcher functions
const todo = await todoFetcher.getTodo("1");
//                                 ^?  (property) getTodo: (input: string) => Promise<string>
const newTodo = await todoFetcher.createTodo({ content: "test" });
//                                   ^?  (property) createTodo: (input: string) => Promise<{ id: string; content: string; }>
```

上面的代码定义上下文和头图案,并创建 `FetcherClient` 和他们在一起 使用 `fetcher` 方法,然后使用 `combineFetchers` 方法.

现在您可以在 React 查询中使用 :

```ts
import { useQuery } from "react-query";
import { todoFetcher } from "path/to/todoFetcher";

const Todo = ({ id }) => {
  const { data, isLoading, error } = useQuery(["todo", id], () =>
    todoFetcher.getTodo(id)
  );

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return <div>{data}</div>;
};
```

```ts
import { useMutation } from "react-query";
import { todoFetcher } from "path/to/todoFetcher";

const TodoForm = () => {
  const [content, setContent] = useState("");
  const { mutate, isLoading, error } = useMutation(todoFetcher.createTodo);

  const handleSubmit = () => {
    e.preventDefault();
    mutate({ content });
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (
    <form onSubmit={handleSubmit}>
      <input value={content} onChange={(e) => setContent(e.target.value)} />
      <button type="submit">Create</button>
    </form>
  );
};
```

## 使用 `postProcess` 以刷新符号

```ts
const f = new FetcherClient({
  ctx: z.object({
    url: z.string().url(),
    refreshToken: z.string(),
  }),
  headers: {
    Authorization: z.string().min(1),
  },
});

const getTodo = f.fetcher(async ({ ctx, get }, id: string) => {
  const { data, response } = await get(
    `${ctx.url}/todos/${id}`,
    z.union([z.object({ code: z.string() }), z.string()])
  );
  if (
    response.status === 401 &&
    typeof data === "object" &&
    "code" in data &&
    data.code === "token-expired"
  ) {
    // throw error to trigger onError
    throw new Error(data.code);
  }
  return { data, response };
});

const createFetchers = f.combineFetchers({
  getTodo,
});

let token = "old-token";
const refreshTokensRetryCounts = new Map<string, number>();

const fetchers = createFetchers(() => ({
  ctx: { url: "https://example.com", refreshToken: "refresh-token" },
  headers: { Authorization: token },
  postProcess: {
    // when your fetcher throw an error, it will call this function with the error and original fetcher function and input
    onError: async ({ options, input, error, fetcher, fetcherName }) => {
      if (refreshTokensRetryCounts.get(fetcherName) === 2) {
        throw new Error(`Refresh token failed when calling: ${fetcherName}`);
      }
      // if the error is token expired, we will refresh the token and retry the original fetcher
      if (error instanceof Error && error.message === "token-expired") {
        refreshTokensRetryCounts.set(
          fetcherName,
          (refreshTokensRetryCounts.get(fetcherName) ?? 0) + 1
        );
        // get new token and update token
        token = await refreshTokens(options.ctx.refreshToken);
        await fetcher(options, input as any);
      }
      return;
    },
  },
}));

await fetchers.getTodo("1");
```

## 常见问题

### @bylg/fetcher 是什么？

一个小包裹 周围取和Zod。 它允许您预先定义标题和上下文,并有类型安全的反应\.

### 如何安装 @bylg/fetcher？

在项目目录运行 npm install @bylg/fetcher，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：zod（^3\.20\.6 \|\| ^4\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @bylg/fetcher 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @bylg/fetcher 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @bylg/fetcher 可以商用吗？

@bylg/fetcher 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @bylg/fetcher 的下载量有多少？

根据 npm 官方下载统计，@bylg/fetcher 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,440 次，日均约 81 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bylg/fetcher 还在维护吗？

最新版本 0\.3\.3 发布于 2026/11/04（5 天前）；至今共发布 15 个版本，其中过去 12 个月发布了 1 个；首次发布于 2023/02/24。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

