npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zero-bits/taro-request

v1.1.0

Published

Zero-Bits Taro Request Library

Readme

@zero-bits/taro-request

适用于 Taro 的请求库,提供两套方案:

  • OnionRequest — 基于洋葱模型的原生请求方案,直接调用 Taro.request,内置 Token 注入、无感刷新、业务异常拦截等中间件,零外部依赖
  • request / initializeRequest — 基于 @zero-bits/request(Axios)的方案,通过 taroAdapter 将 Axios 的请求转换为 Taro.request,适合已有 Axios 使用习惯的团队

安装

# npm
npm install @zero-bits/taro-request axios

# pnpm
pnpm add @zero-bits/taro-request axios

@tarojs/taro、axios、react 为 peerDependency,需在宿主项目中自行安装。

快速上手

方案一:OnionRequest(推荐)

import { createRequest, setupTaroEnvironment } from '@zero-bits/taro-request'

// 小程序环境需要在入口执行一次,补齐缺失的原生对象(如 AbortController)
setupTaroEnvironment()

const http = createRequest({
  baseURL: 'https://api.example.com',
  timeout: 15000,
  getAccessToken: () => getStoredToken(),
  isSuccess: (data) => data.code === 0,
  resolveData: (data) => data.result,
  onBizError: (err) => showToast(err.msg),
  onHttpError: (statusCode, err) => console.error(statusCode, err),
})

// GET
const user = await http.get<User>('/user/info')

// POST
const res = await http.post<LoginRes>('/auth/login', { username: 'admin', password: '123456' })

// 文件上传
const uploadRes = await http.upload('/file/upload', tempFilePath, { type: 'image' })

方案二:request / initializeRequest(Axios 方案)

import { initializeRequest, request, taroAdapter, defaultTransformRequest } from '@zero-bits/taro-request'

initializeRequest({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  adapter: taroAdapter,
  transformRequest: [defaultTransformRequest],
})

const user = await request.get<User>('/user/info')

OnionRequest

createRequest(config)

工厂函数,创建一个内置中间件链的 OnionRequest 实例。

内置中间件执行顺序:

requestInterceptors(用户前置)
  → logMiddleware(耗时日志)
    → authMiddleware(Token 注入 + 无感刷新)
      → bizMiddleware(HTTP 状态码 + 业务异常 + 数据提纯)
        → responseInterceptors(用户后置)
          → 真实网络请求 (Taro.request)

RequestConfig

| 属性 | 类型 | 说明 | |------|------|------| | baseURL | string | 接口根地址前缀 | | header | Record<string, string> | 全局请求头 | | timeout | number | 超时时间(ms),默认 15000 | | getAccessToken | () => string \| undefined | 获取当前 Access Token | | authHeaderKey | string | 鉴权请求头 Key,默认 Authorization | | formatAuthValue | (token: string) => string | 格式化 Token 值,默认 Bearer <token> | | skipAuth | (req) => boolean | 返回 true 时跳过 Token 注入 | | refreshToken | 见下表 | 无感刷新配置 | | isSuccess | (data) => boolean | 判断业务是否成功 | | resolveData | (data) => any | 提取业务数据(成功时) | | onBizError | (err) => void | 业务异常全局回调 | | onHttpError | (statusCode, err) => void | HTTP 异常全局回调 | | requestInterceptors | Middleware[] | 用户前置中间件 | | responseInterceptors | Middleware[] | 用户后置中间件 | | middlewares | Middleware[] | 额外注入的自定义中间件 |

refreshToken 配置

| 属性 | 类型 | 说明 | |------|------|------| | url | string | 刷新 Token 的接口地址(相对 baseURL) | | method | string | 请求方法,默认 POST | | data | () => Record<string, any> | 请求 Body 参数 | | params | () => Record<string, any> | Query 参数 | | header | Record<string, string> | 额外请求头 | | resolveToken | (res) => string \| undefined | 从响应中解析新 Token | | onRefreshed | (res) => void \| Promise<void> | 刷新成功回调(通常用于持久化新 Token) | | onRefreshFailed | (err) => void | 刷新失败回调(通常用于跳转登录页) |

OnionRequest 实例方法

| 方法 | 说明 | |------|------| | request<T>(options) | 发起请求,返回 AbortablePromise<T> | | get<T>(url, data?, options?) | GET 请求 | | post<T>(url, data?, options?) | POST 请求 | | put<T>(url, data?, options?) | PUT 请求 | | delete<T>(url, data?, options?) | DELETE 请求 | | upload<T>(url, filePath, data?, options?) | 文件上传(自动转换为 multipart/form-data) | | use(middleware) | 手动注册中间件 |

所有方法返回的 AbortablePromise<T> 都支持 .abort() 主动取消请求:

const promise = http.get('/list')
promise.abort() // 立即取消

自定义中间件

中间件签名与 Koa 一致:

import type { Middleware } from '@zero-bits/taro-request'

const timingMiddleware: Middleware = async (ctx, next) => {
  const start = Date.now()
  await next()
  console.log(`耗时 ${Date.now() - start}ms`, ctx.req.url)
}

const http = createRequest({
  baseURL: 'https://api.example.com',
  requestInterceptors: [timingMiddleware],
})

RequestContext

中间件中可读写的上下文对象:

| 属性 | 类型 | 说明 | |------|------|------| | req | Taro.request.Option | 请求参数,可在中间件中修改 | | res | Taro.request.SuccessCallbackResult | 响应结果,请求完成后可读 | | error | any | 错误信息 | | state | Record<string, any> | 中间件间共享的数据沙盒 | | state.task | Taro.RequestTask \| Taro.UploadTask | 底层请求任务实例 | | state.abortSignal | boolean | 是否已发出取消信号 | | request | (options) => Promise<any> | 重新发起请求(用于 retry 场景) |


taroAdapter(Axios 方案)

将 Axios 请求桥接到 Taro.request,支持:

  • 普通 JSON 请求
  • arraybuffer 二进制响应
  • 文件上传(multipart/form-data,payload 中需含 filePath 和 name)
  • Axios 的 cancelToken 和 signal 取消机制
import axios from 'axios'
import { taroAdapter, defaultTransformRequest } from '@zero-bits/taro-request'

const instance = axios.create({
  baseURL: 'https://api.example.com',
  adapter: taroAdapter,
  transformRequest: [defaultTransformRequest],
})

defaultTransformRequest

替代 Axios 默认的序列化逻辑,兼容小程序环境:

  • 普通对象 / 数组 → JSON.stringify(自动设置 Content-Type: application/json)
  • application/x-www-form-urlencoded → 原样透传(由小程序底层处理)
  • FormData / ArrayBuffer / Blob / File → 原样透传,不做序列化

setupTaroEnvironment

在小程序入口(app.ts)调用一次,补齐缺失的 AbortController 全局对象,防止部分上游库在小程序环境报错。

import { setupTaroEnvironment } from '@zero-bits/taro-request'

setupTaroEnvironment()

错误处理

AbortError

主动调用 .abort() 时抛出,可用于区分业务错误与用户取消:

import { AbortError } from '@zero-bits/taro-request'

try {
  await http.get('/list')
} catch (err) {
  if (err instanceof AbortError) {
    console.log('请求已取消')
  } else {
    console.error('请求失败', err)
  }
}

错误类型说明

| 错误 | 标志 | 说明 | |------|------|------| | HTTP 错误 | err.isHttpError === true | 状态码 < 200 或 ≥ 300 | | 业务错误 | err.isBizError === true | isSuccess 返回 false | | 取消错误 | err instanceof AbortError | 主动调用 .abort() |


无感刷新完整示例

import { createRequest, setupTaroEnvironment } from '@zero-bits/taro-request'
import Taro from '@tarojs/taro'

setupTaroEnvironment()

const http = createRequest({
  baseURL: 'https://api.example.com',
  timeout: 15000,
  getAccessToken: () => Taro.getStorageSync('accessToken'),
  isSuccess: (data) => data.code === 0,
  resolveData: (data) => data.data,
  onBizError: (err) => Taro.showToast({ title: err.msg || '请求失败', icon: 'none' }),
  refreshToken: {
    url: '/auth/refresh',
    method: 'POST',
    data: () => ({ refreshToken: Taro.getStorageSync('refreshToken') }),
    resolveToken: (res) => res.data?.accessToken,
    onRefreshed: (res) => {
      Taro.setStorageSync('accessToken', res.data.accessToken)
      Taro.setStorageSync('refreshToken', res.data.refreshToken)
    },
    onRefreshFailed: () => {
      Taro.clearStorageSync()
      Taro.reLaunch({ url: '/pages/login/index' })
    },
  },
})

export default http

依赖版本

| 依赖 | 版本要求 | |------|----------| | react | >=18.0.0 | | @tarojs/taro | >=4.2.1 | | axios | >=1.19.0 |

License

MIT