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

Sourcemap support when debugging (Intellij IDEA / Webstorm / others) #150

Closed
jugglingcats opened this issue Apr 3, 2017 · 23 comments
Closed

Comments

@jugglingcats
Copy link

When debugging Jest tests in IDEA I set breakpoints but they are never triggered. I assume this is related to sourcemaps somehow.

Jest correctly gives Typescript filename+line when reporting errors / expect failures, so at this level sourcemaps are working.

This is more of a request for help than bug report. Do people have debugging fully working in your preferred IDE when running Jest tests?

For info, Jetbrains recently released integrated Jest support with progress bar, etc.

image

Here is the full command executed by IDEA:

"C:\Program Files\nodejs\node.exe" --debug-brk=7830 --expose_debug_as=v8debug C:\Users\alfie\gb\gb-util\node_modules\jest\bin\jest --config "{\"transform\":{\".ts$\":\"<rootDir>/node_modules/ts-jest/dist/preprocessor.js\"},\"testRegex\":\"(/__tests__/.*|\\.(test|spec))\\.(ts|tsx)$\",\"moduleFileExtensions\":[\"ts\",\"tsx\",\"js\"],\"rootDir\":\"C:\\Users\\alfie\\gb\\gb-util\",\"transformIgnorePatterns\":[\"/node_modules/\",\"^C:\\Program Files (x86)\\JetBrains\\IntelliJ IDEA 171.3780.15\\plugins\\JavaScriptLanguage\\helpers\"]}" --no-cache --runInBand --colors --setupTestFrameworkScriptFile "C:\Program Files (x86)\JetBrains\IntelliJ IDEA 171.3780.15\plugins\JavaScriptLanguage\helpers\jest-intellij\lib\jest-intellij-jasmine.js" --testPathPattern ^C:\\Users\\alfie\\gb\\gb\-util\\src\\misc\\FlexibleIterator\.spec\.ts$ --testNamePattern "^Flexible iterator Should yield last item after sub\-iterator$"

tsconfig.js:

{
  "compilerOptions": {
    "jsx": "react",
    "module": "commonjs",
    "experimentalDecorators": true,
    "outDir": "./build",
    "preserveConstEnums": true,
    "compileOnSave": true,
    "removeComments": true,
    "sourceMap": true,
    "inlineSources": true,
    "target": "es6",
    "strictNullChecks": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "noUnusedParameters": true,
    "noUnusedLocals": true
  },
  "exclude": [
    "node_modules",
    "build"
  ]
}

package.json:

{
  "name": "gb-util",
  "author": "Alfie Kirkpatrick",
  "version": "1.0.0",
  "description": "Typescript utilities",
  "main": "build/index.js",
  "typings": "build/index.d.ts",
  "license": "UNLICENSED",
  "scripts": {
    "test": "jest --no-cache"
  },
  "devDependencies": {
    "@types/jest": "^19.2.2",
    "jest": "^19.0.2",
    "ts-jest": "^19.0.1",
    "typescript": "^2.2.1"
  },
  "jest": {
    "transform": {
      ".ts$": "<rootDir>/node_modules/ts-jest/dist/preprocessor.js"
    },
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ]
  },
  "unused": {},
  "dependencies": {
    "global": "^4.3.1"
  }
}
@kulshekhar
Copy link
Owner

If there's a minimal repo that I could use to test this with WebStorm/IDEA, I could look into this much earlier than if I had to set a project up from scratch. It would also help me replicate your settings exactly if you include the .idea directory in git

@jugglingcats
Copy link
Author

Hi @kulshekhar, thanks for response. Here is a link to minimal test project: https://github.com/jugglingcats/ts-jest-idea

@kulshekhar
Copy link
Owner

Modifying the default debug config in idea to run Compile Typescript before launch got this working.

ts-jest-idea

@jugglingcats
Copy link
Author

Interesting, I tried that and it's not working for me. No breakpoint hit.

@kulshekhar
Copy link
Owner

I just noticed that you use the Run button (play button). I used the Debug button (bug button)

@jugglingcats
Copy link
Author

I'm using the debug button ;)

Out of interest are you initiating the test run from the .ts file or the build\test.spec.js file?

I am able to set a breakpoint in the .ts file and it will fire correctly if I initiate the test from the .js file. But in this case the pre-processor is not invoked, so ts-jest is not involved, if I understand correctly.

It seems like when you run using the pre-processor it doesn't use the source maps in build. Which kind of makes sense, just not sure if it's fixable.

@kulshekhar
Copy link
Owner

In my configuration, I set Jest to run on the entire project. I don't think (for the way I have set it up) it matters where debugging is initiated from. Here are the exact steps I took:

  1. git clone https://github.com/jugglingcats/ts-jest-idea
  2. cd ts-jest-idea
  3. yarn install
  4. Open the project in WebStorm
  5. Create a configuration (Run > Edit Configurations)
  6. Add a Jest configuration
  7. Add Compile Typescript in the list of tasks to execute before launch. The configuration is set to run All tests
  8. Press the debug button - all tests run fine:
 Debugger listening on [::]:41105
 PASS  build/test.spec.js
 PASS  ./test.spec.ts

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        3.135s, estimated 5s
Ran all test suites.

Process finished with exit code 0
  1. Open test.spec.ts, add a breakpoint and press the debug button again to get the state that I posted a screenshot of earlier

@jugglingcats
Copy link
Author

Ah, ok, that is working for you because you are matching both the .ts sources and the build/*.js generated files. You can see this because 2 test suites are passed!

When you are running the build/test.spec.js file you have the generated sourcemaps too, so your breakpoint in the .ts file is working.

@kulshekhar
Copy link
Owner

It appears to me that if there's a solution to what you want, it is likely somewhere in Webstorm's configuration/support and not ts-jest :)

@jugglingcats
Copy link
Author

I tried a couple of things and got a strange behaviour:

  • Removed the pre-processor config in package.json
  • Added test2.spec.js alongside test.spec.ts with same content (note the .js extension)

The original test.spec.ts is actually valid ES6, so pre-processor is not actually needed.

I also removed Typescript Compile build step and deleted build so it no longer exists.

Now when I debug test2.spec.js I can set and hit a breakpoint no problem.

But when I debug test.spec.ts I don't hit the breakpoint!

The command line that IDEA is using is identical except the filename... very odd.

I don't think this particular behaviour is a ts-jest issue but even if it were able to hit a breakpoint I don't think things will work correctly (see next comment)

@jugglingcats
Copy link
Author

Back to sourcemaps...

I added the pre-processor back in, and I've also added custom cacheDirectory parameter to see what is being generated more easily.

The following file is generated:

'use strict';require('ts-jest').install();"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
describe("a test", function () {
    it("should have a breakpoint", function () {
        const x = 1;
        expect(x).toBe(1);
    });
});
//# sourceMappingURL=test.spec.js.map

Note that I still haven't added Compile Typescript back in the run configuration (no build directory exists). Even if build files were there, the sourceMappingURL has no relative path and so probably won't be found?

To test this theory I generated the build files again, hacked the pre-processor output file and modified the path to be ./build/test.spec.ts.map and whoa breakpoint was hit!

@jugglingcats
Copy link
Author

Sorry just saw your last comment. I think the sourcemap location issue is potentially fixable in ts-jest, assuming the facility is there for you to specify a relative path. Determining the correct relative path may not be trivial though. You would need the outDir from tsconfig.json, but there are other nuances: for example, tsc does clever things to prune unnecessary levels in the source structure (ones that don't have any .ts sourcefiles).

@kulshekhar
Copy link
Owner

I think the sourcemap location issue is potentially fixable in ts-jest

If this is the case, it'd be great to update ts-jest. I'd be happy to take a PR if you want to give it a shot 😄

@jugglingcats
Copy link
Author

Heheh I found your previous question to the Jest devs here: jestjs/jest#1474.

That gave me a clue about inline sourcemaps, so I added inlineSourceMap: true to my tsconfig.json and it all started working!

This config setting causes the sourcemap to be emitted right into the target file using the data:application/json url protocol.

It would be nice if ts-jest did this by default. I hacked the following into preprocessor.js and it seemed to do the trick: compilerOptions.inlineSourceMap=true;

Not sure this is worthy of a pull request... :)

@kulshekhar
Copy link
Owner

@jugglingcats if that worked then setting that value in jest config should also work. Could you try that?

@kulshekhar
Copy link
Owner

@jugglingcats you're right! Setting inlineSourceMap: true in the jest config did the trick. I didn't even have to set the config to run typescript compilation 😄

I'm going to leave this open till I can add tests for this and set this value if it hasn't been explicitly set by the user. That should prevent others from facing this issue!

@kulshekhar
Copy link
Owner

Actually, it'll be better to track this is a new issue - #151

@jugglingcats is it fine if this issue were closed?

@jugglingcats
Copy link
Author

It worked for me too. Example project and readme updated. Many thanks - we're done here.

@GeeWee
Copy link
Collaborator

GeeWee commented May 10, 2017

I'm just going to dig this up from the grave, as I seem to have an issue that's almost the same, but not quite.

The inlinesourcemap work reasonably fine, but the only way I can get the debugger to do anything, is if i set an actual debugger; statement - breakpoints are simply ignored.

Is this something any of you came across during your digging?

my package.json's jest looks like this:

	"jest": {
		"preset": "react-native",
		"transform": {
			"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
			".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
		},
		"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
		"moduleFileExtensions": [
			"ts",
			"tsx",
			"js",
			"json"
		],
		"globals": {
			"__DEV__": true,
			"__TS_CONFIG__" : {
				"jsx": "react",
				"allowSyntheticDefaultImports": true,
				"target": "es2015",
				"moduleResolution": "node",
				"inlineSourceMap": true
			}
		}
	}

@kulshekhar
Copy link
Owner

@GeeWee everything we did when we were working on this is mentioned here in this issue. If that doesn't help, the best thing would be to create a minimal repo that reproduces this and create a new issue

@GeeWee
Copy link
Collaborator

GeeWee commented May 11, 2017

Thanks @kulshekhar - it has been done - #209

@akos-sebestyen
Copy link

I could not get my breakpoints to hit in Webstorm 2018.1.5 with ts-jest 22.4.0. I tried all of the above solutions, but it turns out it was because I was using node v7.10.1

I upgraded to node v8.9.4 and my breakpoints were instantly working. Hopefully this saves someone some struggle.

@huafu
Copy link
Collaborator

huafu commented Sep 14, 2018

@akos-sebestyen FYI:

  • You don't want to stay on odd-numbered releases of NodeJS (like 7, 9, ...). They are EOL (end-of-life, no more maintained) as soon as the next even-numbered release is out (which will be LTS = long term support) – see here
  • It sounds that you're using ts-jest 22. Unless you CAN'T upgrade for some reason, it'd be better that you switch to latest versions of jest and ts-jest (you might have to/should also upgrade some other packages as well which jest rely on). In any case you want major version of ts-jest to follow the one of jest. Also strongly advised to upgrade typescript:

You can see breaking changes of Jest there

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

No branches or pull requests

5 participants