【发布时间】:2023-04-11 04:25:01
【问题描述】:
有没有办法在开发模式下运行 create-react-app 时禁用错误覆盖?
这就是我说的叠加层:
我问这个是因为我在我的应用程序中使用错误边界 (React 16 Error Boundaries) 在组件崩溃时显示错误消息,但错误覆盖弹出并覆盖了我的消息。
【问题讨论】:
标签: create-react-app
有没有办法在开发模式下运行 create-react-app 时禁用错误覆盖?
这就是我说的叠加层:
我问这个是因为我在我的应用程序中使用错误边界 (React 16 Error Boundaries) 在组件崩溃时显示错误消息,但错误覆盖弹出并覆盖了我的消息。
【问题讨论】:
标签: create-react-app
我们不提供在开发过程中禁用错误覆盖的选项。 错误边界不会取代它(它们是为了生产使用)。
开发错误覆盖和错误边界都没有害处;如果您想查看错误边界,只需按 Escape。
我们认为错误覆盖在您的典型错误边界(源代码、点击打开等)上提供了巨大的价值。 在我们探索将热组件重新加载作为所有用户的默认行为时,这一点也很重要。
如果您强烈反对禁用覆盖,则需要退出 react-scripts 并停止使用 webpackHotDevClient。一种侵入性较小的方法可能是移除 window 的覆盖层安装的 error 事件侦听器。
【讨论】:
A less intrusive method may be removing the error event listener installed by the overlay off of window 你能告诉我怎么做吗(代码示例)?谢谢!
另一种解决方案是添加以下 CSS 样式:
iframe
{
display: none;
}
这可以防止错误显示。
【讨论】:
可以使用react-error-overlay 包中的stopReportingRuntimeErrors 辅助实用程序禁用错误覆盖。
首先,安装 react-error-overlay 包:
yarn add react-error-overlay
然后在 index.js 中——在安装根 React 组件之前,导入实用程序并像这样调用它:
import { stopReportingRuntimeErrors } from "react-error-overlay";
if (process.env.NODE_ENV === "development") {
stopReportingRuntimeErrors(); // disables error overlays
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
现在应该禁用 create-react-app 中的错误覆盖。
【讨论】:
Uncaught Error: Not currently listening 和index.js:1 Uncaught Error: Expected options to be injected. 中看到一个空白屏幕和错误
您可以通过first捕获事件来抑制 React 的错误事件处理。
例如,通过放入public/index.html 的<head>:
<script>
window.addEventListener('error', function(e){
// prevent React's listener from firing
e.stopImmediatePropagation();
// prevent the browser's console error message
e.preventDefault();
});
</script>
由于您可能仍希望 React 的错误覆盖超出错误边界的错误,请考虑以下选项:
<script>
window.addEventListener('error', function(e){
const {error} = e;
if (!error.captured) {
error.captured = true;
e.stopImmediatePropagation();
e.preventDefault();
// Revisit this error after the error boundary element processed it
setTimeout(()=>{
// can be set by the error boundary error handler
if (!error.shouldIgnore) {
// but if it wasn't caught by a boundary, release it back to the wild
throw error;
}
})
}
});
</script>
假设你的错误边界是这样的:
static getDerivedStateFromError(error) {
error['shouldIgnore'] = true;
return { error };
}
结果是遵循 try...catch 推理的行为。
【讨论】:
e.stopImmediatePropagation();,我会收到以下错误:Uncaught Error: An error was thrown inside one of your components, but React doesn't know what it was. This is likely due to browser flakiness. React does its best to preserve the "Pause on exceptions" behavior of the DevTools, which requires some DEV-mode only tricks. It's possible that these don't work in your browser. Try triggering the error in production mode, or switching to a modern browser. If you suspect that this is actually an issue with React, please file an issue.
由于某种原因,现在我在升级到 Webpack 5 时才弹出叠加层。
在任何情况下,您现在都可以通过添加 webpack.config.js 来取消覆盖:
module.exports = {
//...
devServer: {
client: {
overlay: false,
},
},
};
或通过 CLI:npx webpack serve --no-client-overlay
取自这里:https://webpack.js.org/configuration/dev-server/#overlay
【讨论】:
要解决此问题,您可以使用 CSS:
body > iframe {
display: none !important;
}
【讨论】:
!important 不需要。
在config/webpack.config.dev.js 中,注释掉entry 数组中的以下行
require.resolve('react-dev-utils/webpackHotDevClient'),
并取消注释这两个:
require.resolve('webpack-dev-server/client') + '?/',
require.resolve('webpack/hot/dev-server'),
【讨论】:
为避免在 prod 中的这个大型开发库中捆绑,您可以使用 动态导入:
yarn add react-error-overlay
if (process.env.NODE_ENV === 'development') {
import('react-error-overlay').then(m => {
m.stopReportingRuntimeErrors();
});
}
【讨论】:
我认为这是有道理的,但有时当您在输入时遇到错误边界时,每个字符笔划都会弹出叠加层,这很烦人。我可以删除我想的处理程序。
【讨论】:
我遇到了同样的问题,并且我已经在 create-react-app 源中挖掘了很长时间。我找不到任何禁用它的方法,但您可以删除它放置的侦听器,这有效地停止了错误消息。打开开发者控制台并选择 html 标签。在那里,您可以删除由 unhandledError.js 放置的错误和 unhandlerejection 事件侦听器。您也可以通过单击屏幕右上角的 x 来关闭错误消息,然后您应该会看到您的消息。
【讨论】:
在文件 webpack.config.js 中,注释以下行:
// require.resolve('react-dev-utils/webpackHotDevClient'),
并取消注释:
require.resolve('webpack-dev-server/client') + '?/',
require.resolve('webpack/hot/dev-server'),
在文件webpackDevServer.config.js中,注释:
// transportMode: 'ws',
// injectClient: false,
【讨论】:
暂时禁用错误非常有用,因此您不必注释/取消注释当前未使用的代码部分,但肯定会在进行一些更改之后。
最快的解决方案是只使用 adblock 来选择有错误的 iframe。
只需单击一下即可切换它以启用/禁用给定页面上的广告拦截。
在开发模式下覆盖渲染页面只是为了通知用户新导入的对象或最近创建的变量尚未使用是违反直觉的。
我会说这是初学者的膝盖箭头:)
【讨论】:
在这里收集答案,我设法自己解决了这个问题。
Here 是我为此创建的包。
【讨论】:
【讨论】: