'Breakpoints in the WebStorm debugger for TypeScript (+Webpack) not hit until the file is recompiled
I'm using WebStorm 2022.1.1. Our app is built using React + TypeScript 3.6.1 + Webpack.
My goals are:
- Make WebStorm stop at breakpoints;
- Use source maps so the variable names are not obfuscated.
I was able to reach the 2nd goal, however I'm stuck at the 1st. I probably looked at the most articles on the Internet, but my progress was minimal.
The problem is, breakpoints work, but only after the file is changed and hot update plugin reloaded this part.
For example, here you can see the breakpoint doesn't have a “tick” mark on it, so breakpoint will not be hit:
I press TypeScript > Compile > Compile All:
The breakpoint is still not hit. Ok, I randomly change the file and press Save so the file is recompiled:
...and the breakpoint is hit but in a random place (I moved the breakpoint a line above, but anyway):
Until this is done, WebStorm doesn't consider stopping on these breakpoints.
Here are my settings:
The folder structure:
A betterscript script:
"watch:dev-debug": {
"command": "node $NODE_DEBUG_OPTION \"node_modules/webpack-dev-server/bin/webpack-dev-server.js\" --watch --colors --config \"webpack/dev.config.ts\" --require source-map-support/register",
"env": {
"NODE_ENV": "development",
"WATCH_MODE": true,
"TS_NODE_COMPILER_OPTIONS": "{\"target\": \"es5\", \"module\": \"commonjs\"}"
}
},
tsconfig.json:
{
"compilerOptions": {
"traceResolution": false,
"noErrorTruncation": true,
"strictNullChecks": true,
"noImplicitAny": true,
"skipLibCheck": true,
"module": "esnext",
"target": "es5",
"sourceMap": true,
"outDir": "build-1",
"lib": [
"es2015",
"es2017",
"es6",
"es7",
"es5",
"dom",
"scripthost"
],
"jsx": "react",
"experimentalDecorators": true,
"moduleResolution": "node",
"baseUrl": "./src",
"noUnusedLocals": true,
"noUnusedParameters": false,
"allowSyntheticDefaultImports": true,
"importHelpers": true,
"strictFunctionTypes": false,
"plugins": [
{
"name": "typescript-tslint-plugin"
}
]
},
"include": [
"src/**/*",
"webpack/**/*"
]
}
Webpack config:
const devConfig: webpack.Configuration = {
target: 'web',
context: path.resolve(__dirname, '..', 'src'),
devtool: 'source-map',
output: {
devtoolLineToLine: true,
sourceMapFilename: `js/[${chunkName}]-[${chunkHash}].bundle.map`,
path: path.resolve(__dirname, '..', 'build'),
filename: `js/[name]-[${chunkHash}].bundle.js`,
chunkFilename: `js/[${chunkName}]-[${chunkHash}].bundle.js`,
globalObject: 'this',
},
resolve: {
modules: ['node_modules', 'src'],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'react-dom': '@hot-loader/react-dom'
},
},
optimization: {
splitChunks: {
chunks: 'all',
},
runtimeChunk: {
name: 'manifest',
},
minimize: false,
},
stats: {
assets: false,
hash: false,
chunks: false,
entrypoints: false,
publicPath: false,
children: false,
modules: false,
warningsFilter: /export .* was not found in/, // TODO: delete when ts-loader will be updated
},
plugins,
output: {
...commonConfig.output,
publicPath: `${publicPath}`,
},
devServer: devServer as webpack.Configuration['devServer'],
mode: 'development',
watch: withHot,
entry: {
app: ([] as string[]).concat(withHot ? 'react-hot-loader/patch' : []).concat('./index.tsx'),
},
module: {
// many different rules here
{
test: /\.js$/,
loader: 'source-map-loader',
exclude: [
path.resolve(__dirname, '..', 'node_modules')
],
},
}
};
This is how I run the app:
NODE_OPTIONS=--no-experimental-fetch npm run watch:dev-debug
P. S. I'm not a frontend developer, so I may not know about how Webpack, NPM and etc works.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|






