Jason G.
Jason G.

Reputation: 810

Breakpoints not working when debugging with VS Code and webpack-dev-server

I am currently working on trying to debug an Azure DevOps extension sample project from VS Code.

The project uses webpack-dev-server to host the extension locally for debugging purposes. That in combination with the Debugger for Chrome extension for VS Code and proper configuration should allow debugging and stepping through the typescript source code.

I am able to step through and debug the .ts file from Chrome but my breakpoints within VS Code report

Breakpoint set but not yet bound

and

Unverified breakpoint

Tool Versions:
VS Code: 1.38.1
Node.js: 10.11.0
Chrome: 77.0.3865.90
Debugger for Chrome: 4.12.0
typescript: 3.6.3
webpack: 4.41.0
webpack-cli: 3.3.9
webpack-dev-server: 3.8.1

tsconfig.json

{
    "compilerOptions": {
        "module": "amd",
        "target": "es5",
        "jsx": "react",
        "moduleResolution": "node",
        "rootDir": "src/",
        "outDir": "dist/",
        "types": [
            "vss-web-extension-sdk",
            "mocha"
        ]
    },   
    "filesGlob": [
        "src/**/*.ts",
        "src/**/*.tsx"
    ]    
}

tsconfig.dev.json

{
    "extends": "./tsconfig",
    "compilerOptions": {
      "sourceMap": true
    }
}

[webpack] base.config.js

const path = require("path");
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    context: path.join(__dirname, '../src'),
    entry: {
        registration: "./app.ts",
        dialog: "./dialog.tsx"
    },
    output: {
        filename: "[name].js",
        libraryTarget: "amd"
    },
    externals: [
        /^VSS\/.*/, /^TFS\/.*/, /^q$/
    ],
    resolve: {
        extensions: [
            "*",
            ".webpack.js",
            ".web.js",
            ".ts",
            ".tsx",
            ".js"],
        modules: [
            path.resolve("./src"),
            'node_modules'
        ]
    },
    module: {
        rules: [
            {
                test: /\.s?css$/,
                loaders: ["style-loader", "css-loader", "sass-loader"]
            }
        ]
    },
    plugins: [
        new CopyWebpackPlugin([
            { from: "../node_modules/vss-web-extension-sdk/lib/VSS.SDK.min.js", to: "libs/VSS.SDK.min.js" },
            { from: "../src/*.html", to: "./" },
            { from: "../marketplace", to: "marketplace" },
            { from: "../vss-extension.json", to: "vss-extension-release.json" }
        ])
    ]
}

[webpack] dev.config.js

const path = require("path");
const merge = require('webpack-merge');
const baseConfig = require('./base.config.js');

module.exports = merge(baseConfig, {
  mode: 'development',
  devtool: 'source-map',
  devServer: {
    port: '9085',
    https: true,
    writeToDisk: true
  },
  module: {
    rules: [
        {
            test: /\.tsx?$/,
            loader: "ts-loader",
            options: {
              configFile: '../tsconfig.dev.json'
            },
        }
    ]
  },
  output: {
    path: path.join(__dirname, '../dist'),
  }
});

launch.json

{
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome",
            "url": {{omitted}},
            "webRoot": "${workspaceFolder}/dist",
            "sourceMaps": true,
            "sourceMapPathOverrides": {
                "webpack:///./*": "${workspaceFolder}/src/*",
                "webpack:///../node_modules/*": "${workspaceFolder}/node_modules/*",
            },
            "trace": true
        },
        {
            "type": "node",
            "request": "launch",
            "name": "Webpack-dev-server",
            "program": "${workspaceFolder}/node_modules/webpack-dev-server/bin/webpack-dev-server.js",
            "args": [
                "--config",
                "webpack/dev.config.js"
            ],
            "sourceMaps": true,
            // "smartStep": true,
            "trace": true,
            "autoAttachChildProcesses": true
        }
      ]
}

Project structure

project structure

Sources structure in Chrome

sources structure in chrome

Original project source code
https://github.com/cschleiden/vsts-quick-decompose

These were a few resources that I already found but no dice:
Debugging webpack dev server in vs code?
How to use VS Code debugger with webpack-dev-server (breakpoints ignored)
https://medium.com/acoolthingilearned/vs-code-chrome-debugger-and-webpack-10b5e3618d05
https://code.visualstudio.com/docs/typescript/typescript-debugging

Thank you in advanced for any help!

Upvotes: 2

Views: 10258

Answers (2)

Roque Orts
Roque Orts

Reputation: 360

In your launch.json file, Try to set the program key to your index.js/app.js file.

{
            "name": "Launch webpack",
            "type": "node",
            "request": "launch",
            "cwd": "${workspaceRoot}",
            **"program": "src/index.ts"**,    
            "outFiles": [
                "${workspaceRoot}/dist/bundle.js"
              ],     
            "runtimeExecutable": "C:\\Users\\...\\bin\\node",
}

Upvotes: 0

Jason G.
Jason G.

Reputation: 810

At this time the VS Code debugger for Chrome does not support iframes. Azure DevOps loads extensions through iframes. This blog plost here led me to the answer:

https://devblogs.microsoft.com/devops/streamlining-azure-devops-extension-development/

Here is the open GitHub issue labeled as an enhancement:

https://github.com/microsoft/vscode-chrome-debug/issues/786

The current working alternative is to use the VS Code debugger for Firefox.
Make sure that you authorize the self signed cert in Firefox

Updated working configuration in conjunction with Firefox plugin:

launch.json

{
    "configurations": [
        {
            "name": "Launch Firefox",
            "type": "firefox",
            "request": "launch",
            "url": "https://localhost:9085",
            "reAttach": true,
            "pathMappings": [
                {
                    "url": "webpack:///",
                    "path": "${workspaceFolder}/"
                }
            ]
        }
      ]
}

[webpack] base.config.js

const path = require("path");
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    entry: {
        registration: path.resolve(__dirname, "../src/app.ts"),
        dialog: path.resolve(__dirname, "../src/dialog.tsx")
    },
    output: {
        filename: "[name].js",
        libraryTarget: "amd",
        path: path.join(__dirname, '../dist'),
    },
    externals: [
        /^VSS\/.*/, /^TFS\/.*/, /^q$/
    ],
    resolve: {
        extensions: [
            "*",
            ".webpack.js",
            ".web.js",
            ".ts",
            ".tsx",
            ".js"],
        modules: [
            path.resolve("./src"),
            'node_modules'
        ]
    },
    module: {
        rules: [
            {
                test: /\.s?css$/,
                loaders: ["style-loader", "css-loader", "sass-loader"]
            }
        ]
    },
    plugins: [
        new CopyWebpackPlugin([
            { from: "./node_modules/vss-web-extension-sdk/lib/VSS.SDK.min.js", to: "libs/VSS.SDK.min.js" },
            { from: "./src/*.html", to: "./", flatten: true },
            { from: "./marketplace", to: "marketplace" },
            { from: "./vss-extension.json", to: "vss-extension-release.json" }
        ])
    ]
}

[webpack] dev.config.js

const path = require("path");
const merge = require('webpack-merge');
const baseConfig = require('./base.config.js');

module.exports = merge(baseConfig, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    contentBase: path.resolve(__dirname, '../dist'),
    port: 9085,
    https: true
  },
  module: {
    rules: [
        {
            test: /\.tsx?$/,
            loader: "ts-loader",
            exclude: /node_modules/,
            options: {
              configFile: path.resolve(__dirname, '../tsconfig.dev.json')
            },
        }
    ]
  }
});

Upvotes: 2

Related Questions