如何在终端中抑制 Vue/Webpack 开发服务器代理错误消息?
How can I supress Vue/Webpack dev server proxy error messages in the terminal?
我的应用程序使用端到端测试框架 (Cypress),它在
终端。当测试对前端代码的更改时,我使用 Vue 开发服务器的
proxy
用于将 API 请求路由到远程后端服务器的选项。
由于请求的高负载冲击了这个测试服务器,我们的应用程序
前端预计某些请求会失败,并且它能够
智能处理给定失败的 API 调用的重试。然而,代理
处理程序不知道这一点,因此控制台日志变得混乱
ECONNRESET
代理错误,如下所示。
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
✓ C22756 should be disabled when no events exist (8018ms)
✓ C22757 should be clickable when events exist (2250ms)
Widget Settings
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
✓ C22758 should have name, date range, and account fields (2435ms)
这些错误可能会变得非常冗长,并且往往 hide/obscure 越简洁
测试输出,使其难以扫描并且几乎无法复制
有效。
有什么方法可以抑制来自开发人员的这些错误消息 server/proxy
handler? 理想情况下,NPM 脚本中会有某种形式的配置
或允许我忽略或隐藏这些的 Vue/Webpack 配置 JS 文件
运行 我们的测试套件出现错误。
作为参考,这里是传递给 vue.config.js
的配置对象
文件的 devServer
属性:
const config = {
allowedHosts: ['localhost', 'local.myapp.io'],
contentBase: path.join(__dirname, 'root/of/frontend/code'),
disableHostCheck: true,
historyApiFallback: true,
https: {
cert: LocalDevCert.getCert(),
key: LocalDevCert.getKey()
},
port: 3000,
proxy: {
'^(?!/(js|modules|img))': {
target: 'https://myapp-dev.appspot.com',
cookieDomainRewrite: 'local.myapp.io',
changeOrigin: true,
secure: true,
bypass (req, res) {
const xsrfToken = uuid();
if (req.headers.accept && req.headers.accept.includes('html')) {
res.cookie('MyXSRFToken', xsrfToken);
res.cookie('MyXSRFToken_C80', xsrfToken);
return '/index.html';
}
if (req.method === 'GET' && req.url.includes('login') && !req.url.includes('google')) {
res.cookie('MyXSRFToken', xsrfToken);
res.cookie('MyXSRFToken_C80', xsrfToken);
return '/';
}
}
}
},
public: 'local.myapp.io:3000'
};
我试过:
- 使用 devServer.client.logging configuration option,但这只会改变浏览器控制台(而不是命令行终端)中显示的内容。
- 将logLevel configuration option添加到相应的代理配置对象(即上面带有键
^(?!/(js|modules|img))
的对象),但这似乎只是增加的数量日志记录(信息和错误)。
我怀疑某些东西需要在较低的层次上被抑制,也许一些 bash-脚本魔法是唯一可行的解决方案。
您可以在测试顶部或全局添加过滤器 /cypress/support/index.js
。
Cypress.on('window:before:load', window => {
const originalConsoleLog = window.console.log;
window.console.log = (msg) => {
const isProxyError = msg.includes('ECONNRESET') || msg.startsWith('Proxy error:');
if (!isProxyError) {
originalConsoleLog(msg)
}
}
})
我最终确定的解决方法是在配置的 Javascript 文件中拦截 process.stdout.write
和 运行 开发人员 server/tests。由于我们的 test
命令是作为 Vue CLI 插件实现的,我可以将覆盖函数放在该插件的 module.exports
中,如下所示:
module.exports = (api, options) => {
api.registerCommand(
'customTestCommand',
{
description: 'A test command for posting on Stack Overflow',
usage: 'vue-cli-service customTestCommand [options]',
options: {
'--headless': 'run in headless mode without GUI'
...
}
},
async (args, rawArgs) => {
// Do other setup work here
process.stdout.write = (function (write) {
let clearBlankLine = false;
return function (...args) {
const string = args[0];
const isProxyError = !!string.match(/Proxy error:|ECONNRESET/);
const hasContent = !!string.trim();
if (isProxyError) {
clearBlankLine = true;
return;
}
if (!clearBlankLine || hasContent) {
write.apply(process.stdout, args);
}
clearBlankLine = false;
};
}(process.stdout.write));
// Wait to run your actual dev server process and test commands
// Until here.
}
);
};
这会在命令行输出中保留所有颜色、间距、历史记录清除等,但删除任何包含术语 Proxy Error
或 ECONNRESET
的行。您可以根据自己的具体需要自定义正则表达式。
有关拦截 stdout 和 stderr 以及将这些输出重定向到不同位置(例如文件)的更详细示例,请参阅以下 Github Ben Buckman 的要点,它启发了我的解决方案:https://gist.github.com/benbuckman/2758563
我的应用程序使用端到端测试框架 (Cypress),它在
终端。当测试对前端代码的更改时,我使用 Vue 开发服务器的
proxy
用于将 API 请求路由到远程后端服务器的选项。
由于请求的高负载冲击了这个测试服务器,我们的应用程序
前端预计某些请求会失败,并且它能够
智能处理给定失败的 API 调用的重试。然而,代理
处理程序不知道这一点,因此控制台日志变得混乱
ECONNRESET
代理错误,如下所示。
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
✓ C22756 should be disabled when no events exist (8018ms)
✓ C22757 should be clickable when events exist (2250ms)
Widget Settings
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
✓ C22758 should have name, date range, and account fields (2435ms)
这些错误可能会变得非常冗长,并且往往 hide/obscure 越简洁 测试输出,使其难以扫描并且几乎无法复制 有效。
有什么方法可以抑制来自开发人员的这些错误消息 server/proxy handler? 理想情况下,NPM 脚本中会有某种形式的配置 或允许我忽略或隐藏这些的 Vue/Webpack 配置 JS 文件 运行 我们的测试套件出现错误。
作为参考,这里是传递给 vue.config.js
的配置对象
文件的 devServer
属性:
const config = {
allowedHosts: ['localhost', 'local.myapp.io'],
contentBase: path.join(__dirname, 'root/of/frontend/code'),
disableHostCheck: true,
historyApiFallback: true,
https: {
cert: LocalDevCert.getCert(),
key: LocalDevCert.getKey()
},
port: 3000,
proxy: {
'^(?!/(js|modules|img))': {
target: 'https://myapp-dev.appspot.com',
cookieDomainRewrite: 'local.myapp.io',
changeOrigin: true,
secure: true,
bypass (req, res) {
const xsrfToken = uuid();
if (req.headers.accept && req.headers.accept.includes('html')) {
res.cookie('MyXSRFToken', xsrfToken);
res.cookie('MyXSRFToken_C80', xsrfToken);
return '/index.html';
}
if (req.method === 'GET' && req.url.includes('login') && !req.url.includes('google')) {
res.cookie('MyXSRFToken', xsrfToken);
res.cookie('MyXSRFToken_C80', xsrfToken);
return '/';
}
}
}
},
public: 'local.myapp.io:3000'
};
我试过:
- 使用 devServer.client.logging configuration option,但这只会改变浏览器控制台(而不是命令行终端)中显示的内容。
- 将logLevel configuration option添加到相应的代理配置对象(即上面带有键
^(?!/(js|modules|img))
的对象),但这似乎只是增加的数量日志记录(信息和错误)。
我怀疑某些东西需要在较低的层次上被抑制,也许一些 bash-脚本魔法是唯一可行的解决方案。
您可以在测试顶部或全局添加过滤器 /cypress/support/index.js
。
Cypress.on('window:before:load', window => {
const originalConsoleLog = window.console.log;
window.console.log = (msg) => {
const isProxyError = msg.includes('ECONNRESET') || msg.startsWith('Proxy error:');
if (!isProxyError) {
originalConsoleLog(msg)
}
}
})
我最终确定的解决方法是在配置的 Javascript 文件中拦截 process.stdout.write
和 运行 开发人员 server/tests。由于我们的 test
命令是作为 Vue CLI 插件实现的,我可以将覆盖函数放在该插件的 module.exports
中,如下所示:
module.exports = (api, options) => {
api.registerCommand(
'customTestCommand',
{
description: 'A test command for posting on Stack Overflow',
usage: 'vue-cli-service customTestCommand [options]',
options: {
'--headless': 'run in headless mode without GUI'
...
}
},
async (args, rawArgs) => {
// Do other setup work here
process.stdout.write = (function (write) {
let clearBlankLine = false;
return function (...args) {
const string = args[0];
const isProxyError = !!string.match(/Proxy error:|ECONNRESET/);
const hasContent = !!string.trim();
if (isProxyError) {
clearBlankLine = true;
return;
}
if (!clearBlankLine || hasContent) {
write.apply(process.stdout, args);
}
clearBlankLine = false;
};
}(process.stdout.write));
// Wait to run your actual dev server process and test commands
// Until here.
}
);
};
这会在命令行输出中保留所有颜色、间距、历史记录清除等,但删除任何包含术语 Proxy Error
或 ECONNRESET
的行。您可以根据自己的具体需要自定义正则表达式。
有关拦截 stdout 和 stderr 以及将这些输出重定向到不同位置(例如文件)的更详细示例,请参阅以下 Github Ben Buckman 的要点,它启发了我的解决方案:https://gist.github.com/benbuckman/2758563