dev c++怎么设置断点_在VSCode中调试webpack-dev-server项目

1e77cc8a3510420adcc36b257b7df1fd.png
(首发于知乎,如需转载请注明出处)

笔者以往web前端项目通常使用Chrome DevTools来进行调试(debug),编码则用的是VSCode,一直以来这款ide以它自带的调试功能作为一大卖点,于是今天来对VSCode调试功能的用法一探究竟,用它调试手头上的一个webpack-dev-server项目。


0.准备就绪

按照在网上查阅的资料[1],了解到想要对Chrome打开的JavaScript页面进行调试,需要在VSCode安装这样一个扩展:

cb17811890c55949ab2b02b498073d2a.png
Debugger for Chrome 扩展,至发稿为止最新版为4.12.6

下载安装很顺利,接着就开始做debug的配置。打开Run and Debug面板,在RUN AND DEBUG下拉框选择Add Config,VSCode自动创建launch.json文件,在光标处键入launch,选择Chrome: Launch,一套用于Chrome启动调试模式的配置模板就出来了:

b9766e39d32c32a553cd4003f4f4d146.png
Chrome: Launch 默认提供的debug配置模板

由于笔者的项目是通过npm加载webpack-dev-server搭建的开发环境,故还需要在真正开始debug前运行npm start命令启动server,怎么办呢?

所幸VSCode周到如斯,为我们提供了一个preLaunchTask属性——我们可以指定在debug前要运行的命令:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome",
            "url": "http://localhost:8080",
            "webRoot": "${workspaceFolder}",
            "preLaunchTask": "debug"
        }
    ]
}

同步在项目的tasks.json文件(通过命令面板输入>Task,选择Tasks: Configure Task)中加入运行命令的Task配置:

{
    "version": "2.0.0",
    "command": "npm",  // Task 要运行的命令
    "tasks": [
        {
            "label": "debug",  // Task 名称,在命令面板中显示
            "isBackground": true,
            "type": "npm",
            "script": "start",  // npm 要执行的 script 名称,对应 package.json 中的定义
            "path": "fe/",  // 执行命令所在的目录,相当于 cd 命令
            "detail": "编译至开发环境",  // Task 的描述,在命令面板中显示
            "group": "test",
            "problemMatcher": {
                "owner": "typescript",
                "fileLocation": "relative",
                "pattern": {
                    "regexp": "^([^s].*)((d+|,d+|d+,d+,d+,d+)):s+(error|warning|info)s+(TSd+)s*:s*(.*)$",
                    "file": 1,
                    "location": 2,
                    "severity": 3,
                    "code": 4,
                    "message": 5
                },
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": ".",
                    "endsPattern": "Version: webpack.+"
                }
            }
        }
    ]
}

注意上面这一大段并非都是必要的,反复测试后,总结出只有下面这些属性必须指定,其他将自动取默认值:

  1. versioncommand——配置的版本号、要运行的命令;
  2. label——Task的名称;
  3. isBackground——指示Task是否在后台运行,必须为true,告诉VSCode可以在Task运行时启动调试会话,具体的启动时机由后面的background.endsPattern指定;
  4. problemMatcher.pattern.regexp——编辑器从命令输出提取警告/错误/提示消息使用的pattern;
  5. background——指示Task后台运行时,VSCode如何跟踪Task运行状态,具体是依靠Task所执行命令的输出来判断的,两个pattern属性分别表示Task启动或结束时输出的消息特征(注意特征不惟一,可以从TERMINAL面板的输出自行确定),VSCode在接收到符合pattern的消息后开始或停止对Task的跟踪。当跟踪停止后,VSCode按launch.json配置启动调试会话(如不指定pattern,VSCode不会对tasks.json报错,但运行Task 10秒后将提示The specified task cannot be tracked. 并中止调试)。

1.见证奇迹的时刻

做好以上两块配置后,就可以按下F5键启动调试了:

477d3608956aa72293ba88be4d2ef813.png
启动调试后,VSCode控制台开始同步输出来自浏览器的控制台消息

然鹅,我们很快就会发现,虽然VSCode可以像浏览器一样正常输出消息,但在对源码中加入断点时,有些行的断点明明可以加,编辑器却加不上去。什么情况?

2.配置Source Map

这还要从webpack编译讲起。由于JS代码经过编译、打包才最终成为浏览器中实际运行的代码,其内容已经与原来的代码大相径庭。比方说同样是88行,在源码这是一句方法调用,到了实际代码那里就只是一个大括号。这就解释了为什么有些行的断点加不上去的现象。

2e5e78f5fc172fbe81d0c0633a59681c.png
没导出SourceMap的情况下,打断点的结果,第一个断点本来打在行首,却直接打在了变量中间;第二个断点本来没毛病,却提示"Unverified Breakpoint"

为了确保断点信息能被VSCode正确读取,浏览器需要知道原始代码和打包代码的映射关系,这就是SourceMap要干的事情。让我们在webpack.config.js加入导出SourceMap的选项:

module.exports = {
    // 若构建速度较慢,可改用 cheap-module-source-map 或 cheap-module-eval-source-map 模式,去掉列映射
    // 不建议使用 source-map,除非你不赶时间,也不在乎源码安全问题
    devtool: 'eval-source-map',
    ...
};

17d18dfe4735b161dd37c2da30943e26.png
配置SourceMap后重新启动调试、加入断点后

重新启动调试,已经可以正常显示所打的断点了。下面总算可以进行正常的调试了吧?

然鹅,当笔者在Index.jsx:749行加入断点后,加是加上去了,却发现运行时,这个断点并没有被触发。难道VSCode出bug了?还是说少了什么配置?

6ab89a86e08c7f7b364a23d9accafaa3.png
在Index.jsx:749行加入断点,没有被触发

3.sourceMapPathOverrides属性

于是笔者又继续查阅网上资料,注意到了一篇关于VSCode debugger的应用介绍[2]里面的代码:

            ...
            "webRoot": "${workspaceFolder}",
            "sourceMapPathOverrides": {
                "webpack:///./*": "${webRoot}/*",
                "webpack:///src/*": "${webRoot}/*",
                "webpack:///*": "*",
                "webpack:///./~/*": "${webRoot}/node_modules/*",
                "meteor:// app/*": "${webRoot}/*"
            },
            ...

放到launch.json里面,VSCode对sourceMapPathOverrides属性的说明是:

A set of mappings for rewriting the locations of source files from what the sourcemap says, to their locations on disk.

而且,看到这一串webpack:///,笔者联想到Chrome DevTools里面对模块文件提示的URL:

a71ebacaa057c8fc678757ca5c9ead51.png
打包后的文件都被 webpack 映射到了一个 webpack:/// 开头的地址

注意到这两点,笔者突然就明白了。

原来,sourceMapPathOverrides这个属性,是VSCode用来定位调试源文件的配置信息。设置了这个属性,VSCode才会在工作区目录下的特定位置寻找源文件,并将其关联到调试中。

而对应到笔者这个项目,源文件所在目录并非与VSCode工作区目录一致,而是工作区目录下的一个子目录fe/src,所以launch.json还要加上对SourceMap映射的源文件的定位配置,如下:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome",
            "url": "http://localhost:8080",
            "webRoot": "${workspaceFolder}/fe",  // 相对于工作区目录下的 fe 子目录寻找源文件
            "sourceMapPathOverrides": {
                "webpack:///./*": "${webRoot}/*",
                "webpack:///src/*": "${webRoot}/*",
                "webpack:///*": "*",
                "webpack:///./~/*": "${webRoot}/node_modules/*",
            },
            "preLaunchTask": "debug"
        }
    ]
}

Ctrl+Shift+F5键重新运行调试,bingo!

ef067c2320dfbc96ff9d87c66edbd306.png
先前在Index.jsx:749行加入的断点被成功触发

4.总结

重温一下这次基于VSCode的调试配置过程,可以发现这款ide在定制调试方式上提供了相当丰富的配置,应该说给予了开发人员相当大的自由度,但不同类型的JS项目所需做的配置各有要点、各不相同,初学者还是需要花一定的时间琢磨才能上手并融会贯通。通过这次体验VSCode调试功能,笔者也体会到了程序调试这门基本功之博大精深,后面还会抽空写一下如何在VSCode中利用Attach方式对外部NodeJS进行调试。

参考

  1. ^使用 Visual Studio Code 调试 webpack + react 项目 https://juejin.im/post/5ab3560d6fb9a028dc40ec99
  2. ^Debug browser code in vscode https://vcfvct.wordpress.com/2019/01/11/debug-browser-code-in-vscode/
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值