阮一峰老师的讲解:JavaScript Source Map 详解
简单来讲,SourceMap可以让压缩/翻译过的最终版的各类文件与原来未压缩过的文件对应起来。那么断点逻辑容易理解:
1.给浏览器提供未压缩的源码和SourceMap文件
2.浏览器跑最终版本的js代码时,经过SourceMap找到对应源码的位置,若是该对应源码处被用户打上了断点标记,那么中断
javascript
同时:
1.仅在你F12打开开发者工具后,浏览器才会去加载最终版代码指示的SourceMap文件(所以基本不影响普通用户加载速度),再根据SourceMap文件指示去加载源码。以下图的文件↓ php
/a.js
时,浏览器会加载
协议://域名/a.js
,显然线上没有此文件。但咱们能够经过浏览器Sources->Filesystem添加文件夹映射,即映射到本地项目的源码中进行断点调试。固然浏览器窗口会给出相应的ui反馈↓
其实是设置webpack配置中的devtool:'source-map'
选项。这里具体位置出入较大,你多是@vue/cli初始化的项目、使用webpack的vue模板构建的项目、项目负责人自行从新组织过的项目等,这里就请自行了解到哪配置webpack了。html
注意:这个devtool:'source-map'
能够说是必须的,其余生成SourceMap的方式都不太适合断点而适合分析,不然因为上述缘由出现各类奇怪表现。vue
在最完整的SourceMap设置下你应该能看到这个结构(a.js是我额外加进去的,不用管)↓ java
webpack://
,这个就是webpack自定义的网络应用层协议,跟
http://
和
https://
同样道理。
webpack:///路径
。另外
.
真的就是一个文件夹
名,不表明当前目录(http协议中
https://juejin.im/timeline
和
https://juejin.im/./timeline
一回事)
webpack:///src
中通常是咱们的原始vue文件,
webpack:///./src
是部分处理事后的vue和png等资源
app.js
和他的
app.js.map
有些什么↓
app.js
文件中最后一行会是
//# sourceMappingURL=app.js.map
,当咱们打开开发者工具,浏览器就会去加载这个map文件。
app.js.map
里面应该有这样几行:
"version":3,
"sources":[
"webpack:///src/app.js",
"webpack:///./src/app.js",
...
]
复制代码
也就是这个SourceMap可以把编译后的代码映射到sources
中指示的若干个js源文件的对应位置。
(3)浏览器能够看做一个强大的IDE,此时咱们能够在开发者工具的source面板找到这些文件,并打上断点进行调试node
实质上vscode调试,就是经过调试扩展链接浏览器以获取调试信息,同时经过本身的ui和交互让咱们感受不到在使用上述浏览器功能。所以若是你发现vscode中调试很奇怪,那么按前面步骤去看看浏览器中能不能正常断点调试,若是浏览器中表现也是这么奇怪,那么无论你vscode怎么配置基本都是徒劳的。理清思路后,进入核心主题(须要安装Debugger for Chrome 这个扩展)webpack
本身命令行启动或者快捷方式,追加启动参数--remote-debugging-port=9222
,这个是让chrome打开9222
调试端口,咱们的vscode扩展会经过这个端口获取浏览器提供的调试信息。下面vscode会以attach方式链接,所以请先启动浏览器,本地跑你的vue项目,并打开目标页面。ios
Normally, if Chrome is already running when you start debugging with a launch config, then the new instance won't start in remote debugging mode.git
注意,若是你已常常规启动chrome,那么再启动一个chrome通常状况下他不会以远程调试模式启动。所以attach方式请关掉全部chrome实例,而且从新以远程调试模式启动一次(如上面参数,能够直接访问http://localhost:9222
看看有没有回应)github
来源:Debugging
可选参数并不统一,需查看各个扩展说明。一些绝大部分扩展都支持的参数官网有说明,不重复了。下面是attach方式中这个扩展经常使用的参数:
true
。可看成上面提到的把目录加入Filesystem)${webRoot}
变量。${webRoot}
是下面两个参数的默认设置用到的变量,从而使得该参数具备意义"webRoot": "${workspaceFolder}"
is just shorthand for a pathMapping like { "/": "${workspaceFolder}"
}(实际上做用基本同下面,区别主要是人类“语义”上的区别和默认的设置不一样。常规文件映射用这个,map文件映射用下面那个,但没有严格区分)${workspaceFolder}
- the path of the folder opened in VS Code${workspaceFolderBasename}
- the name of the folder opened in VS Code without any slashes (/)${file}
- the current opened file${relativeFile}
- the current opened file relative to workspaceFolder${fileBasename}
- the current opened file's basename${fileBasenameNoExtension}
- the current opened file's basename with no file extension${fileDirname}
- the current opened file's dirname${fileExtname}
- the current opened file's extension${cwd}
- the task runner's current working directory on startup${lineNumber}
- the current selected line number in the active file${selectedText}
- the current selected text in the active file${execPath}
- the path to the running VS Code executable来源:Variables Reference 这个点进去看他举例就能理解了,不翻译了。
设置如何映射。下面是它的默认设置
// Note: These are the mappings that are included by default out of the box, with examples of how they could be resolved in different scenarios. These are not mappings that would make sense together in one project.
// webRoot = /Users/me/project
"sourceMapPathOverrides": {
"webpack:///./~/*": "${webRoot}/node_modules/*", // Example: "webpack:///./~/querystring/index.js" -> "/Users/me/project/node_modules/querystring/index.js"
"webpack:///./*": "${webRoot}/*", // Example: "webpack:///./src/app.js" -> "/Users/me/project/src/app.js",
"webpack:///*": "*", // Example: "webpack:///project/app.ts" -> "/project/app.ts"
"webpack:///src/*": "${webRoot}/*", // Example: "webpack:///src/app.js" -> "/Users/me/project/app.js"
"meteor://💻app/*": "${webRoot}/*" // Example: "meteor://💻app/main.ts" -> "/Users/me/project/main.ts"
}
复制代码
其中的${webRoot}
是咱们自定义值的一个变量。你须要作的,就是保证webpack:///
下的各类文件能被正确映射到咱们的开发目录文件。实际就是设置Filesystem(这个某些状况下可右键自定义如何映射到网络资源,不展开了)
注意:sourceMapPathOverrides一旦被自定义设置,那么原来的默认设置无效(就是被从新赋值的意思);存在多个匹配时,后面出现匹配的覆盖前面存在的匹配。
搞了一大堆,其实就是这么几个意思:
1.chrome远程调试模式启动,先确保你知道是哪一个端口可被vscode链接、确保你能在F12里面断点不会有奇奇怪怪的现象
2.vscode建立调试,在launch.json中,点击右下角的添加配置,更改端口port为上面你启动的端口
3.设置url或者urlFilter参数(attach要求你已经打开了这个url对应的页面。launch方式就是多了自动帮你打开这个页面,没多大区别)
4.设置webRoot参数,由于默认的sourceMapPathOverrides中用到了${webRoot}
这个变量
5.等一会,attach上目标页面后,vscode底部栏会变色,能够了。热更新后有问题请刷新页面
6.理解为重,最多见错误是webRoot与sourceMapPathOverrides胡乱设置没有对应上。通常而言,只要你的vue项目是工做目录下有个src文件夹,里面有main.js、App.vue这样结构的话,那么最小化的配置只要6个参数:
{
"type": "chrome",
"request": "attach",
"name": "hello world",
"port": 9222,
"webRoot": "${workspaceFolder}/src",
"url": "http://localhost:8080"
}
复制代码