如何在 Chrome 中調試 TypeScript
原文作者:Shalitha Suranga
原文地址:https://blog.logrocket.com/how-to-debug-typescript-chrome/
翻譯:一川
軟件錯誤是編程錯誤或軟件程序的意外行為。調試是指檢查和刪除軟件系統中的錯誤的過程。程序員使用各種技術進行調試;一些開發人員將輸出寫入終端,而另一些開發人員則使用調試器工具來執行和監視源代碼。
Google Chrome 網絡瀏覽器提供了一個內置的調試器,其中包含著名的 DevTools 模塊,用于調試 JavaScript。Chrome DevTools 實現了對source map的支持,并且可以檢查 Node.js 和 Deno 調試器實例。因此,無論您是在客戶端應用(即基于TypeScript 的 React 應用)還是在服務器端應用中使用 TypeScript,您都可以使用 Chrome 進行調試。
Chrome DevTools 還可以檢查 Android WebViews。幾乎所有基于 JavaScript 的跨平臺移動應用開發框架都實現了 DevTools 協議或提供內置的基于 Web 的調試器 UI,因此在 Chrome 中也可以調試基于TypeScript的移動應用。
Web瀏覽器內置了對JavaScript和WebAssembly的支持,但不支持TypeScript。那么,如果 Chrome 中沒有原生執行 TypeScript,如何調試它呢?Chrome 和所有標準網絡瀏覽器都支持處理 JavaScript source maps。
JavaScript source maps通常將特定 JavaScript 源代碼的特定形式映射到瀏覽器執行的 JavaScript 源代碼。例如,很難在瀏覽器中調試縮小的 JavaScript 文件,但是如果您將源映射與縮小版本一起使用,則在執行其縮小版本時可以輕松調試可讀的 JavaScript 文件。同樣,您可以在 Chrome 中運行 TypeScript 文件的轉譯 JavaScript 版本時對其進行調試。
官方的 TypeScript 編譯器 tsc 可以在轉譯過程中生成源映射,所以現在你可以編寫 TypeScript 代碼,連同源映射一起轉譯到 JavaScript,并在執行轉譯的 JavaScript 代碼的同時在瀏覽器中調試 TypeScript 代碼。這就是Chrome允許開發人員調試客戶端TypeScript的方式。此外,Chrome可以通過內置的遠程調試功能調試在Android WebView/Chrome上運行的客戶端TypeScript代碼。
使用服務器端運行時,如 Node 和 Deno,您可以通過 v8 運行 JavaScript/TypeScript 并偵聽 Chrome DevTools 調試器事件。這就是在Chrome中調試服務器端TypeScript代碼的方法。支持基于 TypeScript 開發的移動框架,如React Native和 NativeScript,也可以與 Chrome 桌面應用程序互連,因此也可以在 Chrome 上調試 TypeScript 移動應用程序。
當您使用前端框架構建應用程序時,其 TypeScript 模板通常附帶已包含的 TypeScript 編譯器配置,并且它們會自動為您生成source map。但在某些情況下,您需要配置 TypeScript 編譯器,生成自己的source map,并使用 HTML script 標記手動鏈接轉譯的 TypeScript 文件。
這是了解如何在 Chrome 中調試 TypeScript 的好方法,因為手動配置和設置可幫助您了解 TypeScript 調試的內部結構。讓我們準備一個開發環境來調試Chrome中的任何客戶端TypeScript文件。
首先,在你喜歡的任何目錄中創建一個新的 npm 項目,如下所示:
npm init
# --- or ---
yarn init
接下來,安裝 typescript package:
npm install typescript
# --- or ---
yarn install typescript
現在,生成 TypeScript 編譯器配置文件:
npx tsc --init
默認配置不會啟用source map生成,因此需要編輯自動生成的配置文件。取消注釋以下 tsconfig.json 行以啟用sourceMap生成:
"sourceMap": true,
添加一個 npm 腳本來生成 JavaScript,方法是修改您的 package.json :
"scripts": {
"build": "npx tsc"
},
現在,您可以使用 npm run build 或 yarn build 命令轉譯 TypeScript 文件。讓我們調試以下 TypeScript 代碼:
function sayHello(name: string): void {
let message = `Hello ${name}!`;
console.log(message);
if(name == 'TypeScript') {
console.log('.ts');
}
else if(name == 'JavaScript') {
console.log('.js');
}
}
sayHello('TypeScript');
sayHello('JavaScript');
將上述代碼添加到main.ts中。接下來,在 main.js中使用index.html :
<script src="./main.js"></script>
使用以下命令生成 main.js 和 main.js.map (我們的source map):
npm run build
# --- or ---
yarn build
在以下位置 http://localhost:3000 提供網頁內容:
npx serve
上面的代碼在端口3000中啟動一個靜態服務器(Vercel的serve)。在 Chrome 中打開網址,打開開發者工具,然后點擊來源標簽。您將看到 main.ts 如下:
圖片
嘗試添加斷點并重新加載應用。您可以像在Chrome中調試JavaScript一樣調試TypeScript:
圖片
Chrome 會自動加載source map,因為 TypeScript 編譯器會將source map文件名附加到 main.js :
//# sourceMappingURL=main.js.map
該 debugger 關鍵字也適用于 TypeScript 調試。在 console.log(message); 語句后添加debugger并重新加載應用程序:
圖片
為了試驗,請嘗試刪除source map文件 (main.js.map) 并進行調試 main.ts 。該文件 main.ts 將從源面板中消失,因為 TypeScript 調試基于source map工作。
使用這種方法,可以調試與 webpack、Rollup 或任何其他支持 TypeScript 轉譯的JavaScript捆綁器捆綁在一起的 TypeScript 代碼。您可以在 Chrome 中啟用調試 TypeScript,方法是將自動生成的源映射添加到您的網絡目錄。
前面,我們討論了 TypeScript 調試如何在 Chrome 中使用手動配置進行。但正如我們提到的,幾乎所有的前端框架/庫都提供預先實現的 TypeScript 模板,其中通常包括用于生成源映射的編譯器配置。結果是,當您在開發者模式下運行應用時,系統會在 Chrome 中自動啟用 TypeScript 調試。
現在,我們將使用Create React App的官方TypeScript模板創建一個 React 應用程序,以學習如何調試使用現代前端框架構建的 TypeScript 應用程序。運行以下命令以創建新的 TypeScript-React 應用程序:
npx create-react-app my-app --template typescript
#--- or ---
yarn create react-app my-app --template typescript
現在,將以下代碼添加到您的 App.tsx 文件中:
import React, { useState } from 'react';
import './App.css';
function App(): JSX.Element {
const [message, setMessage] = useState('');
function generateMessage(name: string): string {
let message: string = `Hello ${name}!`;
return message;
}
function handleClick(): void {
setMessage(generateMessage('TypeScript'));
}
return (
<div>
<div>{message}</div>
<button onClick={handleClick}>Say hello</button>
</div>
);
}
export default App;
上面的代碼在我們單擊“Say hello”按鈕時呈現問候消息。使用以下命令運行項目以開始調試 TypeScript:
npm start
# --- or ---
yarn start
現在,假設您需要為 App.tsx的第 8 行設置斷點。由于有多個源文件,因此您可以通過按 Ctrl+P 輕松導航到 App.tsx :
圖片
現在,設置斷點并單擊按鈕。DevTools 調試器按預期工作 TypeScript:
圖片
嘗試使用 Call Stack 部分來監視 TypeScript 函數調用:
圖片
由于source map,每個調試器功能都適用于 TypeScript 調試。React 腳本模塊進行實時TypeScript編譯,因此您可以通過檢查 Chrome 或您的終端來修復 TypeScript 編程錯誤。
讓我們向 generateMessage 函數發送一個整數,僅用于實驗目的:
function handleClick(): void {
setMessage(generateMessage(1));
}
現在,您將在Chrome和終端上看到TypeScript編譯錯誤:
圖片
所有流行的前端框架,如Angular,Vue,Svelte等,都提供TypeScript開發支持并自動生成JavaScript源映射。因此,當使用前端框架工具時,調試TypeScript變得非常容易。
如果您使用 VS Code 編寫代碼,則可以使用編輯器界面作為調試器界面,而不是 Chrome DevTools。VS Code 通過預安裝的 JavaScript 調試器擴展提供對調試 JavaScript/TypeScript 的內置支持。
啟動您的 Web 開發服務器(即 webpack 開發服務器)并使用以下 launch.json 設置啟動 Chrome:
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"name": "Chrome",
"request": "launch",
"url": "http://localhost:3000"
}
]
}
按 F5 并開始調試時,可以從編輯器設置斷點。下面是一個示例,演示如何調試App.tsx文件:
圖片
您可以使用TypeScript編寫Node.js和Deno后端項目。讓我們討論如何使用Chrome來調試它們。
與客戶端 TypeScript 開發一樣,在使用 Node.js 運行時執行項目之前,我們必須將 TypeScript 轉換為 JavaScript。客戶端 JavaScript 執行使用 Chrome 內置的 v8 引擎,因此我們可以像以前一樣直接使用 DevTools 調試器,但 Node.js 運行時使用自己的 v8 實例,因此它提供了一個內置的調試器工具,因為它不能直接使用 Chrome 的調試器JavaScript 執行環境。
使用我們在客戶端調試中遵循的相同步驟創建新的 npm 項目和一個 TypeScript 配置文件(啟用了source map)。接下來,將以下代碼添加到 main.ts :
function sayHello(name: string): void {
let message: string = `Hello ${name}!`;
console.log(message);
if(name == 'TypeScript') {
console.log('.ts');
}
else if(name == 'JavaScript') {
console.log('.js');
}
}
sayHello('TypeScript');
sayHello('JavaScript');
將以下腳本添加到文件中 package.json :
"scripts": {
"build": "npx tsc",
"debug": "node inspect main.js"
},
生成 JavaScript 文件和源映射:
npm run build
# --- or ---
yarn build
現在,使用以下命令啟動 Node.js 調試器:
npm run debug
# --- or ---
yarn debug
上面的 npm 腳本初始化內置的 Node.js 調試器實用程序,并開始通過 WebSockets 偵聽 Chrome DevTools 協議消息。您可以通過命令行使用內置的 Node.js 調試器實用程序,也可以通過 Chrome DevTools 使用 GUI 調試器。
運行上述命令后,調試器會自動將斷點設置為第一個可執行語句,如下所示:
圖片
內置調試器不支持 TypeScript 調試,因為它不理解source map— 它只是一個帶有多個命令的最小調試器。例如,可以使用以下命令在第 5 行設置斷點,并在新添加的斷點處停止代碼執行:
sb(5)
c
您可以在官方文檔中查看所有內置的調試器命令。我們不會進一步討論內置調試器,因為 Chrome 調試器是本教程的重點。
讓我們在Chrome中調試這個TypeScript項目。使用 debug npm 腳本運行項目,然后在Chrome上轉到以下網址:
chrome://inspect
現在,打開 DevTools 調試器 GUI,如下所示:
圖片
您可以通過Chrome DevTools界面調試TypeScript文件。調試器實用程序反映終端上的調試操作。查看以下預覽:
圖片
早些時候,示例React項目在代碼更改期間預轉譯了修改后的 TypeScript 代碼。您可以使用 tsc --watch 和 nodemon 或 ts-node-dev 對服務器端TypeScript項目執行相同的操作。
Deno 是一個安全的TypeScript運行時,您可以將其用作 Node.js 運行時的替代方案。在 Deno 中調試TypeScript不需要像基于 TypeScript 的 Node.js 應用程序那樣手動配置,因為 Deno 本身支持 TypeScript。
首先,請確保您的計算機上已經安裝了Deno。如果沒有,請根據官方安裝指南安裝最新的Deno運行時版本。
在我們之前創建的基于TypeScript的 Node.js 項目目錄中使用以下命令啟動Deno調試器:
deno run --inspect-brk main.ts
然后,打開 DevTools 并開始調試:
圖片
可以按 F5 并調試 Node.js 應用,而無需額外的擴展,因為內置調試器擴展支持 Node.js 調試。
對于 Deno,您可以安裝 Deno 擴展以進行自動 launch.json 配置,也可以手動使用以下 launch.json 設置:
{
"version": "0.2.0",
"configurations": [
{
"name": "Deno",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "deno",
"runtimeArgs": ["run", "--inspect-brk", "-A", "${file}"],
"attachSimplePort": 9229
}
]
}
看看我如何使用 VS Code 調試TypeScript文件:
圖片
基于 JavaScript 的跨平臺移動應用程序開發框架,允許開發人員使用獨立于平臺的單一代碼庫構建應用程序,從而使開發工作流程更加輕松。有兩種類型的基于 JavaScript 的移動框架:
使用webviews(即Android WebView)來執行JavaScript并呈現類似本機的HTML UI元素的框架,例如Ionic和Apache Cordova。
具有自己的 JavaScript 解釋器實例(即 v8 實例)的框架,用于通過 JavaScript 原生接口或橋接執行 JavaScript 和呈現本機 UI 元素,例如React Native和 NativeScript
我們可以使用 TypeScript 創建使用這兩種框架類型的應用程序,因此能夠調試基于 TypeScript 的移動應用程序代碼非常重要。Chrome 和Android WebView實現協同工作,讓開發者通過Android開發者模式和 Chrome 遠程調試功能在Chrome桌面應用上調試 TypeScript Web 應用(加載在 WebView 中)。第二種框架類型帶有內置的調試工具,允許我們使用Chrome DevTools進行調試。
讓我們仔細看看如何使用Chrome調試各種TypeScript移動應用程序。
調試基于 Android Web View 的應用
之前,我們看到了如何通過 chrome://inspect 內部頁面輸入Chrome DevTools來調試Node.js/Deno服務器端應用。同樣,我們可以檢查當前運行的Android WebView。如果 WebView 加載了 TypeScript的source map,我們可以從 Chrome 桌面應用調試 TypeScript Web 應用源。為了演示此方案,我們需要一個運行 TypeScript Web 應用的 Web 視圖。
首先,在開發模式下啟動任何基于 TypeScript 的Web應用程序。如果您使用本教程創建了以前的 TypeScript React 應用程序,您也可以使用以下命令之一啟動它:
npm start
# --- or ---
yarn start
這是我們將在Android WebView組件中加載的應用程序。我們無法引用來自手機的 localhost URL,即使計算機和手機使用相同的 WiFi 網絡也是如此。要從移動設備加載 TypeScript 應用程序,我們需要使用計算機的 IP 地址,如下所示:
圖片
使用此 URL,您將能夠在移動設備上查看您的 TypeScript 應用程序。接下來,讓我們創建一個Android WebView實例并加載此 URL。我將使用 Flutter 輕松創建原生 Web 視圖,因此請務必在開始之前安裝最新的Flutter SDK版本。
創建一個新的 Flutter 應用程序:
flutter create webview_app_demo
cd webview_app_demo
安裝 webview_flutter 插件:
flutter pub add webview_flutter
更新 android/app/build.gradle 種的最低 SDK 版本屬性:
defaultConfig {
// ----
// ---
minSdkVersion 19
// ---
}
現在,讓移動應用程序訪問互聯網并加載 HTTP 頁面 AndroidManifest.xml ,方法是將以下權限和 usesCleartextTraffic 屬性添加到:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:usesCleartextTraffic="true"
....
....
....
最后,將以下代碼添加到文件中 main.dart ,以將TypeScript Web應用加載到 Web 視圖中。請務必替換為<computer_ip>您之前記下的真實計算機 IP:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
useMaterial3: true,
),
home: const MyStatefulWidget());
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
late final WebViewController controller;
@override
void initState() {
super.initState();
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadRequest(Uri.parse('http://<computer_ip>:3000'));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView Demo'),
),
body: WebViewWidget(controller: controller));
}
}
使用以下命令運行 Flutter 應用程序:
flutter run
現在,您可以使用Chrome遠程調試功能檢查此Web視圖。首先,進入 chrome://inspect 內部頁面,找到 WebView 實例,單擊“檢查”:
圖片
要為 TypeScript React 應用設置斷點,請點擊手機上的“Say hello”按鈕,然后查看 DevTools。調試過程可以通過遠程方式進行:
圖片
在這里,我們使用 Flutter 創建了一個基于Android WebView的應用程序,但這種調試技術適用于使用原生 Android SDK(基于 Java/Kotlin)和其他框架(如 Xamarin、React Native 等)創建的 Web 視圖。
您還可以使用這種 Chrome 遠程調試方法來調試使用 Ionic、Capacitor.js 和 Apache Cordova 框架編寫的基于 TypeScript 的混合移動應用。Chrome無法檢查iOS移動設備中基于WKWebView的混合應用程序,但您可以使用Apple Safari的網絡檢查功能來執行此操作。
集成VS Code用于調試基于 Web 視圖的應用
之前,我們看到了如何使用Chrome DevTools調試界面進行基于WebView的TypeScript移動應用程序調試。如果您是 VS Code 的死忠粉絲,您可以使用此免費擴展直接在編輯器中調試 Android WebView。
繼續在您的移動設備上運行以前的 TypeScript 混合應用程序。現在,讓我們在 VS Code 上調試它。
安裝 Android WebView 調試擴展后,可以使用以下 launch.json 配置將 VS Code 調試器接口附加到移動應用中正在運行的 Android WebView 實例。請確保為application屬性使用正確的應用程序標識符:
{
"version": "0.2.0",
"configurations": [
{
"type": "android-webview",
"request": "attach",
"name": "Attach to Android WebView",
"application": "com.example.webview_app_demo"
}
]
}
將上述配置用于 TypeScript Web 應用項目后,可以按 F5,將 VS Code 內置調試器前端附加到首選WebView應用,然后開始調試,如以下預覽所示:
圖片
調試React Native應用程序
從 v0.71 開始,官方的 React Native CLI 腳手架應用程序默認使用 TypeScript,因此我們有更多的動力使用 TypeScript 來構建 React Native 應用程序。React Native 框架附帶了一個內置的調試器 Web 應用程序,該應用程序在Web worker中托管TypeScript移動應用程序代碼。因此,您可以使用 Chrome 或任何支持 Web Worker 規范的瀏覽器來調試TypeScript React Native應用程序源代碼。
現在,讓我們看看如何使用Chrome調試基于TypeScript的React Native應用程序。首先,使用以下命令創建一個新的 React Native 應用程序:
npx react-native init MyApp
cd MyApp
接下來,將以下 TypeScript 代碼片段添加到您的 App.tsx 文件中:
import React, { useState } from 'react';
import {
SafeAreaView,
StyleSheet,
View,
Button,
Text
} from 'react-native';
function App(): JSX.Element {
const [message, setMessage] = useState('');
function generateMessage(name: string): string {
let message: string = `Hello ${name}!`;
return message;
}
function handlePress(): void {
setMessage(generateMessage('TypeScript'));
}
return (
<SafeAreaView style={styles.container}>
<View>
<Text style={styles.message}>{message}</Text>
<Button onPress={handlePress} title="Say hello"/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
marginTop: 32,
padding: 24,
},
message: {
marginBottom: 32,
fontSize: 20
}
});
export default App;
接下來,使用以下命令啟動應用程序并在移動設備上運行它:
npm start
# --- or ---
yarn start
加載應用程序后,您可以從終端按 d 打開移動應用程序中的開發人員工具菜單。然后,選擇“調試”菜單項以啟用調試功能。React Native 將在您的默認瀏覽器中打開調試器 UI。如果 Chrome 不是您的默認網絡瀏覽器,您也應該能夠使用 Chrome 手動訪問以下網址:
http://localhost:8081/debugger-ui/
打開調試器 Web 應用的 DevTools 并開始調試 TypeScript 移動代碼:
圖片
也可以從VS Code調試React Native應用程序。您可以閱讀本文并了解VS Code React Native調試配置。
調試NativeScript應用
NativeScript 是一個面向 JavaScript 的跨平臺移動應用程序開發框架,使用 React Native 遵循的類似概念實現。它將 JavaScript 運行時 (v8) 嵌入到跨平臺移動應用程序中,并創建一個 JavaScript 原生接口,讓 JavaScript 訪問原生 SDK,類似于 React Native。
NativeScript 允許開發人員使用 TypeScript 就緒的 Web 框架(如 Angular、React 和 Svelte)構建應用程序,因此我們能夠調試 TypeScript NativeScript 應用程序非常重要。NativeScript 實現了Chrome DevTools協議,讓開發人員在 Chrome 中調試 NativeScript 應用。
讓我們看看如何使用Chrome調試基于TypeScript的普通NativeScript應用程序。
首先,根據官方文檔配置開發環境,使用 TypeScript 模板創建新的 NativeScript 應用,如下所示:
ns create MyApp --ts
此 TypeScript 初學者項目已經實現了一個按鈕回調,因此您無需為即將到來的調試演示修改源代碼。
在 NativeScript 調試模式下在移動設備上運行應用,如下所示:
ns debug android
# --- or ---
ns debug ios
在調試模式下加載應用后,NativeScript CLI 將打印 Chrome DevTools UI URL:
devtools://devtools/bundled/inspector.html?ws=localhost:40000
使用 Chrome 導航到此調試器網址。然后,您可以調試 TypeScript 應用源,如以下預覽所示:
圖片
若要使用 VS Code 內置調試器接口調試 NativeScript 應用,可以使用此免費擴展[https://marketplace.visualstudio.com/items?itemName=NativeScript.nativescript]。
總結
調試的主要目標是通過監視源代碼執行和手動審查代碼來識別軟件錯誤。在大多數 Web 開發調試活動中,我們可以通過讀取代碼和使用眾所周知的調試器實用程序功能來識別錯誤。但是,在某些復雜的場景中,我們必須生成許多測試用例并使用高級調試器功能。
大多數 Web 開發人員使用標準控制臺 API(即console.log)進行調試;其他人從Chrome DevTools調試器或VS Code的調試器UI開始。開始跟蹤 Bug 時,首先從上到下分析可疑代碼段。如果尚未找到 bug,則嘗試在邏輯流不復雜時記錄運行時值。如果邏輯流很復雜,從 Chrome 調試器或 VS Code 調試器界面開始可以節省您的時間。
在本教程中,我們討論了如何使用 Chrome 調試用 TypeScript 編寫的瀏覽器、Node.js、Deno 和移動應用程序。我們還討論了如何使用 VS Code 的調試器 UI。
您可以根據自己的要求和個人喜好自定義和使用這些調試技術。與前端框架的 TypeScript 模板類似,您可以使用 通過 node-typescript-boilerplate [https://github.com/jsynowiec/node-typescript-boilerplate]預配置的調試環境更快地創建基于 TypeScript 的 Node.js 項目。或者,您可以使用本教程中討論的步驟創建自己的模板。