Typescript 使用VS代码和webpack dev服务器调试时断点不起作用
我目前正在尝试从VS代码调试Azure DevOps扩展示例项目 该项目使用webpack dev server在本地托管扩展以进行调试。结合VS代码的Chrome扩展调试器和适当的配置,应该允许调试和单步执行typescript源代码 我能够从Chrome中单步调试.ts文件,但我的断点位于VS代码报告中 断点已设置但尚未绑定 及 未验证断点 工具版本: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代码: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')
},
}
]
}
});