hermes でビルドされた bundle ファイルの中身を調べる方法

最近は ReactNative をやっていっています。

ReactNative では、 AppCenter が提供している CodePush という技術を利用して JavaScript を動的に差し替えることが出来ます。これによりストア申請を迂回することが出来るのですが、その際にリリースされる JavaScript が正しいものか事前に確認したいことはありませんか?

事前にビルドしたものは CodePush という手順で提供されているものではないため、 Debug ビルド時のキャッシュファイルを読み込んで CodePush が行なわれた場合や、そもそも手順を間違えて Debug ビルドを Release 環境に向けて CodePush してしまった場合に、中身を確認することが出来ません (ストア申請の場合は GooglePlay や iTunes Connect の機能で内部テストや TestFlight ができる) 。

AppCenter 上から CodePush でリリースする前の bundle ファイルをダウンロードすることが出来ます。しかし、 hermes を使っている場合にはビルド済みのバイナリになっていてまともに読むことができません。

バイナリだとしても文字列リテラルさえ見えれば環境を特定できると思ったため、 grep や strings コマンドを利用してみたのですが、残念ながら私の環境では有用な文字列リテラルを見付けることが出来ませんでした。

f:id:s5r:20210623192708p:plain
JavaScript がこういうバイナリファイルになる

hermes を利用することは ReactNative 開発においてはデファクトスタンダードとなっており、リリース前に中身を確認したいがために hermes を利用しないという選択肢も取り辛いです。

github.com

そこで hermes でビルドしたバイナリを assembly にする方法を見付けたので共有いたします。

hermes を利用している ReactNative プロジェクトの node_modules 配下に hermes-engine というフォルダがあり、その中に hermes の実行ファイルがあります。

./node_modules/hermes-engine/osx-bin/hermes --version

この hermes コマンドを使って、ビルド済みのバイナリファイルを assembly にすることが出来ます。

./node_modules/hermes-engine/osx-bin/hermes -b --dump-bytecode "index.android.bundle" > "dump_hermes_assemble"

あくまで assembly にしかならないので JavaScript として確認できるわけではありません。ですが、文字列リテラルを確認することが出来るので環境ごとの定数 (API エンドポイントなど) を確認すれば、どの環境に向いたビルドか確認することが出来ると思います。

f:id:s5r:20210623193254p:plain
assembly で読める文字列リテラルの例