本番環境での JavaScript エラーのデバッグは困難です。コードはミニファイされており、各ユーザーのデバイス、ブラウザ、ネットワーク条件はそれぞれ異なるためです。ほとんどのブラウザ監視アプローチは PerformanceTiming オブジェクトに依存していますが、これはページの完全な読み込み時間のみをキャプチャし、静的リソースの読み込み時間を除外するため、パフォーマンスボトルネックの特定が困難になります。Application Real-Time Monitoring Service (ARMS) のブラウザ監視は、ソースマップのサポートとユーザー行動のバックトラッキングを組み合わせることで、ミニファイされたスタックトレースを元のソースコードにマッピングし、エラーをトリガーしたユーザーの正確な操作を再生できます。
前提条件
開始する前に、以下が満たされていることを確認してください。
ソースマップの仕組み
ソースマップは、ミニファイされたコード内の位置を、元のソースコード内の対応する位置にマッピングする JSON ファイルです。VLQ エンコーディングを使用して位置データをコンパクトに保存します。ソースマップを使用することで、ブラウザ監視は「1 行目、79585 列目」で発生したエラーを、ソースコード内の正確なファイル、行、列に変換します。
診断ワークフロー
以下のワークフローでは、エラー傾向の特定、ミニファイされたスタックトレースのソースコードへのマッピング、そしてエラーをトリガーしたユーザー操作の再生という、エンドツーエンドのプロセスを順を追って説明します。
ステップ 1:エラー概要の表示
ARMS コンソールにログインします。
左側のナビゲーションウィンドウで、 を選択します。
[ブラウザ監視] ページで、上部のナビゲーションバーからリージョンを選択し、管理したいアプリケーションの名前をクリックします。
左側のナビゲーションウィンドウで [JS エラー診断] をクリックします。

このページでは、以下の情報を確認できます。
[エラー概要] セクションには、エラーの総数、JS エラー率、影響を受けたユーザー数とその割合が表示されます。
曲線グラフには、エラーの傾向が時系列で表示されます。
[頻発するエラー] タブには、発生頻度の高いエラーが一覧表示されます。
[エラー率によるページランキング] タブと [エラービュー] タブには、ページごとのエラーのディストリビューションが表示されます。
ステップ 2:特定エラーの詳細分析
エントリーポイントは 2 つあります。
[頻発するエラー] タブで、対象のエラーの横にある [診断] をクリックします。
曲線グラフで、特定の時間のデータポイントをクリックして [例外インサイト] ダイアログボックスを開きます。
以下の例では、曲線グラフを使用する方法を説明します。
曲線グラフで、エラー率が急上昇しているポイントを特定します。ポインターが手のアイコンに変わるまで変曲点にカーソルを合わせ、クリックします。[例外インサイト] ダイアログボックスが表示されます。詳細については、「例外インサイトの表示」をご参照ください。

[頻発するエラー トップ 5] タブをクリックし、エラーを選択して [操作] 列の [診断] をクリックします。[エラー詳細] タブが表示されます。
ステップ 3:エラー詳細の確認
エラー詳細ページでは、以下のコンテキスト情報が提供されます。
| フィールド | 説明 |
|---|---|
| 初回発生日時 | エラーが最初に記録された日時 |
| 初回発生時のバージョン | エラーが最初に発生したときのアプリケーションのバージョン (任意) |
| エラー名とタイプ | JavaScript エラーの名前と分類 |
| 発生日時 | このエラーインスタンスが発生した日時 |
| デバイス、OS、ブラウザ | エラーが発生したクライアント環境 |
| IP アドレス、リージョン | ユーザーのネットワーク上の場所 |
| 接続タイプ | ネットワーク接続 (Wi-Fi、4G など) |
| エラー URL | エラーがトリガーされたページの URL |
| アプリケーションのバージョン | デプロイされているアプリケーションのバージョン |
| ファイル、行、列 | ミニファイされたファイル内の位置 |
例:以下のスクリーンショットは、リアルタイムダッシュボードのマップモジュールで発生したエラーを示しています。このモジュールは更新中に無効なデータを報告し、スタックトレースはミニファイされたバンドルの 1 行目、79585 列目を指しています。

「1 行目、79585 列目」という情報だけでは、本番コードがミニファイされているため、具体的なアクションにつながりません。次のステップでは、この位置をソースコードにマッピングします。
ステップ 4:エラーのソースコードへのマッピング
スタックトレース内の行番号と列番号は、ソースファイルではなく、ミニファイされたコードを指しています。ソースマップを適用して、元のエラーの場所を解決します。
[スタック情報] セクションで、スタックフレームの左側にある
アイコンをクリックして展開し、[ソースマップの選択] をクリックします。[ソースマップファイル] ダイアログボックスで、既存のソースマップファイルを選択するか、新しいファイルをアップロードし、[OK] をクリックします。
説明一度に最大 5 つのファイルをアップロードできます。

ソースマップを適用すると、ブラウザ監視は [ソースコード] セクションで元のエラー箇所を赤色でハイライト表示し、エラーが発生した正確なファイルと行を示します。エラースタック内の各フレームにソースマップを適用して、完全な呼び出しチェーンをトレースします。
ステップ 5:ユーザー行動のバックトラッキングによるエラーの再現
ソースマップのマッピングによって、エラーが *どこで* 発生したかはわかりますが、必ずしも *なぜ* 発生したかまではわかりません。マップモジュールの例では、ソースコードのマッピングにより、コンポーネント作成中に無効なデータがエラーを引き起こしたことが示されています。しかし、ソースコードにはすでにこのデータに対する null チェックとフォールトトレランスが含まれています。なぜ無効なデータが出現したのかを理解するには、エラー発生直前に何が起こったかを確認する必要があります。
ブラウザ監視は、ユーザーの行動を時系列のイベントノードのトレースとして記録します。
ページの読み込み
ルート変更
ページクリック
API リクエスト
コンソール出力
このトレースを確認することで、エラーに至った一連の操作を再生できます。
例:以下のユーザー行動トレースは、エラーの直前に API リクエストが発生したことを示しています。この API 呼び出しはマップモジュールのリアルタイム更新をリクエストしましたが、レスポンスは有効なマップデータではなく ConsoleNeedLogin を返しました。これは、ユーザーがページからログオフしていたことを示しており、これが無効なデータの根本原因です。

ソースマップの生成
診断ワークフローのステップ 4 にはソースマップが必要です。ビルドツールでソースマップを生成し、ARMS コンソールにアップロードします。
ソースマップファイルをアップロードするには、[ブラウザ監視] ページでアプリケーションを見つけ、[操作] 列の [その他] > [設定] を選択します。設定ページで、[詳細設定] タブをクリックします。
Webpack
webpack.config.js で、devtool プロパティを "source-map" に設定します。Webpack は、さまざまな種類のソースマップに対応する 13 の devtool 値をサポートしています。"source-map" は、完全で独立した .map ファイルを生成するため、本番環境のエラー診断に推奨されます。
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
devtool: "source-map"
};Gulp
gulp-sourcemaps パッケージを使用します。
var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(sourcemaps.write('../sourcemaps'))
.pipe(gulp.dest('dist'));
});Grunt
grunt-contrib-uglify のみを使用する場合:
grunt.initConfig({
uglify: {
options: {
sourceMap: true
}
}
});grunt-usemin を使用する場合 (grunt-contrib-concat と grunt-contrib-uglify を呼び出します):
grunt.initConfig({
concat: {
options: {
sourceMap: true
}
},
uglify: {
options: {
sourceMap: true,
sourceMapIn: function(uglifySource) {
return uglifySource + '.map';
},
}
}
});grunt-jsmin-sourcemap を使用する場合:
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-jsmin-sourcemap');
grunt.initConfig({
'jsmin-sourcemap': {
all: {
src: ['scripts/script.js'],
dest: 'scripts/script.jsmin-grunt.js',
destMap: 'scripts/script.jsmin-grunt.js.map'
}
}
});
grunt.registerTask('default', 'jsmin-sourcemap');
};Angular CLI
ng build --prod --source-map --vendor-source-mapUglifyJS2
UglifyJS2 は CLI ツールです。その他のオプションについては、「CLI source map options」をご参照ください。
uglifyjs app.js -o app.min.js --source-map app.min.js.mapSystemJS
SystemJS Builder を使用します。
builder.bundle('app.js', 'app-outfile.js', {
minify: true,
sourceMaps: true
});