前言
任何一門語言都有對應的調試方法,也有對應的調試工具,JavaScript當然也不例外。最常用的莫過于浏覽器這個調試工具了。而今天我們要講的對于這個基礎調試就不細說,我會将目前所有調試javascript(nodejs)的方法以及工具(主要是VS Code)介紹一下,然後順便講解一下webpack的sourcemap功能。
1 前置條件
- Chrome: 55+
- Nodejs: 6.3+
我目前使用的Nodejs(7.10)和Chome(Version 59.0.3071.104)
該文章配合了一個demo:
2 如何利用sourceMap來調試或者定位我們的錯誤
現代的網頁越來越複雜,加上有babel這類的工具來對我們寫的Js代碼轉譯,然後有uglify這類工具進行壓縮,最後我們看到的代碼與原先的代碼相差将會很大,單純靠列印調試是效率極低的,于是這個時候sourceMap這個功能便應運而生。
在這裡我們結合最火爆的打包工具webpack來說說如果利用webpack的sourcemap功能來調試以及定位錯誤的位置。
首先使用chrome調試帶有sourcemap功能的js檔案需要有下面的條件:
- chrome開啟支援
的功能sourcemap
- webpack配置
參數devtool
開啟chrome的sourcemap支援:
如果配置webpack但是沒有開啟支援,那麼chrome的控制台将會是這樣的:
如果開啟支援但是沒有對應的sourcemap檔案:
滿足以上兩個條件就可以:
在webpack的官網文檔中提供了10中方法,那麼這10種方法有哪些差別,我們要如何更好地利用這些參數去調試呢?下面我們一一通過圖檔來簡單地過一遍。
2.1 eval
eval
該方法官方文檔标榜是效率最高的,它會使用
eval
執行每一個module,然後每個module後面都會跟着
//@ sourceURL
。如下圖:
配置如圖:
生成的檔案如下圖:
官網文檔說該方法的最大缺點是不能準确地顯示行号,但下面的報錯圖是我截取的,貌似行号是正确的顯示的。不建議用于産品環境下。
2.2 eval-source-map
eval-source-map
這個就是把
eval
的
sourceURL
換成了完整souremap資訊的
DataUrl
,剛開始第一次編譯的時候是比較慢,但重新編譯的時候速度會大大地變快。其對應的行号可以正确顯示因為其是從原始代碼來做映射的。對應的配置和報錯圖如下:
報錯提示:
不建議用于産品環境下。
2.3 inline-source-map
inline-source-map
為每一個檔案添加
sourcemap
的
DataUrl
,注意這裡的檔案是打包前的每一個檔案而不是最後打包出來的,同時這個
DataUrl
是包含一個檔案完整
souremap
資訊的`Base64 格式化後的字元串,而不是一個url。對應的配置檔案:
錯誤的定位情況以及生成的檔案如下:
不建議用于産品環境下。
2.4 cheap-eval-source-map
cheap-eval-source-map
類似于
eval-source-map
,但是取名為
cheap
是因為它沒有列映射,隻有行映射。對應的webpack配置如圖:
其生成的檔案如下:
報錯的定位情況:
不建議用于産品環境下。
2.5 cheap-module-eval-source-map
cheap-module-eval-source-map
類似于
cheap-eval-source-map
,但是官網稱這個選項可以更好地處理映射。對應的配置如下:
錯誤的定位情況如下:
不建議用于産品環境下。
2.6 source-map
source-map
該選項會生成一個sourcemap檔案,然後在bundle檔案中添加一個引用聲明,這樣開發工具可以知道在哪裡找到sourcemap檔案,對應的配置如下:
生成的sourcemap檔案大緻如下:
錯誤定位情況如下:
2.7 hidden-source-map
hidden-source-map
和
source-map
一樣,但是不會添加引用聲明到bundle檔案中。如果你隻想要讓sourcemap從錯誤報告中映射錯誤堆棧追溯,但是不想暴露你的sourcemap檔案給開發者工具的話,這種方式很适合你的。對應的配置如下:
錯誤定位情況:
2.8 cheap-source-map
cheap-source-map
類似于
source-map
,但是沒有列映射。對應的配置如下:
錯誤定位情況:
bundle檔案最後的注釋如下:
2.9 cheap-module-source-map
cheap-module-source-map
此種方法也沒有列映射,同時 loader 的 sourcemap 也被簡化為隻包含對應行的。最終的
sourcemap
隻有一份,它是
webpack
對 loader生成的
sourcemap
進行簡化,然後再次生成的。對應的配置如下:
錯誤定位情況:
2.10 nosources-source-map
nosources-source-map
該方法生成的sourcemap檔案沒有
sourcesContent
字段,如下:
配置如下:
錯誤定位情況:
3 前端代碼debugger調試
如果我們在前端代碼中指定的位置打斷點,除了可以直接在控制台中直接打斷點,還可以在你的代碼中添加
debugger
關鍵詞來打斷點:
4 Nodejs的調試
Nodejs寫多了,就免不了調試,而最低級的console列印貌似滿足不了調試nodejs,于是我們就開始尋求新的調試方法,今天就給大家列舉兩種常用的調試工具。
首先我們需要開啟Nodejs調試狀态,隻需要在啟動的檔案使用
--inspect
即可,如下圖:
于是在終端會列印出下面的紅框中的重要的一行話:
Debugger listening on port 5859.
[1] Warning: This is an experimental feature and could change at any time.
[1] To start debugging, open the following URL in Chrome:
[1] chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:5859/39515fe7-3f4a-40b2-8b95-6196a2d22d73
眼尖的童鞋肯定會發現為什麼你的列印中出現了兩次
Debugger listening on port
,那是因為我使用的Nodejs檔案監控重新開機包是
piping
,而這個包的一個最大的特點便是:
使用預設的設定的時候,那麼将會啟動第二個執行個體,這個執行個體由第一個執行個體監控。Piping在第一個執行個體中故意人為的引發uncaughtException操作來避免繼續執行其他代碼,是以真正執行伺服器代碼的是在第二個執行個體,這也就是我們應該使用第二個列印的原因。
4.1 Chrome調試Nodejs
基于上面的介紹,我們将第二個執行個體列印的調試位址粘貼複制到Chome位址欄中,即可打開調試視窗,然後在你想要打斷點的地方加上斷點即可:
4.2 VSCODE調試Nodejs
除了使用chome,你還可以使用VSCode這個神器。使用VScode調試得配置一下:
使用如下的調試配置:
{
// Use IntelliSense to learn about possible Node.js debug attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Process",
"type": "node",
"protocol": "inspector",
"request": "attach",
"address": "localhost",
"port": 5859
}
]
}
其中端口的配置記得和之前列印的調試端口一緻,這裡都是5859。
然後啟動你的Nodejs服務,接着按下
F5
,就可以進入調試狀态,打上斷點,同樣可以檢視本地變量/堆棧等等資訊。如下圖:
參考
- Devtool
- Node.js Debugging in VS Code
- Node Debug Architecture