refactor(projects): 请求适配器函数范型重构、优化请求相关的命名
This commit is contained in:
parent
02992dc02d
commit
7f9c98ab8d
@ -1,30 +1,33 @@
|
||||
/** 请求环境配置 */
|
||||
/** 请求服务的环境配置 */
|
||||
type ServiceEnv = Record<ServiceEnvType, ServiceEnvConfig>;
|
||||
|
||||
/** 不同服务的环境配置 */
|
||||
/** 不同请求服务的环境配置 */
|
||||
const serviceEnv: ServiceEnv = {
|
||||
dev: {
|
||||
pattern: '/proxy-pattrn',
|
||||
url: 'http://localhost:8080',
|
||||
proxy: '/proxy-flag'
|
||||
secondUrl: 'http://localhost:8081'
|
||||
},
|
||||
test: {
|
||||
pattern: '/proxy-pattrn',
|
||||
url: 'http://localhost:8080',
|
||||
proxy: '/proxy-flag'
|
||||
secondUrl: 'http://localhost:8081'
|
||||
},
|
||||
prod: {
|
||||
pattern: '/proxy-pattrn',
|
||||
url: 'http://localhost:8080',
|
||||
proxy: '/proxy-flag'
|
||||
secondUrl: 'http://localhost:8081'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取当前模式的环境配置
|
||||
* 获取当前环境模式下的请求服务的配置
|
||||
* @param env 环境
|
||||
*/
|
||||
export function getEnvConfig(env: ImportMetaEnv) {
|
||||
const { VITE_ENV_TYPE = 'dev' } = env;
|
||||
export function getServiceEnvConfig(env: ImportMetaEnv) {
|
||||
const { VITE_SERVICE_ENV = 'dev' } = env;
|
||||
|
||||
const envConfig = serviceEnv[VITE_ENV_TYPE];
|
||||
const config = serviceEnv[VITE_SERVICE_ENV];
|
||||
|
||||
return envConfig;
|
||||
return config;
|
||||
}
|
||||
|
@ -9,10 +9,15 @@ export function createViteProxy(isOpenProxy: boolean, envConfig: ServiceEnvConfi
|
||||
if (!isOpenProxy) return undefined;
|
||||
|
||||
const proxy: Record<string, string | ProxyOptions> = {
|
||||
[envConfig.proxy]: {
|
||||
[envConfig.pattern]: {
|
||||
target: envConfig.url,
|
||||
changeOrigin: true,
|
||||
rewrite: path => path.replace(new RegExp(`^${envConfig.proxy}`), '')
|
||||
rewrite: path => path.replace(new RegExp(`^${envConfig.pattern}`), '')
|
||||
},
|
||||
[envConfig.pattern]: {
|
||||
target: envConfig.secondUrl,
|
||||
changeOrigin: true,
|
||||
rewrite: path => path.replace(new RegExp(`^${envConfig.pattern}`), '')
|
||||
}
|
||||
};
|
||||
|
||||
|
12
package.json
12
package.json
@ -7,12 +7,12 @@
|
||||
"url": "https://github.com/honghuangdc"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "cross-env VITE_ENV_TYPE=dev vite",
|
||||
"dev:test": "cross-env VITE_ENV_TYPE=test vite",
|
||||
"dev:prod": "cross-env VITE_ENV_TYPE=prod vite",
|
||||
"build": "npm run typecheck && cross-env VITE_ENV_TYPE=prod vite build",
|
||||
"build:dev": "npm run typecheck && cross-env VITE_ENV_TYPE=dev vite build",
|
||||
"build:test": "npm run typecheck && cross-env VITE_ENV_TYPE=test vite build",
|
||||
"dev": "cross-env VITE_SERVICE_ENV=dev vite",
|
||||
"dev:test": "cross-env VITE_SERVICE_ENV=test vite",
|
||||
"dev:prod": "cross-env VITE_SERVICE_ENV=prod vite",
|
||||
"build": "npm run typecheck && cross-env VITE_SERVICE_ENV=prod vite build",
|
||||
"build:dev": "npm run typecheck && cross-env VITE_SERVICE_ENV=dev vite build",
|
||||
"build:test": "npm run typecheck && cross-env VITE_SERVICE_ENV=test vite build",
|
||||
"build:vercel": "cross-env VITE_HASH_ROUTE=Y VITE_VERCEL=Y vite build",
|
||||
"preview": "vite preview",
|
||||
"typecheck": "vue-tsc --noEmit --skipLibCheck",
|
||||
|
@ -1,12 +0,0 @@
|
||||
export function adapterOfFetchDataWithAdapter(
|
||||
res: Service.RequestResult<ApiDemo.DataWithAdapter>
|
||||
): Demo.DataWithAdapter {
|
||||
const { dataId, dataName } = res.data!;
|
||||
|
||||
const result: Demo.DataWithAdapter = {
|
||||
id: dataId,
|
||||
name: dataName
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
10
src/service/api/demo.adapter.ts
Normal file
10
src/service/api/demo.adapter.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export function adapterOfFetchDataWithAdapter(data: ApiDemo.DataWithAdapter): Demo.DataWithAdapter {
|
||||
const { dataId, dataName } = data;
|
||||
|
||||
const result: Demo.DataWithAdapter = {
|
||||
id: dataId,
|
||||
name: dataName
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import { serviceAdapter } from '@/utils';
|
||||
import { adapter } from '@/utils';
|
||||
import { request, mockRequest } from '../request';
|
||||
import { adapterOfFetchDataWithAdapter } from '../adapter';
|
||||
import { adapterOfFetchDataWithAdapter } from './demo.adapter';
|
||||
|
||||
/** 带有适配器的请求(将请求结果进行数据处理) */
|
||||
/** 带有适配器的请求示例 */
|
||||
export async function fetchDataWithAdapter() {
|
||||
const res = await mockRequest.post<ApiDemo.DataWithAdapter>('/apiDemoWithAdapter');
|
||||
return serviceAdapter(adapterOfFetchDataWithAdapter, res);
|
||||
return adapter(adapterOfFetchDataWithAdapter, res);
|
||||
}
|
||||
|
||||
/** 测试代理后的请求 */
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { getEnvConfig } from '~/.env-config';
|
||||
import { getServiceEnvConfig } from '~/.env-config';
|
||||
import { createRequest } from './request';
|
||||
|
||||
const envConfig = getEnvConfig(import.meta.env);
|
||||
const { pattern, url, secondUrl } = getServiceEnvConfig(import.meta.env);
|
||||
|
||||
const isHttpProxy = import.meta.env.VITE_HTTP_PROXY === 'Y';
|
||||
|
||||
export const request = createRequest({ baseURL: isHttpProxy ? envConfig.proxy : envConfig.url });
|
||||
export const request = createRequest({ baseURL: isHttpProxy ? pattern : url });
|
||||
|
||||
export const secondRequest = createRequest({ baseURL: isHttpProxy ? pattern : secondUrl });
|
||||
|
||||
export const mockRequest = createRequest({ baseURL: '/mock' });
|
||||
|
10
src/typings/env.d.ts
vendored
10
src/typings/env.d.ts
vendored
@ -8,10 +8,12 @@ type ServiceEnvType = 'dev' | 'test' | 'prod';
|
||||
|
||||
/** 后台服务的环境配置 */
|
||||
interface ServiceEnvConfig {
|
||||
/** 匹配路径的正则字符串, 用于拦截地址转发代理(任意以 /开头 + 字符串, 单个/不起作用) */
|
||||
pattern: '/proxy-pattrn';
|
||||
/** 请求地址 */
|
||||
url: string;
|
||||
/** 代理标识, 用于拦截地址转发代理(和后端请求路径中有无该路径没有关系) */
|
||||
proxy: '/proxy-flag';
|
||||
/** 另一个后端请求地址(有多个不同的后端服务时) */
|
||||
secondUrl: string;
|
||||
}
|
||||
|
||||
interface ImportMetaEnv {
|
||||
@ -31,8 +33,8 @@ interface ImportMetaEnv {
|
||||
readonly VITE_AUTH_ROUTE_MODE: 'static' | 'dynamic';
|
||||
/** 路由首页的路径 */
|
||||
readonly VITE_ROUTE_HOME_PATH: Exclude<AuthRoute.RoutePath, '/' | '/not-found-page' | '/:pathMatch(.*)*'>;
|
||||
/** vite环境类型 */
|
||||
readonly VITE_ENV_TYPE?: ServiceEnvType;
|
||||
/** 后端服务的环境类型 */
|
||||
readonly VITE_SERVICE_ENV?: ServiceEnvType;
|
||||
/** 开启请求代理 */
|
||||
readonly VITE_HTTP_PROXY?: 'Y' | 'N';
|
||||
/** 是否开启打包文件大小结果分析 */
|
||||
|
14
src/typings/system.d.ts
vendored
14
src/typings/system.d.ts
vendored
@ -70,6 +70,20 @@ declare namespace Service {
|
||||
/** 自定义的请求结果 */
|
||||
type RequestResult<T = any> = SuccessResult<T> | FailedResult;
|
||||
|
||||
/** 多个请求数据结果 */
|
||||
type MultiRequestResult<T extends any[]> = T extends [infer First, ...infer Rest]
|
||||
? First extends any
|
||||
? Rest extends any[]
|
||||
? [Service.RequestResult<First>, ...MultiRequestResult<Rest>]
|
||||
: [Service.RequestResult<First>]
|
||||
: Rest extends any[]
|
||||
? MultiRequestResult<Rest>
|
||||
: []
|
||||
: [];
|
||||
|
||||
/** 请求结果的适配器函数 */
|
||||
type ServiceAdapter<T = any, A extends any[] = any> = (...args: A) => T;
|
||||
|
||||
/** mock示例接口类型:后端接口返回的数据的类型 */
|
||||
interface MockServiceResult<T = any> {
|
||||
/** 状态码 */
|
||||
|
@ -14,14 +14,11 @@ export async function handleServiceResult<T = any>(error: Service.RequestError |
|
||||
return success;
|
||||
}
|
||||
|
||||
type Adapter<T = any> = (...args: Service.RequestResult[]) => T;
|
||||
|
||||
/**
|
||||
* 请求结果的数据转换适配器
|
||||
* @param adapter - 适配器函数
|
||||
* @param args - 适配器函数的参数
|
||||
*/
|
||||
export function serviceAdapter<T extends Adapter>(adapter: T, ...args: TypeUtil.GetFunArgs<T>) {
|
||||
/** 请求结果的适配器:用于接收适配器函数和请求结果 */
|
||||
export function adapter<T extends Service.ServiceAdapter>(
|
||||
adapterFun: T,
|
||||
...args: Service.MultiRequestResult<TypeUtil.GetFunArgs<T>>
|
||||
): Service.RequestResult<TypeUtil.GetFunReturn<T>> {
|
||||
let result: Service.RequestResult | undefined;
|
||||
|
||||
const hasError = args.some(item => {
|
||||
@ -36,11 +33,12 @@ export function serviceAdapter<T extends Adapter>(adapter: T, ...args: TypeUtil.
|
||||
});
|
||||
|
||||
if (!hasError) {
|
||||
const adapterFunArgs = args.map(item => item.data);
|
||||
result = {
|
||||
error: null,
|
||||
data: adapter(...args)
|
||||
data: adapterFun(...adapterFunArgs)
|
||||
};
|
||||
}
|
||||
|
||||
return result as Service.RequestResult<TypeUtil.GetFunReturn<T>>;
|
||||
return result!;
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
import { getRootPath, getSrcPath, viteDefine, setupVitePlugins, createViteProxy } from './build';
|
||||
import { getEnvConfig } from './.env-config';
|
||||
import { getServiceEnvConfig } from './.env-config';
|
||||
|
||||
export default defineConfig(configEnv => {
|
||||
const viteEnv = loadEnv(configEnv.mode, process.cwd()) as ImportMetaEnv;
|
||||
const viteEnv = loadEnv(configEnv.mode, process.cwd()) as unknown as ImportMetaEnv;
|
||||
|
||||
const rootPath = getRootPath();
|
||||
const srcPath = getSrcPath();
|
||||
|
||||
const isOpenProxy = viteEnv.VITE_HTTP_PROXY === 'Y';
|
||||
const envConfig = getEnvConfig(viteEnv);
|
||||
const envConfig = getServiceEnvConfig(viteEnv);
|
||||
|
||||
return {
|
||||
base: viteEnv.VITE_BASE_URL,
|
||||
|
Loading…
Reference in New Issue
Block a user