diff --git a/.fatherrc.js b/.fatherrc.js index 56414d04..a191f716 100644 --- a/.fatherrc.js +++ b/.fatherrc.js @@ -6,7 +6,7 @@ import { join } from "path"; const headPkgs = [ "fes-runtime", - "fes-core", + "fes-compiler", "fes", "fes-preset-built-in", "fes-plugin-request", diff --git a/packages/fes-core/.fatherrc.js b/packages/fes-compiler/.fatherrc.js similarity index 100% rename from packages/fes-core/.fatherrc.js rename to packages/fes-compiler/.fatherrc.js diff --git a/packages/fes-core/package.json b/packages/fes-compiler/package.json similarity index 88% rename from packages/fes-core/package.json rename to packages/fes-compiler/package.json index 44b3bdbe..455d4380 100644 --- a/packages/fes-core/package.json +++ b/packages/fes-compiler/package.json @@ -1,7 +1,7 @@ { - "name": "@webank/fes-core", + "name": "@webank/fes-compiler", "version": "2.0.0", - "description": "@webank/fes-core", + "description": "@webank/fes-compiler", "main": "lib/index.js", "types": "lib/index.d.ts", "files": [ diff --git a/packages/fes-core/src/config/index.js b/packages/fes-compiler/src/config/index.js similarity index 100% rename from packages/fes-core/src/config/index.js rename to packages/fes-compiler/src/config/index.js diff --git a/packages/fes-core/src/config/utils/configUtils.js b/packages/fes-compiler/src/config/utils/configUtils.js similarity index 100% rename from packages/fes-core/src/config/utils/configUtils.js rename to packages/fes-compiler/src/config/utils/configUtils.js diff --git a/packages/fes-core/src/config/utils/isEqual.js b/packages/fes-compiler/src/config/utils/isEqual.js similarity index 100% rename from packages/fes-core/src/config/utils/isEqual.js rename to packages/fes-compiler/src/config/utils/isEqual.js diff --git a/packages/fes-core/src/config/utils/mergeDefault.js b/packages/fes-compiler/src/config/utils/mergeDefault.js similarity index 100% rename from packages/fes-core/src/config/utils/mergeDefault.js rename to packages/fes-compiler/src/config/utils/mergeDefault.js diff --git a/packages/fes-core/src/index.js b/packages/fes-compiler/src/index.js similarity index 100% rename from packages/fes-core/src/index.js rename to packages/fes-compiler/src/index.js diff --git a/packages/fes-core/src/logger/index.js b/packages/fes-compiler/src/logger/index.js similarity index 98% rename from packages/fes-core/src/logger/index.js rename to packages/fes-compiler/src/logger/index.js index 0699d41b..96bdbb6e 100644 --- a/packages/fes-core/src/logger/index.js +++ b/packages/fes-compiler/src/logger/index.js @@ -61,7 +61,7 @@ export default class Logger { delete this.profilers[id]; process.stderr.write(`${this.PROFILE} `); msg = `${this.PROFILE} ${chalk.cyan( - `└ ${namespace}`, + `└ ${namespace}` )} Completed in ${this.formatTiming(time - timeEnd)}`; console.log(msg); } else { diff --git a/packages/fes-core/src/service/enums.js b/packages/fes-compiler/src/service/enums.js similarity index 100% rename from packages/fes-core/src/service/enums.js rename to packages/fes-compiler/src/service/enums.js diff --git a/packages/fes-core/src/service/getPaths.js b/packages/fes-compiler/src/service/getPaths.js similarity index 100% rename from packages/fes-core/src/service/getPaths.js rename to packages/fes-compiler/src/service/getPaths.js diff --git a/packages/fes-core/src/service/index.js b/packages/fes-compiler/src/service/index.js similarity index 100% rename from packages/fes-core/src/service/index.js rename to packages/fes-compiler/src/service/index.js diff --git a/packages/fes-core/src/service/pluginAPI.js b/packages/fes-compiler/src/service/pluginAPI.js similarity index 100% rename from packages/fes-core/src/service/pluginAPI.js rename to packages/fes-compiler/src/service/pluginAPI.js diff --git a/packages/fes-core/src/service/utils/isPromise.js b/packages/fes-compiler/src/service/utils/isPromise.js similarity index 100% rename from packages/fes-core/src/service/utils/isPromise.js rename to packages/fes-compiler/src/service/utils/isPromise.js diff --git a/packages/fes-core/src/service/utils/loadDotEnv.js b/packages/fes-compiler/src/service/utils/loadDotEnv.js similarity index 100% rename from packages/fes-core/src/service/utils/loadDotEnv.js rename to packages/fes-compiler/src/service/utils/loadDotEnv.js diff --git a/packages/fes-core/src/service/utils/pluginUtils.js b/packages/fes-compiler/src/service/utils/pluginUtils.js similarity index 100% rename from packages/fes-core/src/service/utils/pluginUtils.js rename to packages/fes-compiler/src/service/utils/pluginUtils.js diff --git a/packages/fes-plugin-request/package.json b/packages/fes-plugin-request/package.json index 7cd33fef..4c40d066 100644 --- a/packages/fes-plugin-request/package.json +++ b/packages/fes-plugin-request/package.json @@ -14,7 +14,9 @@ "author": "", "license": "MIT", "peerDependencies": { - "axios": "0.21.1", "@webank/fes": "^2.0.0" + }, + "dependencies": { + "axios": "0.21.1" } } diff --git a/packages/fes-plugin-request/src/index.js b/packages/fes-plugin-request/src/index.js index 3da01002..040623cd 100644 --- a/packages/fes-plugin-request/src/index.js +++ b/packages/fes-plugin-request/src/index.js @@ -5,6 +5,7 @@ export default (api) => { api.addRuntimePluginKey(() => 'request'); // 配置 api.describe({ + key: 'request', config: { schema(joi) { return joi.object({ @@ -15,7 +16,7 @@ export default (api) => { }); }, default: { - dataField: 'result' + dataField: '' } } }); @@ -29,7 +30,7 @@ export default (api) => { api.writeTmpFile({ path: absoluteFilePath, content: requestTemplate - .replace('REPLACE_DATA_FIELD', dataField) + .replace('REPLACE_DATA_FIELD', JSON.stringify(dataField)) }); }); diff --git a/packages/fes-plugin-request/src/template/cacheControl.js b/packages/fes-plugin-request/src/template/cacheControl.js index de2b8d2e..edc0e58d 100644 --- a/packages/fes-plugin-request/src/template/cacheControl.js +++ b/packages/fes-plugin-request/src/template/cacheControl.js @@ -44,7 +44,7 @@ const CACHE_TYPE = { local: 'localStorage' }; -const CACHE_DATA = new Map(); +const CACHE_DATA_MAP = new Map(); function genInnerKey(key, cacheType) { if (cacheType !== CACHE_TYPE.ram) { @@ -53,17 +53,18 @@ function genInnerKey(key, cacheType) { return key; } -function canCache(requestData) { - return isObject(requestData) || isString(requestData) || isURLSearchParams(requestData); +function canCache(data) { + return !data || isObject(data) || isString(data) || Array.isArray(data) || isURLSearchParams(data); } function setCacheData({ key, - cacheType, + cacheType = 'ram', data, cacheTime = 1000 * 60 * 3 }) { const _key = genInnerKey(key, cacheType); + const currentCacheData = { cacheType, data, @@ -83,7 +84,7 @@ function setCacheData({ } } } else { - CACHE_DATA.set(_key, currentCacheData); + CACHE_DATA_MAP.set(_key, currentCacheData); } } @@ -111,33 +112,36 @@ function getCacheData({ key, cacheType = 'ram' }) { return null; } } else { - const currentCacheData = CACHE_DATA.get(_key); + const currentCacheData = CACHE_DATA_MAP.get(_key); if (currentCacheData && !isExpire(currentCacheData)) { return currentCacheData.data; } - CACHE_DATA.delete(_key); + CACHE_DATA_MAP.delete(_key); return null; } } -export default (ctx, next) => { +export default async (ctx, next) => { const { config } = ctx; if (config.cache) { - const data = checkHttpRequestHasBody(config.method) ? config.data : config.params; - if (canCache(data)) { + const cacheData = getCacheData({ key: ctx.key, cacheType: config.cache.cacheType }); + if (cacheData) { ctx.response = { - data: getCacheData({ key: ctx.key, cacheType: config.cache.cacheType }) + data: cacheData }; return; } } - next(); + await next(); if (config.cache) { - setCacheData({ - key: ctx.key, - data: ctx.response.data, - ...config.cache - }); + const requestdata = checkHttpRequestHasBody(config.method) ? config.data : config.params; + if (ctx.response && canCache(requestdata) && canCache(ctx.response.data)) { + setCacheData({ + key: ctx.key, + data: ctx.response.data, + ...config.cache + }); + } } }; diff --git a/packages/fes-plugin-request/src/template/genRequestKey.js b/packages/fes-plugin-request/src/template/genRequestKey.js index 21e6b00c..db36fb6c 100644 --- a/packages/fes-plugin-request/src/template/genRequestKey.js +++ b/packages/fes-plugin-request/src/template/genRequestKey.js @@ -5,11 +5,11 @@ import { isURLSearchParams } from './helpers'; * 一个请求同时包含 data | params 参数的设计本身不合理 * 不对这种情况进行兼容 */ -export default function genRequestKey(ctx, next) { +export default async function genRequestKey(ctx, next) { const { url, data, method } = ctx.config; if (isURLSearchParams(data)) { ctx.key = `${url}${data.toString()}${method}`; } ctx.key = `${url}${JSON.stringify(data)}${method}`; - next(); + await next(); } diff --git a/packages/fes-plugin-request/src/template/paramsProcess.js b/packages/fes-plugin-request/src/template/paramsProcess.js index 08b34cd8..c68fa6f2 100644 --- a/packages/fes-plugin-request/src/template/paramsProcess.js +++ b/packages/fes-plugin-request/src/template/paramsProcess.js @@ -1,11 +1,11 @@ -import { checkHttpRequestHasBody, trimObj } from 'helpers'; +import { checkHttpRequestHasBody, trimObj } from './helpers'; -export default (ctx, next) => { +export default async (ctx, next) => { const config = ctx.config; if (checkHttpRequestHasBody(config.method)) { config.data = trimObj(config.data); } else { config.params = trimObj(config.params); } - next(); + await next(); }; diff --git a/packages/fes-plugin-request/src/template/preventRepeatReq.js b/packages/fes-plugin-request/src/template/preventRepeatReq.js index 910afd35..379a109b 100644 --- a/packages/fes-plugin-request/src/template/preventRepeatReq.js +++ b/packages/fes-plugin-request/src/template/preventRepeatReq.js @@ -1,17 +1,17 @@ -const requestQueue = new Map(); +const requestMap = new Map(); -export default (ctx, next) => { +export default async (ctx, next) => { const key = ctx.key; - if (requestQueue.get(key)) { + if (requestMap.get(key)) { ctx.error = { type: 'REPEAT', msg: '重复请求' }; return; } - requestQueue.set(key, true); + requestMap.set(key, true); - next(); + await next(); - requestQueue.delete(key); + requestMap.delete(key); }; diff --git a/packages/fes-plugin-request/src/template/request.js b/packages/fes-plugin-request/src/template/request.js index 3920e90e..aa894287 100644 --- a/packages/fes-plugin-request/src/template/request.js +++ b/packages/fes-plugin-request/src/template/request.js @@ -1,6 +1,6 @@ import axios from 'axios'; import { ApplyPluginsType, plugin } from '@webank/fes'; -import scheduler from 'scheduler'; +import scheduler from './scheduler'; import { checkHttpRequestHasBody, isFunction @@ -10,6 +10,7 @@ import setDataField from './setDataField'; import paramsProcess from './paramsProcess'; import genRequestKey from './genRequestKey'; import preventRepeatReq from './preventRepeatReq'; +import throttle from './throttle'; import cacheControl from './cacheControl'; import resDataAdaptor from './resDataAdaptor'; import resErrorProcess from './resErrorProcess'; @@ -32,22 +33,21 @@ function addResponseInterceptors(instance, interceptors) { addInterceptors(instance, interceptors, 'response'); } -function axiosMiddleware(context, next) { - context.instance.request(context.config).then((response) => { - context.response = response; - }).catch((error) => { +async function axiosMiddleware(context, next) { + try { + context.response = await context.instance.request(context.config); + } catch (error) { context.error = error; - }).finally(() => { - next(); - }); + } + await next(); } function getRequestInstance() { const { responseDataAdaptor, errorConfig, - requestInterceptors, - responseInterceptors, + requestInterceptors = [], + responseInterceptors = [], errorHandler, ...otherConfigs } = plugin.applyPlugins({ @@ -65,14 +65,15 @@ function getRequestInstance() { addRequestInterceptors(instance, requestInterceptors); addResponseInterceptors(instance, responseInterceptors); - scheduler.use(paramsProcess); - scheduler.use(genRequestKey); - scheduler.use(preventRepeatReq); - scheduler.use(cacheControl); - scheduler.use(axiosMiddleware); - scheduler.use(resDataAdaptor); - scheduler.use(resErrorProcess); - scheduler.use(setDataField); + scheduler.use(paramsProcess) + .use(genRequestKey) + .use(preventRepeatReq) + .use(throttle) + .use(cacheControl) + .use(axiosMiddleware) + .use(resDataAdaptor) + .use(resErrorProcess) + .use(setDataField); return { context: { @@ -96,6 +97,7 @@ function userConfigHandler(url, data, options = {}) { } else { options.params = data; } + return options; } let currentRequestInstance = null; @@ -117,10 +119,10 @@ export const request = (url, data, options = {}) => { const userConfig = userConfigHandler(url, data, options); const context = createContext(userConfig); - return currentRequestInstance.request(context).then((ctx) => { - if (!ctx.error) { - return ctx.config.useResonse ? ctx.response : ctx.response.data; + return currentRequestInstance.request(context).then(() => { + if (!context.error) { + return context.config.useResonse ? context.response : context.response.data; } - return Promise.reject(ctx.error); + return Promise.reject(context.error); }); }; diff --git a/packages/fes-plugin-request/src/template/resDataAdaptor.js b/packages/fes-plugin-request/src/template/resDataAdaptor.js index 004a495f..f52d81a8 100644 --- a/packages/fes-plugin-request/src/template/resDataAdaptor.js +++ b/packages/fes-plugin-request/src/template/resDataAdaptor.js @@ -1,8 +1,8 @@ import { isFunction, isObject, isString } from './helpers'; -export default ({ response, responseDataAdaptor }, next) => { +export default async ({ response, responseDataAdaptor }, next) => { if (isFunction(responseDataAdaptor) && (isObject(response.data) || isString(response.data))) { response.data = responseDataAdaptor(response.data); } - next(); + await next(); }; diff --git a/packages/fes-plugin-request/src/template/resErrorProcess.js b/packages/fes-plugin-request/src/template/resErrorProcess.js index 560d422f..9a1e213d 100644 --- a/packages/fes-plugin-request/src/template/resErrorProcess.js +++ b/packages/fes-plugin-request/src/template/resErrorProcess.js @@ -1,29 +1,19 @@ -import { isObject, isFunction } from 'helpers'; +import { isObject } from './helpers'; -function resErrorProcess(error, customerErrorHandler) { - if (isFunction(error)) { - error(); - } else { - customerErrorHandler && customerErrorHandler(error); - } -} - - -export default ({ +export default async ({ error, - errorConfig, - errorHandler, + errorHandler = {}, response }, next) => { - const _errorConfig = Object.assign({ - 403: '用户得到授权,但访问是禁止的' - }, errorConfig); - - if (isObject(response.data) && response.data.code !== '0') { - resErrorProcess(_errorConfig[response.data.code] || response.data.msg || response.data.errorMessage || response.data.errorMsg || '服务异常', errorHandler); - } else if (error && error.response && _errorConfig[error.response.status]) { - resErrorProcess(_errorConfig[error.response.status], errorHandler); + if (response && isObject(response.data) && response.data.code !== '0') { + errorHandler[response.data.code] && errorHandler[response.data.code](response); + } else if (error) { + if (error.type) { + errorHandler[error.type] && errorHandler[error.type](error); + } else if (error.response) { + errorHandler[error.response.status] && errorHandler[error.response.status](error); + } } - next(); + await next(); }; diff --git a/packages/fes-plugin-request/src/template/scheduler.js b/packages/fes-plugin-request/src/template/scheduler.js index b00906d1..5e62120d 100644 --- a/packages/fes-plugin-request/src/template/scheduler.js +++ b/packages/fes-plugin-request/src/template/scheduler.js @@ -30,4 +30,4 @@ class Scheduler { } } -export default Scheduler(); +export default new Scheduler(); diff --git a/packages/fes-plugin-request/src/template/setDataField.js b/packages/fes-plugin-request/src/template/setDataField.js index 07c71c20..3cbb76d8 100644 --- a/packages/fes-plugin-request/src/template/setDataField.js +++ b/packages/fes-plugin-request/src/template/setDataField.js @@ -1,10 +1,10 @@ import { isObject } from './helpers'; -export default (ctx, next) => { +export default async (ctx, next) => { const { dataField, response } = ctx; - if (isObject(response.data) && dataField) { + if (response && isObject(response.data) && dataField) { ctx.response._rawData = response.data; ctx.response.data = response.data[dataField]; } - next(); + await next(); }; diff --git a/packages/fes-plugin-request/src/template/throttle.js b/packages/fes-plugin-request/src/template/throttle.js new file mode 100644 index 00000000..1eb13b5d --- /dev/null +++ b/packages/fes-plugin-request/src/template/throttle.js @@ -0,0 +1,16 @@ + +const throttleMap = new Map(); + +export default async (ctx, next) => { + if (ctx.config.throttle) { + if (throttleMap.get(ctx.key) >= Date.now()) { + ctx.error = { + type: 'FREQUENTLY', + msg: '请求过于频繁' + }; + return; + } + } + await next(); + throttleMap.set(ctx.key, Date.now() + ctx.config.throttle); +}; diff --git a/packages/fes-preset-built-in/package.json b/packages/fes-preset-built-in/package.json index 7fb27eb5..c0d875c8 100644 --- a/packages/fes-preset-built-in/package.json +++ b/packages/fes-preset-built-in/package.json @@ -30,7 +30,7 @@ "@vue/babel-plugin-jsx": "^1.0.0-rc.5", "@vue/compiler-sfc": "^3.0.4", "@vue/preload-webpack-plugin": "1.1.2", - "@webank/fes-core": "^2.0.0", + "@webank/fes-compiler": "^2.0.0", "cliui": "6.0.0", "html-webpack-plugin": "^3.2.0", "html-webpack-tags-plugin": "2.0.17", diff --git a/packages/fes-preset-built-in/src/plugins/commands/build/index.js b/packages/fes-preset-built-in/src/plugins/commands/build/index.js index b613ec16..e6236bfd 100644 --- a/packages/fes-preset-built-in/src/plugins/commands/build/index.js +++ b/packages/fes-preset-built-in/src/plugins/commands/build/index.js @@ -1,6 +1,6 @@ import { relative } from 'path'; import { existsSync } from 'fs'; -import { Logger } from '@webank/fes-core'; +import { Logger } from '@webank/fes-compiler'; import { cleanTmpPathExceptCache, getBundleAndConfigs, diff --git a/packages/fes-preset-built-in/src/plugins/commands/dev/watchPkg.js b/packages/fes-preset-built-in/src/plugins/commands/dev/watchPkg.js index 4573ad41..3a5b911b 100644 --- a/packages/fes-preset-built-in/src/plugins/commands/dev/watchPkg.js +++ b/packages/fes-preset-built-in/src/plugins/commands/dev/watchPkg.js @@ -1,7 +1,7 @@ import { join } from 'path'; import { chokidar, winPath, lodash } from '@umijs/utils'; import { existsSync, readFileSync } from 'fs'; -import { isPluginOrPreset, PluginType } from '@webank/fes-core'; +import { isPluginOrPreset, PluginType } from '@webank/fes-compiler'; function getPlugins(opts) { return Object.keys({ diff --git a/packages/fes-template-h5/.fes.js b/packages/fes-template-h5/.fes.js index 8e65ef6d..ff0906c4 100644 --- a/packages/fes-template-h5/.fes.js +++ b/packages/fes-template-h5/.fes.js @@ -7,6 +7,9 @@ export default { // __VUE_OPTIONS_API__: true, // __VUE_PROD_DEVTOOLS__: false }, + request: { + dataField: 'fileTemplateList' + }, html: { options: { title: '海贼王' diff --git a/packages/fes-template-h5/package.json b/packages/fes-template-h5/package.json index c6fc0b1f..eaac4cda 100644 --- a/packages/fes-template-h5/package.json +++ b/packages/fes-template-h5/package.json @@ -35,6 +35,7 @@ "dependencies": { "vue": "^3.0.4", "@webank/fes": "^2.0.0", - "@webank/fes-plugin-icon": "^1.0.0" + "@webank/fes-plugin-icon": "^1.0.0", + "@webank/fes-plugin-request": "^1.0.0" } } diff --git a/packages/fes-template-h5/src/app.js b/packages/fes-template-h5/src/app.js index e69de29b..140e25e5 100644 --- a/packages/fes-template-h5/src/app.js +++ b/packages/fes-template-h5/src/app.js @@ -0,0 +1,7 @@ +export const request = { + errorConfig: { + 404() { + console.log('to 404 page'); + } + } +}; diff --git a/packages/fes-template-h5/src/page/index.vue b/packages/fes-template-h5/src/page/index.vue index 3e5f081e..49832b68 100644 --- a/packages/fes-template-h5/src/page/index.vue +++ b/packages/fes-template-h5/src/page/index.vue @@ -12,8 +12,7 @@