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) => {
if (req.path === '/favicon.ico') { const proxyConfig = api.config.proxy;
res.sendFile(join(__dirname, 'fes.png')); if (proxyConfig && Object.keys(proxyConfig).some(path => req.path.startsWith(path))) {
} else if (ASSET_EXTNAMES.includes(extname(req.path))) { return next();
next();
} else {
const history = historyFallback();
history(req, res, next);
} }
if (req.path === '/favicon.ico') {
return res.sendFile(join(__dirname, 'fes.png'));
}
if (ASSET_EXTNAMES.includes(extname(req.path))) {
return next();
}
const history = historyFallback();
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(
option.headers[headerkey] = newOption.headers[headerkey]; newOption.headers,
}); (headervalue, 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,65 +141,72 @@ 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();
} }
// set header const sendData = () => {
res.set(matchRequet.headers); // set header
// set Content-Type res.set(matchRequet.headers);
matchRequet.type && res.type(matchRequet.type); // set Content-Type
// set status code matchRequet.type && res.type(matchRequet.type);
res.status(matchRequet.statusCode); // set status code
// set cookie res.status(matchRequet.statusCode);
traversalHandler(matchRequet.cookies, (item) => { // set cookie
const name = item.name; traversalHandler(matchRequet.cookies, (item) => {
const value = item.value; const name = item.name;
delete item.name; const value = item.value;
delete item.value; delete item.name;
res.cookie(name, value, item); delete item.value;
}); res.cookie(name, value, item);
});
// do result // do result
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'); ) {
res.json(matchRequet.result); !matchRequet.type && res.type('json');
} else { res.json(matchRequet.result);
!matchRequet.type && res.type('text'); } else {
res.send(matchRequet.result.toString()); !matchRequet.type && res.type('text');
} 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
ignoreInitial: true .watch(mockFile, {
}).on('change', () => { ignoreInitial: true
api.logger.info('mock.js changedreload'); })
loadMock = createMock(); .on('change', () => {
}); api.logger.info('mock.js changedreload');
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);