使用 Chrome Devtools 调试 Babel 转译的 React 时,“this”的值不正确

Posted

技术标签:

【中文标题】使用 Chrome Devtools 调试 Babel 转译的 React 时,“this”的值不正确【英文标题】:Value of "this" is incorrect when debugging Babel transpiled React with Chrome Devtools 【发布时间】:2016-08-06 22:13:09 【问题描述】:

我有一个使用以下 .babelrc 配置通过 Babel 转译的 React 应用程序


  "presets": [
    "es2015",
    "stage-1",
    "react"
  ],
  "plugins": [
    "transform-decorators-legacy"
  ]

应用程序编译并运行良好。但是,当我调试事件处理程序(特意编写为箭头函数)时,Chrome 调试器将“this”的值显示为 null。这是一个示例事件处理程序

handleNext = (event) => 
    event.preventDefault();
    this.gotoPage(this.state.page + 1);

如果我在事件处理程序的第一行设置断点,调试器会将“this”的值显示为 null,但将“_this”显示为“this”的正确值。正如我所说,代码运行干净,但调试令人沮丧,因为我不能简单地将鼠标悬停在代码中的字段上以查看它们的值。如果我将“this”绑定到我的事件处理程序,我可以解决调试问题,但我不应该做那个额外的步骤。所有这些在 Babel5 中都运行良好,并且在我们切换到 Babel6 后才成为问题。

我正在使用 webpack 来打包代码并创建源映射。这是我的 webpack.config.js 中 sourcemaps 配置的摘录

plugins: [
new webpack.SourceMapDevToolPlugin(
  filename: '[name].js.map',
  include: ['app.js'],
  columns: false
)
],

【问题讨论】:

你试过stage-0预设吗? 据我所知,这也是 Babel 5 中的一个问题。 Chrome 无法将 this 映射到 _this 刚刚注意到,当您应该使用 this.setState(page: this.state.page + 1) 时,您正在改变页面状态。我使用 stage-0 预设并且能够访问适当的上下文。我过去注意到预设的顺序很重要,但最近没有确认这一点。我使用“es2015”、“react”,然后是“stage-0”。 @JohnWilliamDomingo 我已经更正了代码示例,使其不会改变页面状态。实时站点代码实际上有很大不同,也不会改变状态。感谢您指出这一点,这样其他人就不会从糟糕的代码示例中学习。 @JohnWilliamDomingo 直到一周前我们还在使用 stage-0。当我意识到 stage-0 中没有我们正在积极使用的东西时,我将其更改为 stage-1,因此,我希望切换到 stage-1 可以解决我们的上下文问题。但是,它没有。 【参考方案1】:

不幸的是,在将 Babelified 代码中的调试器与 Chrome 一起使用时,这是不争的事实。要实现具有 ECMAScript 规范行为的箭头函数,需要将 this 关键字转换为不同的名称,并且目前无法告诉 Chrome 做什么来进行调试。 Firefox 的开发者工具有很多额外的逻辑来解决此类问题,因此如果您使用 Firefox 并启用“映射范围”复选框,它可能会正常工作,但它也可能会变慢,因为它不是微不足道的。

一种选择是尝试使用箭头函数转换的spec 选项,这应该会使它在调试时表现得更好,但可能并非在所有情况下都有效。

"plugins": [
    ["transform-es2015-arrow-functions", spec: true]
]

【讨论】:

您能否详细说明spec 选项的作用,以便我们了解它为什么有用?谢谢! @CiprianTomoiagă 它没有重命名this,而是尝试使用.bind 来获得类似箭头的行为。 2019年的Babel还是这个问题吗?等效的TypeScript bug 也仍然打开。这是否因缺少源地图功能而被阻止? @Bergi 还是个问题,是的。这个问题是双重的。源地图可能有足够的信息来扭转这一点,但不是所有的都可以,而且由于给定源地图的确切行为非常不明确,这取决于地图的每个消费者来决定他们想从映射中推断出多少数据。例如,如果你使用“Map Scopes”,Firefox 现在可以很好地处理这些东西,因为我为它们编写了一些逻辑,可以推断出大量超出传统方法的东西,但它都是启发式的,默认情况下是关闭的,因为它很慢.

以上是关于使用 Chrome Devtools 调试 Babel 转译的 React 时,“this”的值不正确的主要内容,如果未能解决你的问题,请参考以下文章

使用 Chrome Devtools 调试 CSS 动画

Chrome 73:无法再使用 Dedicated DevTools for Node 调试 NodeJS

在远程调试窗口调整 Chrome DevTools 的停靠位置

如何用 Chrome DevTools 调试 iOS Safari

使用Chrome DevTools直接调试Node.js与JavaScript(并行)

Chrome DevTools