fix: 修复proxy丢失body和fallbackIndex影响proxy的bug

This commit is contained in:
万纯 2021-04-09 11:12:23 +08:00
parent d21c00a558
commit ba3016105d
6 changed files with 103 additions and 67 deletions

View File

@ -4,13 +4,17 @@ import historyFallback from 'connect-history-api-fallback';
const ASSET_EXTNAMES = ['.ico', '.png', '.jpg', '.jpeg', '.gif', '.svg']; const ASSET_EXTNAMES = ['.ico', '.png', '.jpg', '.jpeg', '.gif', '.svg'];
export default () => (req, res, next) => { export default api => (req, res, next) => {
const proxyConfig = api.config.proxy;
if (proxyConfig && Object.keys(proxyConfig).some(path => req.path.startsWith(path))) {
return next();
}
if (req.path === '/favicon.ico') { if (req.path === '/favicon.ico') {
res.sendFile(join(__dirname, 'fes.png')); return res.sendFile(join(__dirname, 'fes.png'));
} else if (ASSET_EXTNAMES.includes(extname(req.path))) { }
next(); if (ASSET_EXTNAMES.includes(extname(req.path))) {
} else { return next();
}
const history = historyFallback(); const history = historyFallback();
history(req, res, next); history(req, res, next);
}
}; };

View File

@ -176,7 +176,7 @@ export default (api) => {
port, port,
proxy: api.config.proxy, proxy: api.config.proxy,
https: isHTTPS, https: isHTTPS,
beforeMiddlewares: [...beforeMiddlewares, createRouteMiddleware()], beforeMiddlewares: [...beforeMiddlewares, createRouteMiddleware(api)],
afterMiddlewares: [...middlewares], afterMiddlewares: [...middlewares],
customerDevServerConfig: api.config.devServer customerDevServerConfig: api.config.devServer
}); });

View File

@ -0,0 +1,17 @@
export default (api) => {
api.describe({
key: 'exportStatic',
config: {
schema(joi) {
return joi.object({
htmlSuffix: joi.boolean(),
dynamicRoot: joi.boolean()
});
}
},
// TODO: api.EnableBy.config 读取的 userConfigmodifyDefaultConfig hook 修改后对这个判断不起效
enableBy: () => ('exportStatic' in api.userConfig
? api.userConfig.exportStatic
: api.config?.exportStatic)
});
};

View File

@ -45,7 +45,9 @@ export default (api) => {
val.forEach(callback); val.forEach(callback);
} }
if (lodash.isPlainObject(val)) { if (lodash.isPlainObject(val)) {
Object.keys(val).forEach((key) => { callback(val[key], key); }); Object.keys(val).forEach((key) => {
callback(val[key], key);
});
} }
} }
@ -67,9 +69,12 @@ export default (api) => {
if (lodash.isPlainObject(newOption)) { if (lodash.isPlainObject(newOption)) {
traversalHandler(newOption, (value, key) => { traversalHandler(newOption, (value, key) => {
if (key === 'headers') { if (key === 'headers') {
traversalHandler(newOption.headers, (headervalue, headerkey) => { traversalHandler(
newOption.headers,
(headervalue, headerkey) => {
option.headers[headerkey] = newOption.headers[headerkey]; option.headers[headerkey] = newOption.headers[headerkey];
}); }
);
} else { } else {
option[key] = newOption[key]; option[key] = newOption[key];
} }
@ -102,11 +107,14 @@ export default (api) => {
// mock打开情况下配置的过滤前缀 // mock打开情况下配置的过滤前缀
const mockPrefixTemp = api.config.mock.prefix || mockPrefix; const mockPrefixTemp = api.config.mock.prefix || mockPrefix;
mockPrefix = mockPrefixTemp === mockPrefix ? mockPrefixTemp : `${mockPrefixTemp}/`; mockPrefix = mockPrefixTemp === mockPrefix
? mockPrefixTemp
: `${mockPrefixTemp}/`;
// mock文件处理 // mock文件处理
mockFile = parsePath('./mock.js'); mockFile = parsePath('./mock.js');
if (!existsSync(mockFile)) { if (!existsSync(mockFile)) {
api.logger.info('mock.js File does not exist, please check'); return; api.logger.info('mock.js File does not exist, please check');
return;
} }
// 清除require的缓存保证 mock 文件修改后拿到最新的 mock.js // 清除require的缓存保证 mock 文件修改后拿到最新的 mock.js
if (require.cache[mockFile]) { if (require.cache[mockFile]) {
@ -119,7 +127,8 @@ export default (api) => {
const _initFunction = require(mockFile); const _initFunction = require(mockFile);
const initFunction = _initFunction.default || _initFunction; const initFunction = _initFunction.default || _initFunction;
if (!lodash.isFunction(initFunction)) { if (!lodash.isFunction(initFunction)) {
api.logger.info('mock.js should export Function'); return; api.logger.info('mock.js should export Function');
return;
} }
initFunction({ cgiMock, mockjs, utils }); initFunction({ cgiMock, mockjs, utils });
} catch (err) { } catch (err) {
@ -132,11 +141,14 @@ export default (api) => {
return next(); return next();
} }
// 请求以 cgiMock.prefix 开头,匹配处理 // 请求以 cgiMock.prefix 开头,匹配处理
const matchRequet = requestList.find(item => req.path.search(item.url) !== -1); const matchRequet = requestList.find(
item => req.path.search(item.url) !== -1
);
if (!matchRequet) { if (!matchRequet) {
return next(); return next();
} }
const sendData = () => {
// set header // set header
res.set(matchRequet.headers); res.set(matchRequet.headers);
// set Content-Type // set Content-Type
@ -156,7 +168,8 @@ export default (api) => {
if (lodash.isFunction(matchRequet.result)) { if (lodash.isFunction(matchRequet.result)) {
matchRequet.result(req, res); matchRequet.result(req, res);
} else if ( } else if (
lodash.isArray(matchRequet.result) || lodash.isPlainObject(matchRequet.result) lodash.isArray(matchRequet.result)
|| lodash.isPlainObject(matchRequet.result)
) { ) {
!matchRequet.type && res.type('json'); !matchRequet.type && res.type('json');
res.json(matchRequet.result); res.json(matchRequet.result);
@ -165,32 +178,35 @@ export default (api) => {
res.send(matchRequet.result.toString()); res.send(matchRequet.result.toString());
} }
}; };
bodyParser.json({ strict: false })(req, res, () => {
bodyParser.urlencoded({ extended: true })(req, res, () => {
cookieParser()(req, res, () => {
sendData();
});
});
});
};
}; };
api.onStart(() => { api.onStart(() => {
// 获取mock配置: 是否打开 // 获取mock配置: 是否打开
mockFlag = lodash.isPlainObject(api.config.mock) ? true : api.config.mock; mockFlag = lodash.isPlainObject(api.config.mock)
? true
: api.config.mock;
if (!mockFlag) return; if (!mockFlag) return;
loadMock = createMock(); loadMock = createMock();
return chokidar.watch(mockFile, { return chokidar
.watch(mockFile, {
ignoreInitial: true ignoreInitial: true
}).on('change', () => { })
.on('change', () => {
api.logger.info('mock.js changedreload'); api.logger.info('mock.js changedreload');
loadMock = createMock(); loadMock = createMock();
}); });
}); });
api.addBeforeMiddlewares(() => {
if (!mockFlag) return [];
return [
bodyParser.json(),
bodyParser.urlencoded({
extended: false
}),
cookieParser()
];
});
api.addBeforeMiddlewares(() => (req, res, next) => { api.addBeforeMiddlewares(() => (req, res, next) => {
if (!mockFlag) return next(); if (!mockFlag) return next();
loadMock(req, res, next); loadMock(req, res, next);

View File

@ -4,11 +4,7 @@ export default (api) => {
key: 'proxy', key: 'proxy',
config: { config: {
onChange: () => { onChange: () => {
const server = api.getServer(); // todo 重新执行proxy的逻辑
if (server) {
// refrest proxy service
server.setupProxy(api.config.proxy, true);
}
}, },
schema(joi) { schema(joi) {
return joi.object(); return joi.object();

View File

@ -92,14 +92,17 @@ export default {
}).catch((err) => { }).catch((err) => {
console.log(err); console.log(err);
}); });
request('/v2/movie/in_theaters_mock').then((data) => { request('/v2/movie/in_theaters_mock', { a: 1 }, 'get').then((data) => {
console.log(data); console.log(data);
}).catch((err) => { }).catch((err) => {
console.log(err); console.log(err);
}); });
console.log('测试 proxy!!'); console.log('测试 proxy!!');
request('/v2/movie/in_theaters_proxy').then((resp) => { request('/v2/movie/in_theaters_proxy', { a: 1 }, {
method: 'get',
headers: { Accept: '*/*' }
}).then((resp) => {
console.log(resp); console.log(resp);
}).catch((err) => { }).catch((err) => {
console.log(err); console.log(err);