【问题标题】:Debugging bundled javascript in Visual Studio 2015在 Visual Studio 2015 中调试捆绑的 javascript
【发布时间】:2015-09-07 20:32:23
【问题描述】:

我正在使用带有这个简单配置文件的 WebPack 来捆绑我的应用程序。

var path = require('path');

module.exports = {
    debug: true,
    devtool: 'source-map',

    context: path.join(__dirname, 'js'),
    entry: './main.js',
    output: {
        path: path.join(__dirname, 'Built'),
        filename: '[name].bundle.js'
    }
};

这会创建源映射,我可以轻松地使用它在所有流行的浏览器中调试我的原始 javascript 文件。但是,在 Visual Studio 中设置断点并运行项目不起作用,断点被禁用,显示“没有为此文档加载任何符号”。我正在通过 IE11 进行调试,Visual Studio 可以立即调试简单的 javascript,但捆绑后就无法使用了。

有迹象表明源映射有效,因为我进入控制台输出Unsupported format of the sourcemap。 sourcemap 生成上面的 using config 看起来像这样

{"version":3,"sources":["webpack:///webpack/bootstrap 2919a5f916c286b8e21a","webpack:///./main.js","webpack:///./structure_editor/content.js","webpack:///./structure_editor/test_bundle.js"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;;;;;;ACVA,8C;;;;;;ACAA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,6B","file":"main.bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 2919a5f916c286b8e21a\n **/","document.write(require(\"./structure_editor/content.js\"));\r\nvar TestBundle = require(\"./structure_editor/test_bundle.js\");\r\n\r\nvar test = new TestBundle();\r\ntest.testMe();\r\n\r\n//var StructureEditor = require(\"./structure_editor/structure_editor.js\");\r\n\r\n//var editor = new StructureEditor(0x00FF00);\r\n\r\n//editor.run();\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = \"It works from content.js.\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./structure_editor/content.js\n ** module id = 1\n ** module chunks = 0\n **/","var TestBundle = function () {\r\n    \r\n}\r\n\r\nTestBundle.prototype.testMe = function() {\r\n    var a = 10;\r\n    var b = 12;\r\n    var c = a + b;\r\n    document.write(c);\r\n};\r\n\r\nmodule.exports = TestBundle;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./structure_editor/test_bundle.js\n ** module id = 2\n ** module chunks = 0\n **/"],"sourceRoot":""}

所以我可以理解由于 webpack:// 可能不支持这种格式(尽管 IE 确实理解它)。但是,如果我知道 VS 的正确格式是怎样的,我可能能够调整 webpack 以生成这种格式。

我正在寻求任何想法、教程、.. 任何可以让它工作的东西。

【问题讨论】:

  • 求教程是题外话
  • @Thomas 情况可能并非如此,在花了整整两天时间寻找解决方案之后,没有找到任何工作或完整的解决方案。但是,可能在某个地方有一篇文章,没有引起太多关注,可以带给我。无论如何,最后一句话的语气应该表明我将非常感谢任何帮助。
  • 我也遇到了同样的问题。我用 VS'13 做了几次尝试,但没有成功。现在我在 Chrome 中使用调试器,但如果有人找到解决方案,我会非常高兴。
  • 通过将源映射嵌入到 javascript github.com/macromaniac/exbundle 中,我能够让它为 typescript 工作

标签: javascript visual-studio debugging webpack source-maps


【解决方案1】:

我没有完整的解决方案,但我确实缩小了范围。

首先要确保源映射和原始文件的路径都可用于 Visual Studio。我发现其中一些请求正在获取登录页面作为响应。我授予对地图和 ts 文件的匿名访问权限。我确实尝试使用适用于 Visual Studio 的 ts 文件的绝对文件系统路径,但浏览器似乎对此并不满意。

据我了解,以下是 SourceMapDevToolPlugin 插件的配置快捷方式。直接使用插件可以让您更好地控制生成的源映射。

devtool: 'source-map'

这意味着将上面的行替换为以下内容。

config.plugins.push(new webpack.SourceMapDevToolPlugin({
    filename: '[file].map',
    moduleFilenameTemplate: "[resource-path]",
    fallbackModuleFilenameTemplate: "[resource-path]?[hash]"
}));

注意[absolute-resource-path] 宏,它会生成文件系统路径,Visual Studio 可以使用这些路径访问文件,而无需通过网站加载它们。这些是在 sources 属性中的输出,反斜杠用第二个反斜杠转义(例如 C:\Projects\...)。正如我上面提到的,这破坏了浏览器中的调试。

此外,[resource-path] 宏似乎在调试期间被解析,就好像它是相对于包含源映射的文件夹一样。这对我的设置不正确。我添加了一个前缀,并使用类似于以下的内容进行排序。

"../../app/[resource-path]"

下一个问题是映射属性(在地图文件中)中某些行的最后一段。这个explanation of the source map format 在这里非常有用,但您需要知道的只是分号分隔行,并且每行可以有多个用逗号分隔的段。这些段可以对以下信息进行编码。

  • 生成的列
  • 出现的原始文件
  • 原始行号
  • 原创专栏
  • 如果有原始名称。

我发现如果我从行尾删除任何短段,Visual Studio 可以处理地图,我可以在原始文件中设置断点等(Typescript 文件被转换为 javascript,然后在我的案例中捆绑)。

为了删除短段,我在 Visual Studio 中对每个地图文件使用了以下手动过程。请注意,通过右键单击文档正文并从上下文菜单中选择“格式化文档”来格式化文件后,我发现文件更容易解释。

  • 在启用正则表达式的情况下执行替换操作。在查找字段中使用以下表达式,并将 $1 作为要替换的值。

    ,\s*[^\s\";]{1,3}?(;|\")

这将替换行尾仅包含 1、2 或 3 个字符的任何段。

在行尾设置断点可能会出现问题,但到目前为止我还没有能够打破它。我确实注意到,当调试器中出现导致执行停止的错误时,这些行并不总是匹配 - 可能是这种操作的结果?

我还编写了一个小控制台应用程序,它将对给定文件夹中的所有地图文件执行此修改。我在构建结束时自动运行它。

    static void Main(string[] args)
    {
        var sourceMapFolder = new DirectoryInfo(args[0]);

        foreach (var sourceMapFile in sourceMapFolder.EnumerateFiles("*.map"))
        {
            var sourceMapFilePath = sourceMapFile.FullName;

            var regex = new Regex(",\\s*[^\\s\\\";]{1,3}?(;|\\\")");

            var oldContent = File.ReadAllText(sourceMapFilePath);

            var newContent = regex.Replace(oldContent, "$1");

            File.WriteAllText(sourceMapFilePath, newContent);
        }
    }

我不确定是 Webpack 不应该生成段还是 Visual Studio 应该处理它们。

更新:我在 Connect 站点上为 Visual Studio 创建了一个 Bug,它涵盖了这个问题。

【讨论】:

  • 非常好,很彻底,有空我会试试这个。
  • @Scott 那么你现在完全能够在 Visual Studio 2015 中调试 webpack 捆绑的 TypeScript 了吗?我要试一试你这里的东西,看看我能不能更进一步
  • @MarkPieszak 是的。我们在VS2015中调试没有任何问题。您可能还想查看 joevbruno 的 webpack 插件。我还没有尝试过,但它看起来应该可以解决这些问题。 github.com/joevbruno/vs-fix-sourcemaps
  • 哇,太棒了,我今天下午要去试试,然后回复你。感谢斯科特的帮助:)
【解决方案2】:

我找到了解决您问题的方法。

在 webpack.config.js 中添加这个插件

plugins: [
  new webpack.SourceMapDevToolPlugin(
    sourceMapFilename, null,
    "[absolute-resource-path]", "[absolute-resource-path]")
]

sourceMapFilename 应该是您的包的名称。
如果您使用多个入口点,也可以使用 [name] 标签。

从你的 webpack.config.js 中删除它

devtool: 'source-map'

现在,当您开始在 VS 中使用 Internet Explorer 进行调试时,您应该点击您在 .ts 文件中设置的断点。

来源:https://github.com/webpack/webpack/issues/238

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2015-02-24
    • 2023-03-03
    • 2022-11-09
    • 2016-12-25
    • 2020-08-14
    • 1970-01-01
    • 2019-12-11
    • 2015-09-18
    • 2017-10-10
    相关资源
    最近更新 更多