当我们的应用程序部署到生产环境时,我们发现它与我们在开发环境时的代码不同。我们的代码在构建过程中会以各种方式进行修改和优化。
TypeScript 被转译、压缩。生成的 JavaScript 包尽可能小并且能够在浏览器中正常运行。
所有这些步骤都很有效率,它们提高了我们应用程序在生产环境下的性能。但是当我们需要在生产环境下调试代码时它对我们产生了很大的障碍。
但是有一个解决方案:Source Map
配合Chrome 开发工具可以为我们提供一个debug线上项目的功能
Source Map简介:
从技术上讲,source maps只是一个包含以下字段的 JSON 文件:
- version: 表示source map版本
- file: source map所属的转译后文件的名称
- sourceRoot: basePath — 源相对于这里
- sources: 原始源文件的路径(例如 TypeScript 文件)
- sourcesContent: 可选属性,可以包含整个源代码。
- names: 在代码中找到的方法或变量名称
- mappings: 这是整个功能起作用的关键。从技术上讲, mappings 属性是一个非常大的字符串,其中包含 Base64 VLQ(可变长度数量)值。这些值有助于找到源文件中的原始位置。
项目环境:
使用 @angular/cli 12.0.3 所搭建的标准 Angular 项目
{"name": "sourcemap","version": "0.0.0","scripts": {"ng": "ng","start": "ng serve","build": "ng build","watch": "ng build --watch --configuration development","test": "ng test"},"private": true,"dependencies": {"@angular/animations": "~12.0.3","@angular/common": "~12.0.3","@angular/compiler": "~12.0.3","@angular/core": "~12.0.3","@angular/forms": "~12.0.3","@angular/platform-browser": "~12.0.3","@angular/platform-browser-dynamic": "~12.0.3","@angular/router": "~12.0.3","rxjs": "~6.6.0","tslib": "^2.1.0","zone.js": "~0.11.4"},"devDependencies": {"@angular-devkit/build-angular": "~12.0.3","@angular/cli": "~12.0.3","@angular/compiler-cli": "~12.0.3","@types/jasmine": "~3.6.0","@types/node": "^12.11.1","jasmine-core": "~3.7.0","karma": "~6.3.0","karma-chrome-launcher": "~3.1.0","karma-coverage": "~2.0.3","karma-jasmine": "~4.0.0","karma-jasmine-html-reporter": "^1.5.0","typescript": "~4.2.3"}
}
debug步骤:
使用Source Map进行调试还需要一些步骤,一般情况下项目的 source maps文件是不会在生产环境下被生成的,以防止源代码泄露。
angular.json 文件包含一个sourceMap属性,允许我们指定是否要在生产构建中使用它
"architect": {"build": {…"configurations": {"production": {…"sourceMap": true}},"defaultConfiguration": "production"}}
或者添加下列命令行进行覆盖 (Angular 7.2版本以下的项目需要使用命令行方式)
--source-map=true
现在如我们所见,在build执行完后,dist中出现了js.map文件
注意:确保你要调试的本地代码与线上代码相同
现在我们可以使用 Chrome 开发工具从本地文件系统上传js.map。
打开开发工具并右键单击。找到需要调试的js以及与其相对的 js.map文件,记录路径。现在输入js.map文件路径。
注意:必须通过以下方式添加路径: file:///pathToFile
我们也可以使用浏览器打开js.map,这样浏览器上方的地址栏就自动生成了我们需要的path
如果左侧出现了webpack://,则表示source map已经成功导入,可以调试对应的源码