Belajar Hermes JS Engine - Hermes Runtime dan Build Pipeline
Episode 4 of 23

Belajar Hermes JS Engine - Hermes Runtime dan Build Pipeline

Membedah pipeline build Hermes di React Native: bagaimana Metro bundler mengubah source menjadi bundle, peran HermesBytecodePlugin yang mengkompilasi bundle menjadi bytecode HBC, opsi bundle-command dan hermesc untuk kendali penuh, hingga produksi artifact output, source maps, dan debugging symbol.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Pendahuluan

Di episode 3 Hermes sudah aktif di project kalian. Sekarang kita lihat apa yang sebenarnya terjadi saat kalian menjalankan perintah build. Di sanalah Hermes bertemu Metro bundler — dan di situlah bytecode lahir.

Episode 4 membedah pipeline build: integrasi Metro dengan HermesBytecodePlugin, opsi bundle-command dan hermesc, serta cara membaca artifact output, source maps, dan debugging symbol.

Perjalanan dari Source Menjadi Bytecode

Sebuah bundle React Native melewati dua tahap. Tahap pertama: Metro membaca seluruh modul JavaScript dan menggabungkannya menjadi satu file bundle. Tahap kedua: hermesc mengompilasi bundle itu menjadi bytecode HBC.

Pipeline build Hermes di React Native
source modules --> Metro bundler --> bundle.js
                                        |
                                        v
                                  HermesBytecodePlugin
                                        |
                                        v
                                  bundle.hbc (+ .map)

HermesBytecodePlugin adalah penghubung keduanya — ia memanggil hermesc di akhir proses bundling. Di React Native modern, plugin ini terpasang otomatis oleh Metro config bawaan.

Integrasi dengan Metro Bundler

Metro memakai file metro.config.js untuk mengatur transform dan bundling. Di React Native dengan Hermes, konfigurasi default sudah menyertakan HermesBytecodePlugin lewat bantuan helper getDefaultConfig. Contoh konfigurasi minimum:

JSmetro.config.js
const { getDefaultConfig } = require("@react-native/metro-config");
 
const config = getDefaultConfig(__dirname);
 
module.exports = config;

Di balik layar, helper ini mendaftarkan HermesBytecodePlugin sebagai bundle plugin — sebuah hook yang dijalankan Metro setelah bundle JavaScript dihasilkan. Hasil akhirnya adalah file bytecode yang dimuat React Native di runtime.

Peran HermesBytecodePlugin

Secara detail, plugin ini melakukan dua hal:

  1. Mengompilasi bundle menjadi bytecode lewat hermesc dengan flag yang sudah dikalibrasi untuk React Native.
  2. Mengalihkan output sehingga artefak yang dipakai app adalah .hbc, bukan .js.

Jika kalian ingin melihat plugin ini secara eksplisit di konfigurasi, gunakan HermesBytecodePlugin langsung dari package React Native:

JSmetro.config.js dengan plugin eksplisit
const { getDefaultConfig } = require("@react-native/metro-config");
const HermesBytecodePlugin = require("react-native/HermesBytecodePlugin");
 
const config = getDefaultConfig(__dirname);
 
config.transformer.bundlePlugins = [HermesBytecodePlugin];
 
module.exports = config;

Plugin ini membaca konfigurasi seperti opsi compiler yang disetel di file package.json React Native. Untuk kendali penuh atas compiler, kalian bisa menimpa lewat opsi yang kita bahas berikutnya.

Opsi Build: bundle-command

Cara paling fleksibel mengendalikan pipeline adalah dengan bundle-command — opsi yang memberitahu React Native untuk memanggil command custom alih-alih default. Ini berguna untuk build pipeline di CI atau eksperimen bytecode. Contoh penggunaan:

Bundle dengan command custom
npx react-native bundle \
  --platform android \
  --dev false \
  --entry-file index.js \
  --bundle-output dist/index.android.bundle

Command ini tetap menghasilkan bundle JavaScript biasa; kompilasi bytecode tetap dilakukan oleh plugin bawaan. bundle-command berguna saat kalian ingin menambahkan langkah post-processing setelah Metro selesai — misalnya mengukur ukuran bundle atau menandatanganinya.

Opsi Build: hermesc Secara Langsung

Untuk eksperimen, panggil hermesc secara langsung (binary dari episode 3) tanpa Metro sama sekali:

Kompilasi bundle menjadi bytecode
build/bin/hermesc \
  -O \
  -emit-binary \
  -output-source-map \
  -bundle \
  -w=-0 \
  index.js \
  -out dist/index.android.bundle.hbc

Penjelasan flag:

  • -emit-binary — menghasilkan file bytecode .hbc.
  • -bundle — menandai bahwa input adalah bundle Metro, bukan modul tunggal.
  • -output-source-map — menghasilkan source map untuk debugging.
  • -w=-0 — menonaktifkan peringatan error yang sebenarnya hanya warning.
  • -O — mengaktifkan optimizer; detail lengkap di episode 5.

Artifact Output

Setelah build, periksa apa saja yang dihasilkan di folder android/app/build/generated/assets (Android) atau di direktori output bundle:

Struktur artifact build
dist/
  index.android.bundle      <- bundle JS (Metro)
  index.android.bundle.hbc  <- bytecode Hermes (hasil hermesc)
  index.android.bundle.map  <- source map

Berkas .hbc inilah yang akhirnya di-embedd ke APK. Ukurannya biasanya lebih kecil dari bundle JS karena bytecode lebih padat — dan ini yang akan kita optimisasi di episode 5.

Source Maps

Source map menghubungkan bytecode dengan kode sumber asli, sehingga stack trace yang dilaporkan app bisa dipetakan kembali ke file dan baris yang sebenarnya. Hermes menghasilkan source map lewat flag -output-source-map di atas. Di React Native, source map diproduksi otomatis saat build release:

Build release sekaligus source map
npx react-native run-android --mode release

Source map release dihasilkan di folder dist project. Tanpa source map, error di production hanya menampilkan posisi bytecode yang tidak terbaca manusia — masalah yang kita tuntaskan di episode 10.

Warning

Source map memuat pemetaan ke source asli. Untuk aplikasi production, pastikan source map tidak ikut ter-embedd ke APK — simpan di backend symbol server dan jaga agar tidak bocor, karena bisa membuka source code kalian.

Debugging Symbol

Selain source map, Hermes menyediakan debugging symbol untuk tool seperti Android Studio. Saat build release, React Native menghasilkan file map dengan hermesc yang memuat informasi symbol untuk stack trace native. Untuk mengunduh symbol saat crash, SDK tools biasanya mencari file .symbol yang dihasilkan dari -output-source-map bersama -emit-binary. Inilah yang dipakai layanan crash reporting untuk menerjemahkan crash Hermes ke lokasi asli di source.

Penutup

Pipeline build Hermes sudah terpetakan. Inilah yang wajib kalian bawa pulang:

  • Metro menggabungkan modul menjadi satu bundle, lalu HermesBytecodePlugin mengkompilasinya menjadi .hbc.
  • HermesBytecodePlugin terpasang otomatis di React Native modern; bisa juga dipasang eksplisit di metro.config.js.
  • bundle-command dan pemanggilan hermesc langsung memberi kendali penuh atas pipeline.
  • Artifact utama build adalah bundle JS, bytecode HBC, dan source map.
  • Source map dan debugging symbol wajib dikelola dengan hati-hati di production.

Selanjutnya, di episode 5 kita mengoptimisasi: prepackaging bytecode, flag optimizer -O, dan bagaimana ukuran bundle memengaruhi cold start. Sampai jumpa!

Belajar Hermes JS Engine - Hermes Runtime dan Build Pipeline | Belajar Hermes JS Engine