简体   繁体   English

在Visual Studio 2015中调试捆绑的javascript

[英]Debugging bundled javascript in Visual Studio 2015

I'm using WebPack with this simple config file to bundle my application. 我正在使用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'
    }
};

This creates source mapping that I can easily use to debug my original javascript files in all popular browsers. 这将创建源映射,我可以轻松地在所有流行的浏览器中调试我的原始javascript文件。 However, setting breakpoint inside Visual Studio and running the project doesn't work, the breakpoints are disabled saying "No symbols have been loaded for this document". 但是,在Visual Studio中设置断点并运行项目不起作用,断点被禁用说“没有为此文档加载符号”。 I'm debugging through IE11, where simple javascript can be debugged right away by Visual Studio, but after bundling this doesn't work anymore. 我正在通过IE11进行调试,其中简单的javascript可以通过Visual Studio立即调试,但在捆绑之后这不再起作用了。

There is a sign that the sourcemapping works, because I get in console output Unsupported format of the sourcemap . 有一个迹象表明源映射有效,因为我在控制台输出中得到Unsupported format of the sourcemap The sourcemap generated the using config above looks like this 生成上面使用配置的源地图如下所示

{"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":""}

So I can understand that this format might not be supported because of the webpack:// (although IE does understand it). 所以我可以理解,由于webpack://可能不支持这种格式(尽管IE确实理解它)。 However, if I knew how the proper format for VS looks like I might be able to tweak webpack to produce such format. 但是,如果我知道VS的正确格式如何,我可能能够调整webpack来生成这样的格式。

I'm asking for any ideas, tutorials,.. whatever to get this working. 我要求任何想法,教程,......无论如何工作。

I don't have a full solution to the problem but I did narrow it down a bit. 我没有完全解决问题的方法,但我确实缩小了一点。

The first thing to ensure is that the paths to both the source map and the original files are available to Visual Studio. 要确保的第一件事是Visual Studio可以使用源映射和原始文件的路径。 I found that some of these request were getting the login page as a response. 我发现其中一些请求是将登录页面作为响应。 I granted anonymous access to the map and ts files. 我授予了对地图和ts文件的匿名访问权限。 I did try using absolute, file system paths for the ts files which worked for Visual Studio but the browsers did not seem very happy about it. 我确实尝试使用适用于Visual Studio的ts文件的绝对文件系统路径,但浏览器似乎并不高兴。

From what I understand, the following is a shortcut for configuration of the SourceMapDevToolPlugin plugin. 据我所知,以下是配置SourceMapDevToolPlugin插件的快捷方式。 Going direct to the plugin will give you more control over the source maps that are generated. 直接进入插件可以让您更好地控制生成的源地图。

devtool: 'source-map'

That would mean replacing the line above with something like the following. 这意味着用以下内容替换上面的行。

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

Note the [absolute-resource-path] macro which will result in file system paths that Visual Studio can use to access the files without loading them through the website. 请注意[absolute-resource-path]宏,它将生成Visual Studio可以用来访问文件的文件系统路径,而无需通过网站加载它们。 These are output in the sources property with backslashes escaped with a second backslash (C:\\Projects\\... for example). 这些是在sources属性中输出的,反斜杠使用第二个反斜杠进行转义(例如,C:\\ Projects \\ ...)。 As I noted above though, this broke debugging in the browsers. 正如我上面提到的,这打破了浏览器中的调试。

Also, the [resource-path] macro appears to be resolved during debugging as if it is relative to the folder that contains the source maps. 此外,[resource-path]宏似乎在调试期间被解析,就好像它是相对于包含源映射的文件夹一样。 This was not correct for my setup. 这对我的设置不正确。 I added a prefix and used something similar to the following to sort that out. 我添加了一个前缀,并使用类似于以下的东西来排序。

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

The next issue was with the last segments for some of the lines within the mappings property (within the map files). 下一个问题是映射属性中某些行的最后一个段(在映射文件中)。 This explanation of the source map format was very helpful here but pretty much, all you need to know is that semi colons separate lines and that each line can have multiple segments separated by commas. 这里对源地图格式的解释非常有用,但是很多,你需要知道的是,半冒号分隔行,每行可以有多个用逗号分隔的段。 The segments can encode the following information. 段可以编码以下信息。

  • Generated column 生成的列
  • Original file this appeared in 原始文件出现在
  • Original line number 原始行号
  • Original column 原始栏目
  • And if available original name. 如果有原始名称。

I found that if I removed any short segments from the ends of lines that Visual Studio could process the map and I could set breakpoints etc. in the original files (Typescript files that were converted to javascript which was then bundled in my case). 我发现,如果我删除了Visual Studio可以处理地图的行末端的任何短段,我可以在原始文件中设置断点等(转换为javascript的Typescript文件,然后捆绑在我的情况下)。

To remove the short segments I used the following, manual process in Visual Studio for each of the map files. 为了删除短段,我使用了以下内容,在Visual Studio中为每个映射文件手动处理。 Note that I found it easier to interpret the files after I had formatted them by right clicking in the body of the document and selecting Format Document from the context menu. 请注意,通过右键单击文档正文并从上下文菜单中选择“格式化文档”,我发现在格式化文件后,我发现更容易解释这些文件。

  • Perform a replace operation with regular expressions enabled. 执行启用正则表达式的替换操作。 Use the following expression in the find field and $1 as the value to replace. 在find字段中使用以下表达式,并将$ 1作为要替换的值。

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

在此输入图像描述

This will replace any segments that contain only 1, 2 or 3 characters at the end of lines. 这将替换在行尾仅包含1,2或3个字符的任何段。

It is possible that there will be problems setting breakpoints at the ends of lines but I have not been able to break it so far. 在行的末尾设置断点可能会出现问题,但到目前为止我还无法破解它。 I did notice though that when there were errors that caused execution to stop in the debugger that the lines did not always match up - maybe a result of this manipulation? 我确实注意到,当有错误导致执行在调试器中停止时,行并不总是匹配 - 可能是这种操作的结果?

I also wrote a little console application that will perform this modification on all map files in a given folder. 我还写了一个小的控制台应用程序,它将对给定文件夹中的所有地图文件执行此修改。 I run this automatically at the end of our build. 我在构建结束时自动运行它。

    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);
        }
    }

I am unsure as to whether it is Webpack which should not be generating the segments or Visual Studio which should be handling them. 我不确定Webpack是否应该生成段或Visual Studio应该处理它们。

Update: I created a Bug on the Connect site for Visual Studio which covers this issue. 更新:我在Visual Studio的Connect站点上创建了一个Bug ,它涵盖了这个问题。

I found a solution for your problem. 我找到了解决问题的方法。

In the webpack.config.js add this plugin 在webpack.config.js中添加此插件

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

sourceMapFilename should be the name of your bundle. sourceMapFilename应该是您的包的名称。
You can also use the [name] tag if you use multiple entry points. 如果使用多个入口点,也可以使用[name]标签。

remove this from your webpack.config.js 从webpack.config.js中删除它

devtool: 'source-map'

Now when you start debugging in VS with Internet Explorer you should hit the breakpoints you set up in your .ts files. 现在,当您使用Internet Explorer在VS中开始调试时,您应该点击在.ts文件中设置的断点。

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

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM