6

I have a React application that is transpiled with Babel using the following .babelrc configuration

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

The application transpiles and runs fine. However, when I debug event handlers (purposely written as arrow functions), the Chrome debugger displays the value of "this" as null. Here is a sample event handler

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

If I set a breakpoint on the first line of the event handler, the debugger displays the value of "this" as null but displays "_this" as the correct value for "this". As I said, the code runs clean, but debugging is frustrating since I cannot simply hover on fields in the code to see their value. I can work around the debugging issue if I bind "this" to my event handler, but I should not have to do that extra step. All of this worked fine in Babel5 and has only been an issue since we switched to Babel6.

I am using webpack to bundle the code and create the sourcemaps. Here is an excerpt from my webpack.config.js for sourcemaps configuration

plugins: [
new webpack.SourceMapDevToolPlugin({
  filename: '[name].js.map',
  include: ['app.js'],
  columns: false
})
],
Bob Cardenas
  • 181
  • 1
  • 1
  • 5
  • Have you tried stage-0 preset? – John William Domingo Apr 15 '16 at 05:54
  • 1
    As far as I know, this was an issue in Babel 5 too. Chrome cannot map `this` to `_this`. – loganfsmyth Apr 15 '16 at 06:05
  • 1
    Just noticed you're mutating the page state when you should be using this.setState({page: this.state.page + 1}). I use the stage-0 preset and am able to access proper context. I've noticed in the past that the order of the presets matter but have not confirmed this lately. I use "es2015", "react", and then "stage-0". – John William Domingo Apr 15 '16 at 06:18
  • @JohnWilliamDomingo I have corrected the code example so that it does not mutate page state. The live site code is actually much different and also does not mutate state. Thanks for pointing this out so someone else does not learn from a bad code example. – Bob Cardenas Apr 20 '16 at 05:24
  • @JohnWilliamDomingo We were using stage-0 up until a week ago. I changed it to stage-1 when I realized there was nothing in stage-0 that we are actively using and so, I was hoping that switching to stage-1 would fix our context issue. But, it did not. – Bob Cardenas Apr 20 '16 at 05:27
  • @JohnWilliamDomingo I just tried using your order for the presets, but the value of "this" is still null. – Bob Cardenas Apr 20 '16 at 05:28
  • @loganfsmyth We never ran into this issue with Babel 5. – Bob Cardenas Apr 20 '16 at 05:30
  • Depending on how the function is called, `this` and `_this` might be the same value, so maybe that's what you're thinking of? I run into this constantly when debugging in Babel 5. – loganfsmyth Apr 21 '16 at 01:43

1 Answers1

7

Unfortunately this is a fact of life when using the debugger in Babelified code with Chrome. To implement arrow functions with the ECMAScript spec behavior, the this keyword needs to be transformed into a different name, and there's currently no way to tell Chrome what do to for debugging. Firefox's developer tools have a bunch of extra logic to address issues like this, so it may work properly if you're using Firefox and enable to "Map Scopes" checkbox, but it can also be slower because it isn't trivial.

One option would be to try to use the spec option of the arrow function transformation, which should make this behave better for debugging, but may not work in all cases.

"plugins": [
    ["transform-es2015-arrow-functions", {spec: true}]
]
loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • 1
    can you please detail what does the `spec` option do so that we can understand why it helps ? Thank you! – Ciprian Tomoiagă Aug 20 '18 at 10:51
  • 1
    @CiprianTomoiagă Instead of renaming `this`, it attempts to use `.bind` to get arrow-like behavior. – loganfsmyth Aug 20 '18 at 17:51
  • Is this still an issue with Babel in 2019? The equivalent [TypeScript bug](https://github.com/microsoft/TypeScript/issues/2617) is still open as well. Is this blocked on a missing sourcemap feature? – Bergi Aug 26 '19 at 21:43
  • @Bergi Still an issue, yeah. The issue is kind of two-fold. Sourcemaps _might_ have enough information to reverse this, but not all of them will, and since the exact behavior of a given source-map is pretty under-defined, it is up to each individual consumer of a map to decide just how much data they want to try to infer from the mappings. For instance, Firefox now handles this stuff pretty well if you use "Map Scopes", because I wrote some logic for them that infers a ton of stuff beyond what is traditionally done, but it's all heuristics and is off by default because it is slow. – loganfsmyth Aug 26 '19 at 23:28