Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line numbers aren't mapped correctly in TSX files when using Node 8 AND React 16 #334

Closed
jimthedev opened this issue Sep 30, 2017 · 36 comments
Milestone

Comments

@jimthedev
Copy link
Contributor

  • Issue

When using Node version 8 tsx-errors.spec.ts fails with:

Summary of all failing tests
 FAIL  tests/__tests__/tsx-errors.spec.ts
  ● TSX Errors › should show the correct error locations in the typescript files

    expect(string).toContain(value)

    Expected string:
      "FAIL __tests__/Button.test.tsx
      ✓ Button renders correctly (13ms)
      ✕ BadButton should throw an error on line 18 (6ms)

      ● BadButton should throw an error on line 18

        Error in Bad button

          at BadButton.Object.<anonymous>.BadButton.render (Button.tsx:34:15)
          at Object.<anonymous> (__tests__/Button.test.tsx:11:14)
              at Promise (<anonymous>)
              at <anonymous>
          at process._tickCallback (internal/process/next_tick.js:188:7)

    Test Suites: 1 failed, 1 total
    Tests:       1 failed, 1 passed, 2 total
    Snapshots:   1 passed, 1 total
    Time:        2.75s
    Ran all test suites.
    "
    To contain value:
      "Button.tsx:18:17"

      at Object.<anonymous> (tests/__tests__/tsx-errors.spec.ts:10:20)
          at Promise (<anonymous>)
          at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:188:7)


Test Suites: 1 failed, 22 passed, 23 total
Tests:       1 failed, 67 passed, 68 total
Snapshots:   2 passed, 2 total
Time:        23.794s
Ran all test suites matching /^(?!(.*watch.spec.ts$)).*/i.
npm ERR! Test failed.  See above for more details.
  • Expected behavior

I expect the test to pass.

  • Link to a minimal repo that reproduces this issue

This test is in the ts-jest repo so reproducing just involves upgrading to node 8 via nvm, n or some other method.

@kulshekhar
Copy link
Owner

Thanks for reporting this. I was able to reproduce this issue. It looks related to react 16 in some way.

@jimthedev
Copy link
Contributor Author

Yes I think you're correct. I would be happy to help on this if you point me in the right direction of what in React 16 might have changed the error line mappings?

@kulshekhar
Copy link
Owner

I've pushed an additional change to your PR which should, hopefully, result in a failed build. It'll be good to have a common point of reference when debugging this issue.

I would be happy to help on this if you point me in the right direction of what in React 16 might have changed the error line mappings?

The issue appears to arise due to some changes in react-test-renderer

@jimthedev
Copy link
Contributor Author

Sounds good!

@jimthedev
Copy link
Contributor Author

Yeah react-test-renderer is where I got to and then figured I was out of my element since I wasn't sure what it did.

@kulshekhar
Copy link
Owner

This is probably being caused due to the new error handling mechanism that React has. I'm not sure how this can be fixed in ts-jest.

@jimthedev
Copy link
Contributor Author

I wonder if we can add in a custom log output in componentDidCatch that captures the right line.

@jimthedev jimthedev changed the title BadButton throws wrong line in Node 8 BadButton throws wrong line in Node 8 / React 16 Oct 1, 2017
@kulshekhar
Copy link
Owner

componentDidCatch doesn't contain any line numbers

@jimthedev
Copy link
Contributor Author

:( Dang.

@kulshekhar
Copy link
Owner

kulshekhar commented Oct 1, 2017

they have some sort of a plugin for those using Babel but it won't help here
https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html#component-stack-traces

@GeeWee
Copy link
Collaborator

GeeWee commented Oct 1, 2017

If this is due to the react code - can we just throw our errors in non-react code?

@gaearon
Copy link

gaearon commented Oct 1, 2017

We just read <div />._source.lineNumber. I don’t know where it comes from for TypeScript users. If you use Babel, babel-plugin-transform-react-jsx-source generates it as part of JSX.

So to fix it, you would need to either remove babel-plugin-transform-react-jsx-source (assuming you somehow use it after running TS), or add source metainformation at TypeScript level.

@kulshekhar
Copy link
Owner

@GeeWee

If this is due to the react code - can we just throw our errors in non-react code?

I'm not sure I understand. Could you please elaborate?

@gaearon

We just read <div />._source.lineNumber

that's set by the babel-plugin-transform-react-jsx-source plugin.

I don’t know where it comes from for TypeScript users.

It isn't available at the moment the TypeScript file is processed. It wasn't required prior to v16 as all errors in .tsx files were displayed with the correct line numbers.

So to fix it, you would need to either remove babel-plugin-transform-react-jsx-source (assuming you somehow use it after running TS)

We don't currently use it but I actually think otherwise. We might need to use it if we can't find any solution. In that case as well, the plugin should be capable of using sourcemaps (that are emitted after we process .tsx files) to display the correct line numbers. Does the plugin handle sourcemaps?

or add source metainformation at TypeScript level

In the worst case, this might be the way to go.

@kulshekhar
Copy link
Owner

kulshekhar commented Oct 2, 2017

Curiously, it only fails in node version 8. I was able to reproduce this as part of #333

@GeeWee
Copy link
Collaborator

GeeWee commented Oct 2, 2017

I'm not sure I understood it right the first time around. Do we still think this is due to react error boundaries?

It only failing in node 8 says no to me, but it's very curious.

@gaearon
Copy link

gaearon commented Oct 2, 2017

It wasn't required prior to v16 as all errors in .tsx files were displayed with the correct line numbers.

React 16 didn't change anything in how line numbers are associated with JSX. There are only two things that changed:

  • React now catches errors during rendering before rethrowing them.
  • React adds extra information in the form of component stack when JSX line numbers are available.

React can't possibly affect the line numbers from JavaScript stack. Those are reported by the JavaScript engine. I now see that your report was about JS line numbers so my previous comments about JSX transform were not relevant.

@kulshekhar
Copy link
Owner

I'm going to try and find some time to dive deeper into this but in case someone else is looking at it, here's what the situation looks like:

  • This issue seems to affect only projects that use React 16 AND Node 8.
  • Projects using React 16 with an older version of node aren't affected
  • Projects using an earlier version of React with node 8 aren't affected

@kulshekhar
Copy link
Owner

kulshekhar commented Oct 2, 2017

Some debugging threw up this error message:

    Error
        console.error ../../node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2055
          The above error occurred in the <BadButton> component:
              in BadButton
              in BadButtonBoundary
          
          React will try to recreate this component tree from scratch using the error boundary you provided, BadButtonBoundary.
      
        console.error ../../node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2055
          The above error occurred in the <BadButtonBoundary> component:
              in BadButtonBoundary

I have a suspicion that some code in react is throwing the built-up error and in the process (directly or indirectly) suppressing the stack trace

@kulshekhar
Copy link
Owner

kulshekhar commented Oct 2, 2017

@gaearon

React 16 didn't change anything in how line numbers are associated with JSX. There are only two things that changed:

  • React now catches errors during rendering before rethrowing them.
  • React adds extra information in the form of component stack when JSX line numbers are available.

React can't possibly affect the line numbers from JavaScript stack. Those are reported by the JavaScript engine. I now see that your report was about JS line numbers so my previous comments about JSX transform were not relevant.

Thanks for the insights.

The absence of a stack trace is the likely cause of this issue.

Is it possible that some edge case handler (or some branch of code) in the renderer is suppressing the stack trace? The reason I think this might be the case is because this fails only on Node 8 and not on the earlier versions.

@gaearon
Copy link

gaearon commented Oct 2, 2017

Where do you see the stack trace being suppressed?

@kulshekhar
Copy link
Owner

Sorry about that!

That was the result of some changes that I had made while debugging. Please disregard my previous comment (updated)

@jimthedev jimthedev changed the title BadButton throws wrong line in Node 8 / React 16 BadButton throws wrong line in Node 8 AND React 16 Oct 2, 2017
@kulshekhar kulshekhar changed the title BadButton throws wrong line in Node 8 AND React 16 Line numbers aren't mapped correctly in TSX files when using Node 8 AND React 16 Oct 2, 2017
@kulshekhar
Copy link
Owner

kulshekhar commented Oct 3, 2017

I've spent some time on this and don't think this is an issue with ts-jest. ts-jest is processing the tsx files correctly and is adding the sourcemap as well as the code to use source-map-support.

There's not much we can do about this here, I'm afraid.

The readme needs to be updated with a note about react 16 + node 8.

kulshekhar added a commit to jimthedev/ts-jest that referenced this issue Oct 3, 2017
There's an issue when using React 16 with Node 8 (kulshekhar#334).

Disabling this test temporarily so that we can continue with the updates
@fbartho
Copy link

fbartho commented Feb 26, 2018

I noticed that I get correct source-mapping in thrown Errors when I set "useBabelrc": false, in the package.json["jest"]["globals"]["ts-jest"] config block (alongside "mapCoverage": true)

(To be clear, this doesn't mean I got correct code-coverage, just that errors thrown in TS files needed ts-jst to avoid babel).

Maybe this helps?

@jamietre
Copy link

jamietre commented Apr 2, 2018

I was wondering if there is any more information or progress on this? I'm trying to set up Jest for the first time and stack trace line numbers are incorrect as per this issue. It's a little different for me:

  1. We are on React 15
  2. Node version has no effect (tried 6, 7, 8, 9)
  3. Source maps work perfectly when I debug in VS Code, so it seems unrelated to sourcemaps themselves.

I've sought support via Discord and there are unanswered Stack Overflow questions with the same issue, there doesn't seems to be any resolution or workaround. This seems like a pretty big problem.

Does anyone more familiar with Jest & this issue know if this is affecting everyone using Jest + TypeScript or just isolated cases? It seems odd that it's been going on so long unresolved if it's affecting a large number of people. I'm not sure how I can make a case that we should be adopting Jest if I can't get source maps working correctly, but i've been working on this for several days and nothing seems to work so I'm pretty baffled. I've tried various workarounds from older issues, e.g. turn on mapCoverage, disableSourceMapSupport option, nothing makes any difference.

@singuerinc
Copy link

I fixed it by adding the --mapCoverage flag

react-scripts test --env=jsdom --coverage --mapCoverage

@jamietre
Copy link

jamietre commented Apr 3, 2018

Tried adding mapCoverage, it's been deprecated as of 22.4.0. I've tried literally every possible combination of options - useBabelrc, disableSourceMapSupport, in babelrc "sourceMap": "inline", nothing makes any difference.

@6220119
Copy link

6220119 commented May 10, 2018

Not sure what magic it is.
We also have this problem. However, running the tests with --mapCoverage flag fixed this.
versions:
ts-jest: 22.4.5
node: v9.10.1
react: v16.0.0

@maoueh
Copy link

maoueh commented Jul 3, 2018

@jamietre Did you try the CLI flag --mapCoverage or the config option? I did both test and strangely, only the command line flag --mapCoverage works. Using mapCoverage: true is not working.

That's really strange :(

@fbartho
Copy link

fbartho commented Jul 3, 2018

@maoueh ! -- that's a big catch. I was only using the config option. I haven't tested the CLI flag. I don't know when I'll get to experiment with implementing that in our repo, but that's really key.

@SimenB
Copy link
Contributor

SimenB commented Sep 6, 2018

For people coming to this issue from the FAQ, mapCoverage is removed in later versions of Jest as it's not needed anymore.

(that won't help create-react-app I suppose, as that's on an older version of jest)

@huafu
Copy link
Collaborator

huafu commented Sep 6, 2018

@jamietre @6220119 @maoueh @fbartho you can try the beta release of ts-jest (see #697). It should fix your coverage/line-mapping issues.

@SimenB I'd love to chat about jest+ts-jest. We now have our slack channel so let's chat there if you can.

@huafu huafu modified the milestone: v23.10.0 Sep 6, 2018
@SimenB
Copy link
Contributor

SimenB commented Sep 15, 2018

@huafu sorry, missed your message. I'm already a member of way too many Slacks, but you can join us over on Reactiflux? https://discord.gg/MWRhKCj

@huafu huafu added this to the v23.10.0 milestone Sep 19, 2018
@huafu huafu closed this as completed Sep 19, 2018
@fider-apptimia
Copy link

fider-apptimia commented Mar 18, 2020

Same problem for non-react projects - invalid stack trace line number.

Node v12.16.1
ts-jest@25.2.1
jest@25.1.0

(it is showing .ts file but line number isn't mapped to original ts file)

@adambeben
Copy link

@fider-apptimia I had the same problem in non-react project when I was using async/await. Changing target in tsconfig.json to ES2019 fixed it for me.

This is how my tsconfig.json looks like (only target is edited, the rest are default tsc --init values):

{
  "compilerOptions": {
    "target": "ES2019",                       /* ES2019 is rquired to display proper stack trace when using async/await and '?.' operator */
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  }
}

@fider-apptimia
Copy link

@adambbn here is my full tsconfig:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "noImplicitAny": true,
    "module": "CommonJS",
    "moduleResolution": "node",
    "allowJs": true,
    "strict": true,
    "isolatedModules": true,
    "pretty": true,
    "sourceMap": true,
    "target": "ES2019",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "rootDir": "./",
    "outDir": "./dist"
  },
  "exclude": ["dist", "node_modules"]
}

Still invalid stack trace with ES2019 - stack traces of errors throwed from my .ts file wrapped by jest are still not mapped.

@Cellule
Copy link

Cellule commented Feb 15, 2023

Just in case someone stumbles on this issue in the future.
I've hit that issue again recently.
While I was trying to make a minimal repro, I was struggling to do it in a controlled environment.
After much reducing in my main project I finally identified the culprit.
There was a ts-node import and register which caused bad line numbers

I managed to make a minimal repro here
https://github.com/Cellule/ts-jest-line-numbers

I doubt this is something that ts-jest should handle/fix ? But if that can help another than I'm glad

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests