Debugger does not stop at production code breakpoints - node.js

I have nodejs module which I unit test with jasmine-ts [0.3.0] by running jasmine-ts --config=spec/support/jasmine.json.
My intention is that I want to run some unit test and stop at breakpoint which is inside the function that I am testing. Unfortunately debugger stops only inside unit tests, but not in production code.
What could be the issue?
More information about my tries.
Typescript recompilation on changes is on in my Intellij IDEA 2020.1. I can recognise that it works correctly as when I change some typescript file in production code, I can see the changes in corresponding Javascript file in dist folder.
If I run my module then I can stop at breakpoints as well.
The weird thing is that I can stop at the breakpoint in production code while executing unit tests in another module where mocha is used and is run like this: npx mocha -r ts-node/register test/**/*.test.ts.
Thoughts what could be wrong.
Dependencies might not work correctly together. I was recently updating the libraries to the latest version, but noticed, that jasmine-ts requires ts-node less than 8, so currently I have the following versions in my package.json:
"devDependencies": {
"jasmine": "3.3.1",
"jasmine-ts": "^0.3.0",
"ts-node": "7.0.1",
"nyc": "^13.0.1",
"typescript": "^3.8.3",
"#types/jasmine": "^3.3.8",
"jasmine-spec-reporter": "^4.2.0",
"jasmine-reporters": "^2.3.2"
}
Source mapping might be broken. I have checked some *.js.map files and it seems like they are pointing to correct *.ts files, so, don't know what to check more there.
I was thinking if typescript configuration might influence as well, but unclear for me exactly how. Anyway, this is my tsconfig.json:
{
"compilerOptions": {
"strict": false,
"target": "es2015",
"sourceMap": true,
"module": "commonjs",
"outDir": "./dist",
"moduleResolution": "node"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"./spec/**/*.ts",
"./node_modules/**/*.ts"
]
}
Something is definitely wrong. When I want to see the coverage that I run with nyc npm test, I see Javascript files, however, it should be Typescript. But I assume that it might be a different issue, but maybe not...
Any hints to resolve the issue?:)
Update:
One way to fix this issue is to clean up the code from Intellij IDEA and other files that might influence to the stable work by removing the project completely from the computer and clone it again. By this action it helped me to stop at breakpoints in other modules that use jasmine, however my module still have weird state as I come to the production code at some point, but not in order. I assume seeing some errors regarding promises, but I don't.

The issue was that I had the Recompile on changes checkbox on in the Language & Frameworks -> Typescript.
This brings the functionality that for each .ts file there will be generated .js file, but in my case all js compiled files must be in dist directory that I specify in tsconfig file. My assumption is that during debug session debugger didn't know which file to take or was taking the wrong one. Setting Recompile to changes to off solved the problem.
Even though I still have weird behaviour as debugger comes to the production code earlier than expected, I think it is different story and relates not to Intellij IDEA preferences, but to async code with running tasks periodically.

Related

"SyntaxError: Cannot use import statement outside a module" in TypeScript (nodemon) and Node.js (with Docker)

In the server directory of my web app (in TypeScript), I have a nodemon command (that reruns code after changes) like this:
nodemon dist/index.js
However, running it now throws this error:
/path/to/app/server/src/entities/Post.ts:1
import { Field, Int, ObjectType } from "type-graphql";
^^^^^^
SyntaxError: Cannot use import statement outside a module
From what I read on here, the cause of this error is typically the fact that Node.js requires CommonJS syntax by default (as in this question, for example).
In my tsconfig.json, I have these compilerOptions:
"target": "es2017",
"module": "commonjs",
"moduleResolution": "node",
"lib": ["dom", "es6", "es2017", "esnext.asynciterable"],
"skipLibCheck": true,
(In my package.json, "type" is not specified.)
In tsconfig.json, "module" is specified as "commonjs", and it seems that tsc compiles JavaScript correctly. Running tsc gives me no errors, and the same file in /dist uses exports syntax (Object.defineProperty(exports, "__esModule", { value: true });, for example), which is correct CommonJS syntax, right?
Running the same nodemon command with ts-node doesn't return any errors:
nodemon --exec ts-node src/index.ts
What's interesting, I only started getting this error after initializing a Docker build in my /server like this:
docker build -t [username]/[project]:[version] .
Any attempts to get Node to use ES (setting "type": "module" in package.json and changing "module" only seem to bring more errors. (I was regenerating /dist to make sure it's not caused by older compiled files.)
Versions:
tsc: 4.9.5
node: 18.13.0
nodemon: 2.0.20
What am I doing wrong here?
Any help would be much appreciated!
Hmmm I'm going to take a bit of an educated guess. What's strange is from your error you appear to have /path/to/app/server/src/entities/Post.ts (notice the ts extension and the fact the path is coming from src and not dist) being imported and yet you are running a js file from dist. Technically you should only see .js files being imported. My suspicion is you are somehow importing src/entities/Post.ts incorrectly. For example you could be doing something along the lines of ../src/entities/Post.ts which would break out of dist and make it into src. Regardless the point is somehow you are importing Post.ts from src and not dist.
This would also explain why running from ts-node works, but running from ./dist/index.js does not. Feel free to leave a comment here so I can help you debug this further if it's not clear what you are supposed to do next.

How to use ESM and TypeScript in Node.js with test coverage

I'm trying to use ESM and TypeScript in Node.js v14. This is not hard and exist some questions for it:
How to use ts-node ESM with node modules?
Can't run my Node.js Typescript project TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /app/src/App.ts
Try to summarize it in tsconfig.json:
{
"compilerOptions": {
"module": "es2022",
"esModuleInterop": true
},
"ts-node": {
"esm": true
}
}
If not provide esm: true, you can use ts-node-esm instead of ts-node
For example: npx ts-node-esm my-code.ts
But main problem is that when using nyc, it can't correctly collect the statements/branches that have passed.
I have tried nyc-config-typescript and esm-loader-hook but none of these works.
How can I handle this problems?
I have tried to tackle this problem two days and finally "fix" it by using c8
You can see the example by example repo. In the example, I'm using jasmine but you can use other testing framework (e.g. mocha)
as you want.
Finally you can execute testing with coverage by:
npx c8 ts-node jasmine.ts

Unable to use import instead of require, or unable to build dependensides with ts-node & tsdx

I have the following problem and know exactly why it has been triggered, but I haven't found any solution yet, so probably the community may help me with that.
I am using tsdx for initiating ts repos, and also ts-node for quick debug (instead of building code each time).
Recursive Dilemma:
So, each time when I want to add the module to my package via yarn add modulename and if in my tsconfig.json file in compilerOptions option: "module": "commonjs" has the following value, tsdx build unable to build code, and return me the following error:
Error: Incompatible tsconfig option. Module resolves to 'CommonJS'. This is incompatible with rollup, please use 'module: "ES2015"' or 'module: "ESNext"'
BUT!
if I will update compilerOptions to module: "ESNext" from commonjs, ts-node will give me an error, because it's still unable to use import {Method} from Module instead of const x = require(CommonJS) (which is quite old bug, according to this issue and this question)
Typescript -v 4.1.5 (latest)
ts-node: "^9.1.1"
node -v: 15+
"compilerOptions": {
"module": "commonjs", || "ESNext"
"lib": ["dom", "esnext"],
...//other options
According to that, I am using WebStorm and README.md from ts-node repo, I understand, that I could update Environment Variables with custom tsconfig. So in that case I need two tsconfig files in repo, for ts-node and for production. So the question is: maybe there is another TS_NODE_FLAG, especially for module compiler options? So I could run ts-node with the flag, that would overwrite this minor parameter?
Currently working compromise is having two config files, which are exactly the same:
tsconfig.json
tsconfig.dev.json
except that the second has "module":"commonjs"
The second option, which actually somehow not working for me is adding to WebStrom's Environment Variables TS_NODE_COMPILER_OPTIONS='{"module":"commonjs"}' from this question.
another option:
import typescript from 'rollup-plugin-typescript2';
export default {
...
plugins: [
typescript({
// 覆盖 tsconfig.json 的配置项
tsconfigOverride: {
compilerOptions: {
module: "ESNext"
},
include: ['src/**/*'],
},
})
]
};

Using babel with preset-env on a small node project, unable to convert import/export statements to commonjs

I'm trying to set up a node project so I can use the common import/export syntax, and for compatibility, use babeljs to convert the import and export statements to requires.
When I try transpiling using babel though, I'm not seeing any changes and I don't know why.
Here's my babel.config.js
// babel.config.js
module.exports = {
// I thought this was what I would need to add for making the changes, based on the docs
plugins: ["#babel/plugin-transform-modules-commonjs"],
// env takes care of the majority of changes I might need to convert code to make
// easy to run on a wider range of machines
presets: [
[
"#babel/preset-env",
{
targets: {
// target an older version where I know there is no ESM support
node: "10"
}
}
]
],
// this was in the docs too - I'm not sure if I need it TBH
sourceType: "module"
}
I have a bunch of code using import/export, and async/await in a directory, that I wanted to transpile and put into another directory, lib.
Here's the command I am using:
npx babel src --out-dir lib
My package.json file online too, and there's nothing too esoteric there. I've tried to follow the documentation faithfully.
I would expect to see changes in the code to replace the import/export calls with requires in the lib, but no joy.
What am I doing wrong here? I worked on a related project 6-7 months ago, where I am using babel like this and it does make the changes for me.
You can see the branch with the problem code on github, with the package.json, and here's the source code for other project mentioned where it is working.
Please be gentle, fellow SO commenters - I'm trying my best, I really am.
It looks like you're using "babel-cli": "^6.26.0" instead of "#babel/cli": "^7.11.6" that should fix it.

WebStorm remote debugging NodeJS with Babel

I'm running my node application with:
"./node_modules/nodemon/bin/nodemon.js --ignore ./build/* ./bin/www --exec babel-node --debug=7001",
When I connect with a WebStorm remote configuration it seems to work, but the placing breakpoint results in either them being ignored, or the code actually stop at different lines.
This is probably due to Babel transpiling. How can I do that, given my code is transpiled at runtime?
My .babelrc file:
{
"presets": ["es2015", "stage-2"],
"plugins": ["transform-runtime"]
}
Here is the revelent documentation : https://blog.jetbrains.com/webstorm/2015/05/ecmascript-6-in-webstorm-transpiling/
If you’d like to debug your code using WebStorm or Chrome, make sure
the tools you’re using generates source maps. For example, when
using Babel only, you need to add "sourceMaps": "both" option to
your .babelrc file or pass it as a command-line argument. If you’re
using Babel as a part of a more complex build process, you might need
a addition configuration for generating source maps, e.g. use
gulp-sourcemaps with Gulp or add devtool: "source-map" option when
using Webpack.
Source maps allow you to put breakpoints in the original source files in the IDE and be sure that they are hit then compiled code is
executed in the browser.

Resources