WebpackerでRailsアプリケーションでエラー管理にRollbarを使用しているときに、デフォルトだとエラーが発生してもminify等がされたjsにリンクされてしまい何が起きているのか、よくわかりません。。。
そんなときにSourceMapをRollbarにアップロードするとエラー発生箇所が特定しやすくなるので、そのへんのやり方をメモしておきます📝
ちなみに今回の環境は以下です。
- rails: 6.0.3.4
- webpacker: 5.2.1
また前提として以下のドキュメントの通りBrowserJsのRollbarの設定は完了しているものとします。
docs.rollbar.com
SourceMapとは
ソースマップ は変換後のソースと元のソースを関連付けるファイルであり、ブラウザーが元のソースを再構成して、そのソースをデバッガーに提供できます。
ソースマップを使用する - 開発ツール | MDN
Webpackを利用したminified等、jsのソースコードは実際に実行されるときには元のソースコードから変換されていることが多いので、元のソースコードを生成するための情報をブラウザに提供するものといった感じと理解しました👀
SourceMapをアップロードする
SourceMapをアップロードするにはRollbarの特定のEndpointにminifiedしているjsのファイルごとにリクエストを投げる必要があります。
docs.rollbar.com
単一のjsにまとめているような運用なら以下のようなCI系の機能を使えば簡単に出来そうなのですが、Webpackerのデフォルトのようにエンドポイントごとにentryを分けるような設定の場合には、entryごとにリクエストを投げる必要があるので、結構たいへんです😓
github.com
circleci.com
そんなときに役に立つのがrollbar-sourcemap-webpack-plugin
です📦
github.com
this.getAssets(compilation)
でソースファイルとSourceMapを集めて、それぞれRollbarにUploadしてくれます📮
uploadSourceMaps(compilation) {
const assets = this.getAssets(compilation);
if (assets.length > 0) {
process.stdout.write('\n');
}
return Promise.all(
assets.map(asset => this.uploadSourceMap(compilation, asset))
);
}
rollbar-sourcemap-webpack-plugin
は以下のような形でinstallします。
$ yarn add rollbar-sourcemap-webpack-plugin
私は、以下ような感じにconfig/webpack/production.js
を修正しました。
各設定値の詳細はREADMEを参照してください📝
process.env.NODE_ENV = process.env.NODE_ENV || "production";
const RollbarSourceMapPlugin = require("rollbar-sourcemap-webpack-plugin");
const token = process.env.ROLLBAR_POST_SERVER_ITEM_ACCESS_TOKEN;
const codeVersion = process.env.SOURCE_VERSION;
const publicPath = process.env.PUBLIC_PATH + "/packs";
const RollbarSourceMapPluginConfig = require("./plugins/rollbarSourceMapConfig");
const environment = require("./environment");
RollbarSourceMapPluginConfig = new RollbarSourceMapPlugin({
accessToken: token,
version: codeVersion,
publicPath: publicPath,
ignoreErrors: true,
});
environment.config.merge({
devtool: "hidden-source-map",
});
environment.plugins.prepend("RollbarSourceMapPlugin", RollbarSourceMapPluginConfig);
process.env.SOURCE_VERSION
にはdeploy時の最新のcommit hashを SourceMapをuploadするwebpackのbuild前に設定しておく必要があります。
CI系のサービスを利用してdeployしている場合には、すでに環境変数に入っているものもあるようです👀
CircleCI
CIRCLE_SHA1
The SHA1 hash of the last commit of the current build.
https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables
GitHub
GITHUB_SHA
The commit SHA that triggered the workflow. For example, ffac537e6cbbf934b08745a378932722df287a53.
https://docs.github.com/en/free-pro-team@latest/actions/reference/environment-variables#default-environment-variables
Heroku
SOURCE_VERSION
For git-push builds, this is the git commit SHA-1 of the source being built.
https://devcenter.heroku.com/changelog-items/630
これで本番のWebpackのビルド時にSourceMapが送信されるようになりました🎉
RollbarにアップロードしたSourMapは、Project > Settings > Source Maps
で見ることが出来ます。
UploadしたSourMapを利用するように既存のRollbarの設定を修正
SourceMapがアップロードされるようになったら、次はError通知時にSourceMapが利用されるように設定を変更していきます⚙
変更した設定が以下の通りです、client
部分が追加した設定になります。
詳細は以下のURLから公式ドキュメントを確認してください📝
https://docs.rollbar.com/docs/source-maps#2-configure-the-rollbarjs-sdk-to-support-source-maps
Rollbarはpayload.client.code_version
の値とアップロードされたSourceMapのversion
で紐付けているようです🤝
const token = process.env.ROLLBAR_POST_CLIENT_ITEM_ACCESS_TOKEN;
const railsEnv = process.env.RAILS_ENV;
const codeVersion = process.env.SOURCE_VERSION;
const rollbarParamsValidation = () => !(railsEnv === "test") && token;
if (rollbarParamsValidation()) {
let _rollbarConfig = {
accessToken: token,
captureUncaught: true,
captureUnhandledRejections: true,
payload: {
environment: railsEnv,
client: {
javascript: {
source_map_enabled: true,
code_version: codeVersion,
guess_uncaught_frames: true,
},
},
},
};
これで以下のような感じでSourceMapを活用して、minified前の実際にエラーの発生したfileの行数で見ることが出来るようになりました🙌
参考
engineer.crowdworks.jp
qiita.com