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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@vft/request

v0.0.50

Published

自定义项目的 `request`

Readme

使用

自定义项目的 request

import {
  ContentTypeEnum,
  createAxios,
  RequestEnum,
  type RequestOptions,
} from '@ky/request';
import { AxiosResponse, InternalAxiosRequestConfig } from 'axios';

const { VITE_API_BASE_URL } = import.meta.env;

export interface ResponseProps {
  retCode: string;
  retMsg: string;
  [key: string]: any;
}

const request = createAxios({
  timeout: 15 * 1000,
  transform: {
    requestInterceptors: config => {
      config.params = {
        ...config.params,
        id: VITE_APP_ID,
      };

      return config as InternalAxiosRequestConfig<any>;
    },
    transformResponseHook: (res: AxiosResponse) => {
      // 当接口都没有返回 data 字段信息时,直接报错
      if (!res.data) {
        throw new Error('系统错误');
      }

      return res.data;
    },
  },
  requestOptions: {
    apiUrl: VITE_API_BASE_URL,
    joinTime: false,
    withToken: false,
  },
});

requestOptions 相关定义类型如下

export interface RequestOptions {
  /** 将请求参数拼接到url */
  joinParamsToUrl?: boolean;
  /** 格式化请求参数时间 */
  formatDate?: boolean;
  /** 是否处理请求结果 */
  isTransformResponse?: boolean;
  /** 是否返回原生响应头 比如:需要获取响应头时使用该属性 */
  isReturnNativeResponse?: boolean;
  /** 公共的接口请求地址 */
  apiUrl?: string | (() => string);
  /** 请求拼接路径 */
  urlPrefix?: string;
  /** 是否添加时间戳 */
  joinTime?: boolean;
  /** 是否忽略重复请求(两次同样的请求,如果第二次比第一次请求的快,则将第一次的请求取消) */
  ignoreCancelToken?: boolean;
  /** 是否需要携带 token */
  withToken?: boolean;
  // 请求重试机制
  retryRequest?: RetryRequest;
  /** 报错信息是否自定义 */
  errorMessageCustom?: boolean;
  /** token 请求头 */
  authenticationScheme?: string;
  /** token key 值 */
  tokenKey?: string;
  /** 自定义请求成功数据字段名称 */
  responseParams?: {
    /** 接口对应 code 字段名称 */
    code?: string;
    /** 接口对应 message 字段名称 */
    message?: string;
    /** 接口对应数据字段名称 */
    data?: string;
    /** 接口对应成功的返回码 */
    successCode?: string | number;
    /** 接口数据是和 code message 平铺在一个层级的 */
    dataIsTile?: boolean;
  };
  /** 错误处理方式 */
  errorFunction?: AnyFunction<any>;
  /** 获取 token 的方法 */
  getTokenFunction?: () => unknown;
  /** 没有权限的方法 */
  unauthorizedFunction?: (msg?: string) => void;
  /** 增加jsonp 适配 */
  jsonpAdapter?: boolean | JsonpConfig;
}

export type JsonpConfig = {
  /** jsonp 的 */
  callbackParamName?: string;
  callbackFunctionName?: string;
};

export interface RetryRequest {
  /** 是否开启接口重试 */
  isOpenRetry: boolean;
  /** 重试次数 */
  count: number;
  /** 重试等待时间 */
  waitTime: number;
}

自定义 transform

export abstract class AxiosTransform {
  /**
   * @description请求之前进行流程配置
   */
  beforeRequestHook?: (
    config: AxiosRequestConfig,
    options: RequestOptions,
  ) => AxiosRequestConfig;

  /**
   * @description 请求已成功处理
   */
  transformResponseHook?: (
    res: AxiosResponse & any,
    options: RequestOptions,
  ) => any;

  /**
   * @description 请求失败处理
   */
  requestCatchHook?: (e: Error, options: RequestOptions) => Promise<any>;

  /**
   * @description 请求之前的拦截器
   */
  requestInterceptors?: (
    config: AxiosRequestConfig,
    options: AxiosRequestConfig,
  ) => InternalAxiosRequestConfig<any>;

  /**
   * @description 请求之后的拦截器
   */
  responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>;

  /**
   * @description 请求之前的拦截器错误处理
   */
  requestInterceptorsCatch?: (error: Error) => void;

  /**
   * @description: 请求之后的拦截器错误处理
   */
  responseInterceptorsCatch?: (
    axiosInstance: AxiosInstance,
    error: Error,
  ) => void;
}

如何定义

import { request } from '@/apis';
import { objAddPrefix } from '@vft/utils';

const prefixUrl = '';

const Api = {
  table: '/table',
  common: '/common',
};

interface TableProps {
  page: number;
  pageSize?: number;
}

objAddPrefix(Api, prefixUrl);

/** 表格测试 */
export const getTableData = (params: TableProps) =>
  request.get({
    url: Api.table,
    params,
  });

export const commonTestApi = () =>
  request.get({
    url: Api.common,
  });

如何调用

通过 useRequest 调用

const { runAsync: deleteItem } = useRequest(commonTestApi, {
  manual: true,
  onSuccess() {
    Message.success('删除成功');
  },
});

正常调用

const data = await commonTestApi();