0.3.1 • Published 19 days ago

axios-plugins v0.3.1

Weekly downloads
-
License
MIT
Repository
github
Last release
19 days ago

Extend more plugin capabilities (such as debounce and throttle, etc.) for axios with minimal impact.

Features

  • Lightweight The core package size is 1.37kb/gziped, complete package size is 5.88kb/gziped, supports TreeShaking and single plugin reference.
  • Multiple instance support Plugin cache variables are associated with axios instances, and multiple axios instances do not interfere with each other.
  • Low intrusiveness Plugins are extended by wrapping, without affecting the existing configuration of the instance, and without destroying the api of axios.
  • Low integration cost Compared with other plugins, there is no need to make a lot of changes to integrate the plugin, and there is no learning cost.
  • Rich plugin selection Compared with other plugins based on axios.interceptors, this library provides more diversified plugin options.
  • Extendable Provides the IPlugin interface, which only needs to follow the interface specification to extend more plugin capabilities on its own.

Usage

  • install
yarn add axios axios-adapters
# or
npm install axios axios-adapters
  • use plugin
import axios from 'axios'
import { useAxiosPlugin, mock, loading } from 'axios-plugins'

// 1. create axios instance
export const request = axios.create({
    /* ... */
})

// 2. append plugin support

useAxiosPlugin(axios) // default axios
// or
useAxiosPlugin(request) // new instance

// 3. use plugin

useAxiosPlugin(axios).plugin(mock())

// 4. Example: use plugin extension parameters during the request process

request.post('/api', {}, { mock: true })

// 5. If you need to use 'request()' to request, then you need to use the 'wrap()' method to overwrite the original instance
const request2 = useAxiosPlugin(request).wrap()
  • on need import
import axios from 'axios'
// + Modify the dependency import to the following way
import { useAxiosPlugin } from 'axios-plugins/core'
import { loading } from 'axios-plugins/plugins/loading'

// 1. create axios instance
export const request = axios.create({
    /* ... */
})

// 2. use plugin
useAxiosPlugin(request).plugin(loading())

Plugins

PluginDescription
debounceWhen duplicate requests are made within a certain time, the later request will wait for the last request to complete before executing
throttleWhen duplicate requests are made within a certain time, the later request will be discarded
mergeWhen duplicate requests are made within a certain time, the requests will only be made once, and each requester will receive the same response
retryWhen a request fails (errors), retry n times. If all retries fail, an exception will be thrown
cancelProvides cancelAll() method to cancel all ongoing requests
cacheStores the response content of the request and returns it for the next request (within cache expiration time)
envsNormalizes axios environment configuration tool
loadingProvides a unified control capability for global loading to reduce the workload of independent loading control for each loading method
loggerCustom request process log printing
mockProvides global or single interface request mock capability
normalizeFilters out undefined, null, and other parameters generated during the request process
pathParamsExpands support for Restful API specification of route parameters
signProvides request anti-tampering capability. This feature requires collaboration with backend logic implementation
sentryCaptureExtension Sentry.captureException implementation
onlySendProvides a wrapper method for navigator.sendBeacon to submit embedded data when the page is exited. This requires backend support
mpExpands support for network requests from small programs (WeChat, Toutiao, QQ, etc.) and cross-platform frameworks (uni-app, taro)

Example

debounce

import { useAxiosPlugin } from 'axios-plugin/core'
import { debounce } from 'axios-plugins/plugins/debounce'

const request = axios.create({})

// add plugin
useAxiosPlugin(request).plugin(debounce())

// set delay judgment time
debounce({ delay: 200 })

// set filter pattern
debounce({ includes: '/api/', excludes: [] })

// set duplicate request determination method
debounce({ calcRequstHash: (config) => config.url })

// on execute request, set higher priority judgment criteria
request.post('/api/xxx', {}, { debounce: true })

// set different delay judgment times
request.post('/api/xxx', {}, { debounce: { delay: 1000 } })

throttle

import { useAxiosPlugin } from 'axios-plugin/core'
import { throttle, GiveUpRule } from 'axios-plugins/plugins/throttle'

const request = axios.create({})
/** 配置 */
// 基础使用
useAxiosPlugin(request).plugin(throttle())

// set delay judgment time
throttle({ delay: 200 })

// 设置哪些请求将触发节流策略 (按需设置 `includes`, `excludes`)
throttle({ includes: '/api/', excludes: [] })

// 设置节流策略处理规则
throttle({ giveUp: GiveUpRule.throw }) // 抛出异常 (默认)
throttle({ giveUp: GiveUpRule.cancel }) // 中断请求, 并返回空值结果
throttle({ giveUp: GiveUpRule.slient }) // 静默, 既不返回成功、也不抛出异常

// 自定义相同请求判定规则 (忽略参数差异时比较有用)
throttle({ calcRequstHash: (config) => config.url })

// 在请求时, 设置请求将触发防抖策略 (优先级更高)
request.post('/api/xxx', {}, { throttle: true })

// set different delay judgment times
request.post('/api/xxx', {}, { throttle: { delay: 1000 } })
// in request, set capture throttle handle rule
request.post('/api/xxx', {}, { throttle: { giveUp: GiveUpRule.cancel } })
// 单个请求设置触发节流后抛出的异常消息
request.post('/api/xxx', {}, { throttle: { throttleErrorMessage: 'xxxxx' } })

merge

import { useAxiosPlugin } from 'axios-plugin/core'
import { merge } from 'axios-plugins/plugins/merge'

const request = axios.create({})
/** 配置 */
// 基础使用
useAxiosPlugin(request).plugin(merge())

// set delay judgment time
merge({ delay: 200 })

// 设置哪些请求将触发重复请求合并策略 (按需设置 `includes`, `excludes`)
merge({ includes: '/api/', excludes: [] })

// 自定义相同请求判定规则 (忽略参数差异时比较有用)
merge({ calcRequstHash: (config) => config.url })

// 在请求时, 设置请求将触发重复请求合并策略 (优先级更高)
request.post('/api/xxx', {}, { merge: true })

// 单个请求设置不同的触发延时
request.post('/api/xxx', {}, { merge: { delay: 1000 } })
retry
import { useAxiosPlugin } from 'axios-plugin/core'
import { retry } from 'axios-plugins/plugins/retry'

const request = axios.create({})
/** 配置 */
// 基础使用 (必须设置重试次数)
useAxiosPlugin(request).plugin(retry({ max: 3 }))

// 设置哪些请求失败后将重试 (不建议设置这个option, 建议在请求时指定retry参数)
retry({ includes: [], excludes: [] })

// 自定义失败请求检查方法 (不建议设置这个option, 建议在添加一个 `axios.interceptors` 或 `transform()` 插件来判断响应结果)
retry({ isExceptionRequest: (config) => false })

// 在请求时, 设置请求将触发防抖策略 (优先级更高)
request.post('/api/xxx', {}, { retry: 3 })
cancel

TIP: 如果请求指定了 cancelToken, 将会导致此插件失效.

import { useAxiosPlugin } from 'axios-plugin/core'
import { cancel, cancelAll } from 'axios-plugins/plugins/cancel'

const request = axios.create({})
// 添加插件
useAxiosPlugin(request).plugin(cancel())

// > 中止所有在执行的请求
cancelAll(request)

transform

import { useAxiosPlugin } from 'axios-plugin/core'
import { transform } from 'axios-plugins/plugins/transform'

const request = axios.create({})
// 添加插件
useAxiosPlugin(request).plugin(
    transform({
        // + 转换请求参数
        request: (config) => {
            // TODO
            return config
        },
        // + 转换响应参数
        response: (res) => {
            // TODO
            return res
        },
        // + 转换异常信息
        capture: (e) => {
            // TODO
            throw e
        }
    })
)

cache

import { useAxiosPlugin } from 'axios-plugin/core'
import { cache } from 'axios-plugins/plugins/cache'

const request = axios.create({})
// 添加插件
useAxiosPlugin(request).plugin(cache())

// 设置全局缓存失效时间
cache({ expires: Date.now() + 24 * 60 * 60 * 1000 })
// 设置缓存存储位置 (默认: sessionStorage)
cache({ storage: localStorage })
// 设置 storage 中, 缓存cache的字段名
cache({ storageKey: 'axios.cache' })
// 设置自定义的缓存key计算方法
cache({ key: (config) => config.url })

// 请求时, 指定此接口触发响应缓存
request.post('/api', {}, { cache: true })
// 自定义此接口缓存失效时间
request.post('/api', {}, { cache: { expires: Date.now() } })
// 自定义此接口缓存key
request.post('/api', {}, { cache: { key: '/api' } })

envs

import { useAxiosPlugin } from 'axios-plugin/core'
import { envs } from 'axios-plugins/plugins/envs'

const request = axios.create({})
// 添加插件
useAxiosPlugin(request).plugin(
    envs([
        {
            rule: () => process.env.NODE_ENV === 'development',
            config: {
                baseURL: 'http://dev'
            }
        },
        {
            rule: () => process.env.NODE_ENV === 'production',
            config: {
                baseURL: 'http://prod'
            }
        }
    ])
)

loading

import { useAxiosPlugin } from 'axios-plugin/core'
import { loading } from 'axios-plugins/plugins/loading'
import { loading as ElLoading } from 'element-plus'

const request = axios.create({})

let loadingEl
// 添加插件
useAxiosPlugin(request).plugin(
    loading({
        onTrigger: (show) => {
            if (show) {
                loadingEl = ElLoading({
                    lock: true,
                    text: 'Loading',
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.7)'
                })
            } else {
                loadingEl.close()
            }
        }
    })
)
// 自定义显示延时和隐藏延时 (避免频繁显示或隐藏 loading 效果)
loading({ delay: 200, delayClose: 200 })

// 指定请求禁用 loading
request.post('/api', {}, { loading: false })

logger

import { useAxiosPlugin } from 'axios-plugin/core'
import { logger } from 'axios-plugins/plugins/logger'

const request = axios.create({})

// 添加插件
useAxiosPlugin(request).plugin(
    logger({
        // 开启 请求参数打印
        request: true,
        // 开启 响应参数打印
        response: true,
        // 开启异常信息打印
        error: true
    })
)

// 自定义打印配置 (参考: https://www.npmjs.com/package/axios-logger)
logger({ config: {} })

mock

建议借助三方工具(如: apifox, apipost 等) 实现 mock 能力

import { useAxiosPlugin } from 'axios-plugin/core'
import { mock } from 'axios-plugins/plugins/mock'

const request = axios.create({})

useAxiosPlugin(request).plugin(
    // 添加插件, 并指定mock服务器地址
    mock({ mockUrl: 'http://mock' })
)
// 自定义启用条件 (如果没有使用 webpack, vite 那么此参数是必要的)
mock({ enable: () => false })

// 使用全局mock
const request1 = axios.create({
    mock: true
})

// 按需mock (单个请求mock)
request.post('/api', {}, { mock: true })

// 针对不同接口使用不同的mock服务器
request.post('/api', {}, { mock: { mock: true, mockUrl: 'http://mock1' } })

normalize

import { useAxiosPlugin } from 'axios-plugin/core'
import { normalize } from 'axios-plugins/plugins/normalize'

const request = axios.create({})

useAxiosPlugin(request).plugin(
    normalize({
        // 过滤url
        url: {
            // 过滤url中, 重复的 `//`, 如: `/api/a//b` -> `/api/a/b`
            noDuplicateSlash: true
        },
        // 设置完整的过滤参数
        data: {
            /** 过滤 null 值 */
            noNull: true,
            /** 过滤 undefined 值 */
            noUndefined: true,
            /** 过滤 nan */
            noNaN: true,
            /** 是否对对象进行递归 */
            deep: true
        },
        // 设置仅过滤 undefined
        params: true
    })
)

pathParams

import { useAxiosPlugin } from 'axios-plugin/core'
import { pathParams } from 'axios-plugins/plugins/pathParams'

const request = axios.create({})

// 添加插件
useAxiosPlugin(request).plugin(pathParams())

// 设置仅从 params 中获取路径参数
pathParams({ form: 'params' })

sign

import { useAxiosPlugin } from 'axios-plugin/core'
import { sign } from 'axios-plugins/plugins/sign'

const request = axios.create({})

// 添加插件
useAxiosPlugin(request).plugin(sign({}))

// 设置签名生成参数
sign({
    // 签名字段
    key: 'sign',
    // 签名算法
    algorithm: 'md5',
    // 禁用参数排序
    sort: false,
    // 禁用过滤空值
    filter: false,
    // 加盐
    salt: 'xxxxx'
})

sentryCapture

import { useAxiosPlugin } from 'axios-plugin/core'
import { sign } from 'axios-plugins/plugins/sign'
import * as sentry from '@sentry/browser' // or @sentry/vue or @sentry/react ...

const request = axios.create({})

// 添加插件
useAxiosPlugin(request).plugin(sentryCapture({ sentry }))

onlySend

import { useAxiosPlugin } from 'axios-plugin/core'
import { onlySend } from 'axios-plugins/plugins/onlySend'

const request = axios.create({})

// 添加插件
useAxiosPlugin(request).plugin(onlySend())

// 设置浏览器不支持 `navigator.sendBeacon` api时报错
onlySend({ noSupport: 'error' })

mp

import { useAxiosPlugin } from 'axios-plugin/core'
import { mp } from 'axios-plugins/plugins/mp'

const request = axios.create({})

// 添加插件
useAxiosPlugin(request).plugin(mp({ env: 'wx' }))

// 指定不同的小程序平台
mp({ env: 'tt' }) // 头条、抖音等等
// 添加请求的公共配置
mp({
    config: {
        /** ... */
    }
})

Thanks

0.3.1-dev.1

19 days ago

0.3.1

19 days ago

0.0.2-fix.1

10 months ago

0.0.2-fix.2

10 months ago

0.0.2-fix.3

10 months ago

0.1.0

8 months ago

0.2.1

7 months ago

0.0.3

10 months ago

0.2.0

7 months ago

0.0.2

10 months ago

0.2.7

6 months ago

0.2.6

6 months ago

0.2.8

6 months ago

0.2.3

7 months ago

0.0.5

8 months ago

0.2.2

7 months ago

0.0.4

8 months ago

0.2.5

6 months ago

0.2.4

7 months ago

0.0.1

11 months ago

0.0.1-dev.6

11 months ago

0.0.1-dev.5

11 months ago

0.0.1-dev.8

11 months ago

0.0.1-dev.7

11 months ago

0.0.1-dev.4

11 months ago

0.0.1-beta.3

11 months ago

0.0.1-beta.2

11 months ago

0.0.1-dev.10

11 months ago

0.0.1-dev.9

11 months ago

0.0.1-beta.1

11 months ago

0.0.1-dev.3

11 months ago

0.0.1-dev.2

11 months ago

0.0.1-dev

11 months ago