阮一峯老師的講解: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"
}
複製代碼