You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多客户端Monorepo项目中Axios的管理方案咨询

Monorepo多客户端Axios管理方案

针对你的Monorepo场景,以下是几个落地性强的Axios管理思路,兼顾复用性与客户端隔离需求:

1. 抽离共享Axios核心包

在packages目录下新建axios-core包,统一管理基础配置与通用拦截逻辑,同时提供扩展能力让客户端定制自身逻辑:

核心实现示例

// packages/axios-core/src/index.ts
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';

// 通用基础配置
const baseConfig: AxiosRequestConfig = {
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 10000,
};

// 创建基础Axios实例
const baseAxios = axios.create(baseConfig);

// 添加全局通用请求拦截器(如统一携带token)
baseAxios.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('auth_token');
    if (token) config.headers.Authorization = `Bearer ${token}`;
    return config;
  },
  (error) => Promise.reject(error)
);

// 添加全局通用响应拦截器(如统一处理401跳转)
baseAxios.interceptors.response.use(
  (res) => res,
  (error) => {
    if (error.response?.status === 401) window.location.href = '/login';
    return Promise.reject(error);
  }
);

// 提供客户端定制实例的创建函数
export function createClientAxios(customInterceptors?: {
  request?: Parameters<AxiosInstance['interceptors']['request']['use']>[0];
  response?: Parameters<AxiosInstance['interceptors']['response']['use']>[0];
}): AxiosInstance {
  const clientAxios = baseAxios.create();
  
  // 挂载客户端专属拦截器
  if (customInterceptors?.request) {
    clientAxios.interceptors.request.use(customInterceptors.request);
  }
  if (customInterceptors?.response) {
    clientAxios.interceptors.response.use(customInterceptors.response);
  }
  
  return clientAxios;
}

// 导出基础实例供共享Composable使用
export default baseAxios;

2. 拦截器分层复用与定制

  • 共享拦截器:所有通用逻辑(如token携带、通用错误码处理)放在axios-core中,所有客户端默认继承。
  • 客户端专属拦截器:每个客户端在自身代码中调用createClientAxios方法添加专属逻辑,比如client1需要添加特定请求头、client2需要处理专属业务错误:
// apps/client1/composables/axios.ts
import { createClientAxios } from '@monorepo/axios-core';

// 创建client1专属Axios实例
export const client1Axios = createClientAxios({
  request: (config) => {
    config.headers['X-Client-Identifier'] = 'client1';
    return config;
  },
  response: (res) => {
    // 处理client1专属响应逻辑
    if (res.data?.client1_feature_flag) {
      // 自定义业务处理
    }
    return res;
  }
});

3. Composable分层与构建隔离

分层管理

  • 共享Composable:放在packages/composables下,使用axios-core导出的基础实例调用共享API,比如getUser:
// packages/composables/user.composable.ts
import baseAxios from '@monorepo/axios-core';
import type { IUser } from '@monorepo/models';

export async function getUser(): Promise<IUser> {
  const res = await baseAxios.get('/api/user/profile');
  return res.data;
}
  • 客户端专属Composable:放在对应客户端的composables目录下,使用客户端定制的Axios实例调用专属API,比如getClient1Data:
// apps/client1/composables/user.composable.ts
import { client1Axios } from './axios';

export async function getClient1Data(): Promise<unknown> {
  const res = await client1Axios.get('/api/client1/exclusive-data');
  return res.data;
}

构建隔离保障

利用Monorepo构建工具的特性,确保客户端专属代码不会被其他客户端编译:

  • 若使用Nx/Turbo:将每个客户端标记为独立项目,构建时仅处理当前项目的源码目录。
  • 若使用Vite/Webpack:在客户端的配置文件中指定root为自身目录(如apps/client1),或在tsconfig.json中排除其他客户端目录:
// apps/client1/tsconfig.json
{
  "exclude": [
    "../client2/**/*",
    "../client3/**/*",
    "node_modules"
  ]
}

4. 类型统一管理

  • 共享类型(如IUser)继续放在packages/models下,供所有客户端与共享Composable引用。
  • 客户端专属类型放在各自客户端的models目录下,仅在当前客户端内部使用,避免跨客户端引用。

内容的提问来源于stack exchange,提问作者Jacek Kaczmarek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:00:48