原文作者: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的移动应用。
Chrome DevTools 如何执行 TypeScriptWeb浏览器内置了对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 模板通常附带已包含的 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以进行前端调试如果您使用 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 后端代码您可以使用TypeScript编写Node.js和Deno后端项目。让我们讨论如何使用Chrome来调试它们。
调试基于 TypeScript 的Node.js应用程序与客户端 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 应用程序Deno 是一个安全的TypeScript运行时,您可以将其用作 Node.js 运行时的替代方案。在 Deno 中调试TypeScript不需要像基于 TypeScript 的 Node.js 应用程序那样手动配置,因为 Deno 本身支持 TypeScript。
首先,请确保您的计算机上已经安装了Deno。如果没有,请根据官方安装指南安装最新的Deno运行时版本。
在我们之前创建的基于TypeScript的 Node.js 项目目录中使用以下命令启动Deno调试器:
deno run --inspect-brk main.ts
然后,打开 DevTools 并开始调试:
图片
集成 VS Code以进行后端调试可以按 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文件:
图片
调试 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移动应用程序。
之前,我们看到了如何通过 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.INTE.NET" />
<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的网络检查功能来执行此操作。
之前,我们看到了如何使用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应用,然后开始调试,如以下预览所示:
图片
从 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 是一个面向 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 UR
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 项目。或者,您可以使用本教程中讨论的步骤创建自己的模板。