在生产环境中调试 Angular 应用程序而不显示源映射
當我們的 Angular 應用程序部署到生產環境時,我們經常會遇到與我們在開發過程中編輯的不同的代碼。我們的代碼在構建過程中會以各種方式進行修改和優化。
TypeScript 被 transpiled, minified 和 uglifed。生成的 JavaScript 包盡可能小,并且能夠在瀏覽器中運行。
所有這些概念都很棒,因為它們提高了我們應用程序的性能。但是,這也給生產系統的故障排查帶來了一些困難。
SourceMap 是一個解決方案。
從本質上講,源映射是一個 JSON 文件,其中包含將轉譯后的代碼映射回原始源所需的所有信息。很酷!
從技術上講,源映射只是一個包含以下字段的 JSON 文件:
- version : 表示源映射規范版本
- file : 此源映射所屬的轉譯文件的名稱
- sourceRoot : basePath — 源相對于這里
- sources : 原始源文件的路徑(例如 TypeScript 文件)
- sourcesContent : 可選屬性,可以包含您的整個源代碼。當源代碼在此屬性中內聯時,無需托管源代碼即可檢索。
- names:代碼中找到的方法或變量名稱
- mappings:這是整個魔術發生的地方。從技術上講,映射屬性是一個非常大的字符串,其中包含Base64 VLQ(可變長度數量)值。這些值有助于找到源文件中的原始位置。
如何檢索源映射?
要檢索源映射,我們需要告訴瀏覽器它們所在的位置。我們可以通過添加以下行在文件末尾指定
sourceMappingURL:
例子:
//# sourceMappingURL=pathToSourceMaps有了這些信息,瀏覽器就可以下載源映射文件并解釋其內容以創建映射。
注意:瀏覽器僅在開發者工具打開時下載源地圖。對于普通用戶,沒有性能影響。
除了在文件末尾添加注釋之外,您還可以SourceMap在獲取 minified 的 JavaScript 文件的響應中將路徑作為HTTP 標頭的值發送。
SourceMap: pathToSourceMap
第二種可能性使您可以在服務器端切換源映射,而無需更改 minified 之后的 JavaScript 文件。
開發和生產期間的源映射
開發和生產版本不同。
在開發過程中,擁有完整的源圖是有意義的,因為我們專注于工具、開發經驗或 hot module 替換。
另一方面,在生產中,我們專注于性能——使用 small bundles 快速初始加載。
應該在生產過程中啟用源映射嗎?
這個問題的答案很大程度上取決于您的項目。如果您正在從事開源項目,那么肯定是這樣。
但是我們大多數人在日常工作中并不從事開源項目。在企業項目中,您有充分的理由不想公開您的源代碼。
- 我們不想暴露易于閱讀的應用程序代碼給外界。
- 更快的構建
- 不想暴露 source map 的提供源頭
下面介紹如何在生產環境啟用 Source Map,但是不暴露其來源。
Angular CLI 允許我們配置是否需要源映射。然后它將這些信息傳遞給底層的 Webpack。
要探索 Angular 中的源映射,讓我們從一個由 Angular CLI 生成的全新 Angular 項目開始。
ng new sourceMapInspector
Component 實現很簡單:
public changeTitle(): void {this.title = 'awesome app'; }模板里的消費代碼:
<button (click)="changeTitle()">Change title</button>使用 ng serve 命令。
源映射幫助我們在開發工具中顯示我們的原始源。
我們現在可以打開app.component.ts并在changeTitle函數內放置一個斷點。通過單擊“更改標題”按鈕,我們然后點擊了我們的斷點。
如果我們查看 main.js 文件的最后一行,我們可以看到瀏覽器獲取源映射的位置。
//# sourceMappingURL=main.js.map
這對開發非常有用。我們有完整的源映射,可以輕松調試我們的代碼。
讓我們檢查一下 Angular 中的生產構建在源映射方面的行為。我們可以使用以下命令運行 prod 構建。
ng build --prod
該 dist 文件夾現在包含沒有 source map 的捆綁文件。讓我們切換到該dist文件夾并在 HTTP 服務器上運行該應用程序,以了解它在生產中的外觀。
可以使用 npm 模塊http-server作為本地 Web 服務器。
http-server 是一個簡單的、零配置的命令行 http 服務器,可以安裝 npm i -g http-server
因此,讓我們運行我們的生產版本并打開開發工具來調試我們的功能。
在生產模式下,沒有來源,也沒有可供點擊的 Webpack 菜單項。
我們在哪里設置斷點?我們需要手動在轉換后的 JavaScript 文件中找到我們的函數,這很麻煩。
我們在第 7841 行設置了斷點,即使我們的應用程序只包含幾行代碼。
將源映射添加到 Angular 生產構建
angular.json 文件包含一個 architect 屬性,允許我們指定是否要為我們的生產構建使用源映射。
要啟用源映射,我們需要將 sourceMap 屬性更改為 true或通過傳遞 --source-map 給我們的 ng build 命令來覆蓋它。
這種方法會將源映射添加到我們的生產構建中并在生產中獲取它們,以便每個人都可以訪問我們的源。
對源映射的細粒度控制?
Angular 7.2 為我們提供了對源映射的更細粒度控制。該 sourceMap 屬性現在接受具有以下屬性的對象,而不是一個簡單的 boolean 值。
"sourceMap": {"hidden": true,"scripts": true,"styles": true }scripts 和 styles 屬性允許我們只為 scripts 或者 styles 生成 source map.
而 hidden 屬性,顧名思義,可以生成隱藏的 source map.
源映射本身對于常規構建或帶有隱藏源映射的構建沒有區別。只有生成的包在一行中有所不同——webpack 添加的用于檢索源映射的注釋。
讓我們看一下使用源映射生成的包。
注意最后的一行注釋語句。當我們打開開發工具時,瀏覽器將解釋此注釋并嘗試獲取源映射。現在讓我們看一下使用隱藏源映射生成的包。
我們可以看到文件末尾沒有添加注釋。因此瀏覽器不會嘗試獲取源映射。如果有一種方法可以使用一些簡單的 npm 腳本來處理生產環境中的源映射呢?
上傳本地源地圖
我們總是可以在本地重新生成源映射并在以后上傳它們。
"sourceMap": { "hidden": true, "scripts": true, "styles": true }接下來,我們需要創建一個 postbuild 腳本,該腳本僅刪除我們剛剛生成的源映射。
"postbuild": "rm dist/sourceMapInspector/*.map"該 postbuild 腳本是必需的,否則我們將提供源映射。由于缺少 comment,它們不會被解析。但他們仍然被提供。
為了在生產中進行調試,我們手動上傳源映射。但是我們從哪里得到它們呢?我們剛剛刪除了它們。
答案很簡單,我們需要重新生成它們。
我們現在可以使用 Chrome 開發工具從本地文件系統上傳源映射。因此,打開開發工具并右鍵單擊您的main[hash].js. 現在輸入上面腳本生成的源映射的路徑。
必須按以下方式添加路徑:file///pathToFile.
更多Jerry的原創文章,盡在:“汪子熙”:
總結
以上是生活随笔為你收集整理的在生产环境中调试 Angular 应用程序而不显示源映射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 论文阅读:Siam-RPN
- 下一篇: JLINK固件,JLINK驱动和JLIN