Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

mengqiuleo/axios-plugin

Open more actions menu

Repository files navigation

@axios-plugin

概述

一个 axios 请求层拦截器代码组织的方案。

它将项目中自定义封装的请求、响应拦截器进行解构,封装成一个插件,并且通过 @axios-plugin/core 将 axios 插件化, 之后就可以在插件化之后的 axios 实例身上挂载各种功能插件。

通过插件化的开发,可以实现所有拦截器职责单一、方便维护、并统一维护自动调度,避免实际业务中对每个项目的重复封装。

如何运行的

@axios-plugin/core 内部,实现了一个 AxiosPluginify 类,并且通过向外暴露的 pluginify 函数,返回一个 AxiosPluginify 类的实例。 在 AxiosPluginify 类身上,有 use 方法,实现将传入的插件收集到数组中,以便挂载到 axios 实例上。 另外,该类还有 generate 方法,它会按照传入的插件顺序,依次将这些插件挂载到 传入的 axios 实例上,最后返回新的 axios 实例。

已提供的插件

安装

npm i @axios-plugin/core

自定义插件

自定义 Class 实现

插件的 TS 类型定义

export interface AxiosPlugin {
  pluginName: string;
  beforeCreate?: beforeCreateHook;
  created?: createdHook;
}

PluginClass

import axios from 'axios'
import { pluginify } from "@axios-plugin/core"

class Plugin implements AxiosPlugin {
  public pluginName = 'plugin' //必选,插件名,用于记录插件调用出错的情况
  // 可选
  constructor(pluginConfig) {
    this.pluginConfig = pluginConfig;
  }

  // 可选 axios 实例化前创建
  beforeCreate(axiosConfig, axiosStatic) {
    console.log(this.pluginConfig);
    console.log(axiosConfig);
    console.log(axiosStatic);
  }

  // 可选 axios 实例化后创建
  created(axiosInstance, axiosConfig) {
    console.log(axiosInstance);
    console.log(axiosConfig);
  }
}

const axiosInstance = pluginify(axios).use(new Plugin()).generate();

axiosInstance.get('/users');

包装已有类库

import axios from 'axios'
import { pluginify } from "@axios-plugin/core"
import axiosRetry, { IAxiosRetryConfig } from 'axios-retry';

export class RetryPlugin implements AxiosPlugin {
  public pluginName = 'RetryPlugin'
  constructor(public config?: IAxiosRetryConfig) {}

  created(axios: AxiosInstance) {
    axiosRetry(axios, this.config)
  }
}


const axiosInstance = pluginify(axios)
  .use(new RetryPlugin())
  .generate()

axiosInstance.get('/users')

包装拦截器

import axios from 'axios'
import { pluginify } from "@axios-plugin/core"

class RequestWithToken {
  public pluginName = 'RequestWithToken'
  constructor(token) {
    this.token = token
  }
  created(axiosInstance) {
    axiosInstance.interceptors.request.use((config) => {
      config.headers['x-access-token'] = this.token
    });
  }
}

class ExtractResultPlugin {
  public pluginName = 'ExtractResultPlugin'
  created(axiosInstance) {
    axiosInstance.interceptors.response.use((response) => {
      if (response.status === 200) {
        return response.data
      }
    });
  }
}

const axiosInstance = pluginify(axios)
  .use(new RequestWithToken('token'), new ExtractResultPlugin())
  .generate()

axiosInstance.get('/users')

API

pluginify

pluginify(axios)

pluginify(axios, config);
// config 的 TS 类型为 AxiosRequestConfig

config 具体内容可参考:https://axios-http.com/zh/docs/req_config

use

const axiosPluginify = pluginify(axios)

axiosPluginify.use(new Plugin(), new Plugin(), new Plugin())

//or

axiosPluginify.use(new Plugin()).use(new Plugin()).use(new Plugin())

demo

//1. axiosStatic add config
const config = {
  baseURL: '/users',
  timeout: 5000
}
const axiosInstance1 = pluginify(axios, config).use(new Plugin(), new Plugin()).generate();
const axiosInstance2 = pluginify(axios).use(new Plugin()).use(new Plugin()).generate();

//2. AxiosInstance add config
axiosInstance2.defaults.baseURL = '/users'
axiosInstance2.defaults.timeout = 5000

const res1 = await axiosInstance1.get('/info')
const res2 = await axiosInstance2.get('/info')

generate

创建 axios 实例并结合 use 方法所给定的插件.

const axiosPluginify = pluginify(axios)

const axiosInstance = axiosPluginify.use(new Plugin()).generate()

通过向 generate 传入 true 表示生成 axiosInstance 后销毁 pluginify 内部保存的引用, 避免内存泄漏.

const axiosPluginify = pluginify(axios);

const axiosInstance = axiosPluginify.use(new Plugin()).generate(true)

destroy

用于销毁 pluginify 内部保存的引用, 可以通过 generate(true) 触发.

plugin

插件是一个类(也可以是一个构造函数), 可以提供数个生命周期钩子.

class Plugin {
  public pluginName = 'Plugin' //required
  
  // optional
  constructor() {}

  // optional
  beforeCreate(axiosRequestConfig, axiosStatic) {}

  // optional
  created(axiosInstance, axiosRequestConfig) {}
}

这里的 axiosInstance 代表 创建出的 axios 实例,axiosStatic 代表 axios 本身

FAQ

插件的执行顺序是怎样的

@axios-plugin 会按照 use 方法的执行顺序来处理它们的挂载。

但在 axios 内部,对于请求拦截器,是先挂载的后执行;对于响应拦截器,是先挂载的先执行。

遇到不正确的插件

这里对自定义插件的要求很低,只要编写的插件中含有 beforeCreate 或者 created 函数就OK,至于在函数内部做的事情都不做要求,最后在统一调用时,依次取出所有的插件函数执行。

目前对插件调用出错的情况,向外抛错,插件调用流程终止。

About

一个 axios 请求层拦截器代码组织的方案,将 axios 插件化,实现与自定义拦截器的解耦

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.