From 2ee1b659a0bb046b3f88a85fe3be0972abca9b19 Mon Sep 17 00:00:00 2001 From: bac-joker Date: Tue, 29 Dec 2020 21:27:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20request=20?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/fes-core/src/service/getPaths.js | 3 ++- .../src/template/cacheControl.js | 8 +++----- .../src/template/genRequestKey.js | 15 +++++++++++++++ .../fes-plugin-request/src/template/helpers.js | 13 ------------- .../src/template/preventRepeatReq.js | 17 +++++++++++++++++ .../fes-plugin-request/src/template/request.js | 6 ++++++ packages/fes-preset-built-in/src/index.js | 1 + .../src/plugins/features/define.js | 4 ++++ .../src/plugins/features/singular.js | 12 ++++++++++++ .../src/plugins/misc/route/index.js | 15 ++++++++------- packages/fes-template-h5/.fes.js | 4 ++++ 11 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 packages/fes-plugin-request/src/template/genRequestKey.js create mode 100644 packages/fes-plugin-request/src/template/preventRepeatReq.js create mode 100644 packages/fes-preset-built-in/src/plugins/features/singular.js diff --git a/packages/fes-core/src/service/getPaths.js b/packages/fes-core/src/service/getPaths.js index 5e725ecd..47cc2c45 100644 --- a/packages/fes-core/src/service/getPaths.js +++ b/packages/fes-core/src/service/getPaths.js @@ -19,7 +19,8 @@ export default function getServicePaths({ if (isDirectoryAndExist(join(cwd, 'src'))) { absSrcPath = join(cwd, 'src'); } - const absPagesPath = config.singular + + const absPagesPath = config.singular !== false ? join(absSrcPath, 'page') : join(absSrcPath, 'pages'); diff --git a/packages/fes-plugin-request/src/template/cacheControl.js b/packages/fes-plugin-request/src/template/cacheControl.js index e7f60969..de2b8d2e 100644 --- a/packages/fes-plugin-request/src/template/cacheControl.js +++ b/packages/fes-plugin-request/src/template/cacheControl.js @@ -1,5 +1,5 @@ import { - genRequestKey, isObject, isString, isURLSearchParams, checkHttpRequestHasBody + isObject, isString, isURLSearchParams, checkHttpRequestHasBody } from './helpers'; /** * 缓存实现的功能 @@ -122,13 +122,11 @@ function getCacheData({ key, cacheType = 'ram' }) { export default (ctx, next) => { const { config } = ctx; - let requestKey; if (config.cache) { const data = checkHttpRequestHasBody(config.method) ? config.data : config.params; - requestKey = genRequestKey(config.url, data, config.method); if (canCache(data)) { ctx.response = { - data: getCacheData({ key: requestKey, cacheType: config.cache.cacheType }) + data: getCacheData({ key: ctx.key, cacheType: config.cache.cacheType }) }; return; } @@ -137,7 +135,7 @@ export default (ctx, next) => { if (config.cache) { setCacheData({ - key: requestKey, + 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 new file mode 100644 index 00000000..21e6b00c --- /dev/null +++ b/packages/fes-plugin-request/src/template/genRequestKey.js @@ -0,0 +1,15 @@ +import { isURLSearchParams } from './helpers'; +/** + * 唯一定位一个请求(url, data | params, method) + * 其中请求参数(data, params)根据请求方法,只使用其中一个 + * 一个请求同时包含 data | params 参数的设计本身不合理 + * 不对这种情况进行兼容 + */ +export default 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(); +} diff --git a/packages/fes-plugin-request/src/template/helpers.js b/packages/fes-plugin-request/src/template/helpers.js index 8b4944ee..c0314996 100644 --- a/packages/fes-plugin-request/src/template/helpers.js +++ b/packages/fes-plugin-request/src/template/helpers.js @@ -90,16 +90,3 @@ export function trimObj(obj) { }); } } - -/** - * 唯一定位一个请求(url, data | params, method) - * 其中请求参数(data, params)根据请求方法,只使用其中一个 - * 一个请求同时包含 data | params 参数的设计本身不合理 - * 不对这种情况进行兼容 - */ -export function genRequestKey(url, data, method) { - if (isURLSearchParams(data)) { - return `${url}${data.toString()}${method}`; - } - return `${url}${JSON.stringify(data)}${method}`; -} diff --git a/packages/fes-plugin-request/src/template/preventRepeatReq.js b/packages/fes-plugin-request/src/template/preventRepeatReq.js new file mode 100644 index 00000000..910afd35 --- /dev/null +++ b/packages/fes-plugin-request/src/template/preventRepeatReq.js @@ -0,0 +1,17 @@ +const requestQueue = new Map(); + +export default (ctx, next) => { + const key = ctx.key; + if (requestQueue.get(key)) { + ctx.error = { + type: 'REPEAT', + msg: '重复请求' + }; + return; + } + requestQueue.set(key, true); + + next(); + + requestQueue.delete(key); +}; diff --git a/packages/fes-plugin-request/src/template/request.js b/packages/fes-plugin-request/src/template/request.js index 5229c64d..3920e90e 100644 --- a/packages/fes-plugin-request/src/template/request.js +++ b/packages/fes-plugin-request/src/template/request.js @@ -8,6 +8,9 @@ import { import setDataField from './setDataField'; import paramsProcess from './paramsProcess'; +import genRequestKey from './genRequestKey'; +import preventRepeatReq from './preventRepeatReq'; +import cacheControl from './cacheControl'; import resDataAdaptor from './resDataAdaptor'; import resErrorProcess from './resErrorProcess'; @@ -63,6 +66,9 @@ function getRequestInstance() { addResponseInterceptors(instance, responseInterceptors); scheduler.use(paramsProcess); + scheduler.use(genRequestKey); + scheduler.use(preventRepeatReq); + scheduler.use(cacheControl); scheduler.use(axiosMiddleware); scheduler.use(resDataAdaptor); scheduler.use(resErrorProcess); diff --git a/packages/fes-preset-built-in/src/index.js b/packages/fes-preset-built-in/src/index.js index 15c242d2..3b256beb 100644 --- a/packages/fes-preset-built-in/src/index.js +++ b/packages/fes-preset-built-in/src/index.js @@ -44,6 +44,7 @@ export default function () { require.resolve('./plugins/features/proxy'), require.resolve('./plugins/features/publicPath'), require.resolve('./plugins/features/styleLoader'), + require.resolve('./plugins/features/singular'), require.resolve('./plugins/features/targets'), require.resolve('./plugins/features/terserOptions'), require.resolve('./plugins/features/vueLoader'), diff --git a/packages/fes-preset-built-in/src/plugins/features/define.js b/packages/fes-preset-built-in/src/plugins/features/define.js index df8a082a..e8b2ea01 100644 --- a/packages/fes-preset-built-in/src/plugins/features/define.js +++ b/packages/fes-preset-built-in/src/plugins/features/define.js @@ -5,6 +5,10 @@ export default (api) => { config: { schema(joi) { return joi.object(); + }, + default: { + __VUE_OPTIONS_API__: true, + __VUE_PROD_DEVTOOLS__: false } } }); diff --git a/packages/fes-preset-built-in/src/plugins/features/singular.js b/packages/fes-preset-built-in/src/plugins/features/singular.js new file mode 100644 index 00000000..fd835dab --- /dev/null +++ b/packages/fes-preset-built-in/src/plugins/features/singular.js @@ -0,0 +1,12 @@ +export default (api) => { + api.describe({ + key: 'singular', + config: { + default: {}, + schema(joi) { + return joi + .boolean(); + } + } + }); +}; diff --git a/packages/fes-preset-built-in/src/plugins/misc/route/index.js b/packages/fes-preset-built-in/src/plugins/misc/route/index.js index f516c629..d978fe30 100644 --- a/packages/fes-preset-built-in/src/plugins/misc/route/index.js +++ b/packages/fes-preset-built-in/src/plugins/misc/route/index.js @@ -47,8 +47,9 @@ const getRouteName = function (parentRoutePath, fileName) { .replace(/\*/g, 'FUZZYMATCH'); }; -const getComponentPath = function (parentRoutePath, fileName) { - return posix.join('@/pages/', parentRoutePath, fileName); +const getComponentPath = function (parentRoutePath, fileName, config) { + const pagesName = config.singular ? 'page' : 'pages'; + return posix.join(`@/${pagesName}/`, parentRoutePath, fileName); }; const getRoutePath = function (parentRoutePath, fileName) { @@ -67,7 +68,7 @@ const getRoutePath = function (parentRoutePath, fileName) { }; // TODO 约定 layout 目录作为布局文件夹, -const genRoutes = function (parentRoutes, path, parentRoutePath) { +const genRoutes = function (parentRoutes, path, parentRoutePath, config) { const dirList = readdirSync(path); const hasLayout = checkHasLayout(path); const layoutRoute = { @@ -91,7 +92,7 @@ const genRoutes = function (parentRoutes, path, parentRoutePath) { const routePath = getRoutePath(parentRoutePath, fileName); // 路由名称 const routeName = getRouteName(parentRoutePath, fileName); - const componentPath = getComponentPath(parentRoutePath, fileName); + const componentPath = getComponentPath(parentRoutePath, fileName, config); if (hasLayout) { if (fileName === 'layout') { layoutRoute.component = componentPath; @@ -120,9 +121,9 @@ const genRoutes = function (parentRoutes, path, parentRoutePath) { const component = join(path, item); const nextParentRouteUrl = posix.join(parentRoutePath, item); if (hasLayout) { - genRoutes(layoutRoute.children, component, nextParentRouteUrl); + genRoutes(layoutRoute.children, component, nextParentRouteUrl, config); } else { - genRoutes(parentRoutes, component, nextParentRouteUrl); + genRoutes(parentRoutes, component, nextParentRouteUrl, config); } } }); @@ -172,7 +173,7 @@ const getRoutes = function ({ config, absPagesPath }) { if (config.routes) return config.routes; const routes = []; - genRoutes(routes, absPagesPath, '/'); + genRoutes(routes, absPagesPath, '/', config); fix(routes); return routes; }; diff --git a/packages/fes-template-h5/.fes.js b/packages/fes-template-h5/.fes.js index 30d8f23d..8e65ef6d 100644 --- a/packages/fes-template-h5/.fes.js +++ b/packages/fes-template-h5/.fes.js @@ -3,6 +3,10 @@ import pxtoviewport from 'postcss-px-to-viewport'; export default { + define: { + // __VUE_OPTIONS_API__: true, + // __VUE_PROD_DEVTOOLS__: false + }, html: { options: { title: '海贼王'