typescriptvisual-studio-codewebpack

How to debug TypeScript bundled with Webpack in VS Code?


Let's consider this very simple TypeScript file:

console.log("log");
console.trace();
console.log("again");

I want to debug it from VS Code. However, it seems to not see my breakpoints.

Here is my configuration:

I installed the required modules:

npm install --save-dev webpack-cli typescript ts-loader

The command I use to bundle the program is:

node ./node_modules/webpack-cli/bin/cli.js

When I run it from the CLI, we can see that the sources are correctly mapped:

$ node --enable-source-maps ./dist/bundle.js 
log
Trace
    at console (webpack:///src/main.ts:2:9)
    at Module._compile (node:internal/modules/cjs/loader:1356:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1414:10)
    at Module.load (node:internal/modules/cjs/loader:1197:32)
    at Module._load (node:internal/modules/cjs/loader:1013:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12)
    at node:internal/main/run_main_module:28:49
again

Indeed, as you can see, it is displayed webpack:///src/main.ts:2:9.

However, in VS Code, when I run the program through the debugger, the breakpoints are not seen.

What's wrong in my configuration?

Note: I tried to "source-map" and "inline-source-map" in my Webpack configuration file and it does not work in both cases.

Here are the versions of Node and npm I am using:

$ node --version
v18.19.0
$ npm --version
9.2.0

Solution

  • There are several issues in my configuration. In the webpack.config.js, the mode is set to production. It optimizes the bundled Javascript and prevents efficient debugging (variable values are missing, for instance). Also, it is possible to determine how the sources will be written in the source map files using devtoolModuleFilenameTemplate. To avoid using resolveSourceMapLocations in the launch.json of VS Code, I can set this option to [absolute-resource-path].

    Here is the final webpack.config.js:

    const path = require('path');
    
    module.exports = {
      entry: './src/main.ts',
      mode: 'development',
      module: {
        rules: [
          {
            test: /\.tsx?$/,
            use: 'ts-loader',
            exclude: /node_modules/,
          },
        ],
      },
      resolve: {
        extensions: ['.tsx', '.ts', '.js'],
      },
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
        devtoolModuleFilenameTemplate: '[absolute-resource-path]'
      },
      devtool: 'source-map',
    };
    

    Then, in the launch.json VS Code configuration file, as said just before, it is not useful to use resolveSourceMapLocations anymore. Also, the resolveSourceMapLocations option should point to the files that have a source map associated with. In my case, it should point to the bundled JavaScript file.

    Here is the final .vscode/launch.json file:

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Launch Program",
                "program": "${workspaceFolder}/dist/bundle.js",
                "request": "launch",
                "type": "node",
                "outFiles": [
                    "${workspaceFolder}/dist/**/*.js"
                ],
                "runtimeArgs": ["--enable-source-maps"],
                "sourceMaps": true,
                "resolveSourceMapLocations": [
                    "${workspaceFolder}/dist/*",
                ]
            },
        ]
    }
    

    Now, I can set a breakpoint in my TypeScript source file, and run the VS Code debugger, and the program stops at the location of the breakpoint and I can look at the values of the variables in VS Code.