Typescript 使用VS代码和webpack dev服务器调试时断点不起作用

Typescript 使用VS代码和webpack dev服务器调试时断点不起作用,typescript,webpack,visual-studio-code,webpack-dev-server,azure-devops-extensions,Typescript,Webpack,Visual Studio Code,Webpack Dev Server,Azure Devops Extensions,我目前正在尝试从VS代码调试Azure DevOps扩展示例项目 该项目使用webpack dev server在本地托管扩展以进行调试。结合VS代码的Chrome扩展调试器和适当的配置,应该允许调试和单步执行typescript源代码 我能够从Chrome中单步调试.ts文件,但我的断点位于VS代码报告中 断点已设置但尚未绑定 及 未验证断点 工具版本: VS代码:1.38.1 Node.js:10.11.0 铬:77.0.3865.90 Chrome的调试器:4.12.0 打字稿:3.6.3

我目前正在尝试从VS代码调试Azure DevOps扩展示例项目

该项目使用webpack dev server在本地托管扩展以进行调试。结合VS代码的Chrome扩展调试器和适当的配置,应该允许调试和单步执行typescript源代码

我能够从Chrome中单步调试.ts文件,但我的断点位于VS代码报告中

断点已设置但尚未绑定

未验证断点

工具版本:
VS代码:1.38.1
Node.js:10.11.0
铬:77.0.3865.90
Chrome的调试器:4.12.0
打字稿:3.6.3
网页:4.41.0
网页包cli:3.3.9
网页包开发服务器: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"
    ]    
}
{
    "extends": "./tsconfig",
    "compilerOptions": {
      "sourceMap": true
    }
}
{
    "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
        }
      ]
}
{
    "configurations": [
        {
            "name": "Launch Firefox",
            "type": "firefox",
            "request": "launch",
            "url": "https://localhost:9085",
            "reAttach": true,
            "pathMappings": [
                {
                    "url": "webpack:///",
                    "path": "${workspaceFolder}/"
                }
            ]
        }
      ]
}
tsconfig.dev.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"
    ]    
}
{
    "extends": "./tsconfig",
    "compilerOptions": {
      "sourceMap": true
    }
}
{
    "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
        }
      ]
}
{
    "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 = {
    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" }
        ])
    ]
}
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'),
  }
});
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" }
        ])
    ]
}
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')
            },
        }
    ]
  }
});
[webpack]dev.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" }
        ])
    ]
}
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'),
  }
});
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" }
        ])
    ]
}
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')
            },
        }
    ]
  }
});
launch.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"
    ]    
}
{
    "extends": "./tsconfig",
    "compilerOptions": {
      "sourceMap": true
    }
}
{
    "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
        }
      ]
}
{
    "configurations": [
        {
            "name": "Launch Firefox",
            "type": "firefox",
            "request": "launch",
            "url": "https://localhost:9085",
            "reAttach": true,
            "pathMappings": [
                {
                    "url": "webpack:///",
                    "path": "${workspaceFolder}/"
                }
            ]
        }
      ]
}
项目结构

铬合金中的源结构

原始项目源代码

这些是我已经找到的一些资源,但没有骰子:




提前感谢您的帮助

目前,Chrome的VS代码调试器不支持iFrame。Azure DevOps通过iFrame加载扩展。这个博客让我找到了答案:

以下是标记为增强的开放GitHub问题:

当前的替代方案是使用Firefox的VS代码调试器。
确保在Firefox中授权自签名证书

与Firefox插件一起更新工作配置:

launch.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"
    ]    
}
{
    "extends": "./tsconfig",
    "compilerOptions": {
      "sourceMap": true
    }
}
{
    "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
        }
      ]
}
{
    "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 = {
    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" }
        ])
    ]
}
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'),
  }
});
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" }
        ])
    ]
}
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')
            },
        }
    ]
  }
});
[webpack]dev.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" }
        ])
    ]
}
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'),
  }
});
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" }
        ])
    ]
}
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')
            },
        }
    ]
  }
});