Menjalankan aplikasi Node.js di tempat baru selalu diawali pertanyaan yang sama: apakah mesinnya sudah memasang Node, versi berapa, dan apakah npm install akan berjalan lancar di sana. Single Executable Application (SEA) menghapus ketiga pertanyaannya sekaligus: aplikasi dikemas bersama salinan runtime Node.js menjadi satu berkas executable yang bisa dijalankan begitu saja — tanpa instalasi, tanpa dependencies, tanpa Node di mesin sasaran. Chapter ini membangun satu executable sungguhan dari nol lewat tiga langkah resmi, lalu menimbang kapan kemasan semacam ini layak dipakai.
Runtime yang Ikut Pindah #
Cara kerjanya lugas bila dibayangkan sebagai dua bahan. Bahan pertama: sebuah blob — berkas tunggal berisi skrip aplikasi kita hasil persiapan khusus. Bahan kedua: salinan mentah biner node itu sendiri. Alat bernama postject
kemudian menyuntikkan blob ke dalam salinan biner tersebut, ditandai sebuah sentinel fuse — deretan byte penanda yang dipakai Node untuk mengenali bahwa dirinya membawa aplikasi. Saat berkas hasilnya dijalankan, Node yang berada di dalamnya menemukan penanda, memuat blob, dan menjalankan skrip persis seperti node salam.cjs.
Bandingkan dua tetangganya: Docker dari Section Deployment dan Operations mengemas aplikasi di atas sistem operasi penuh — lebih berat namun menyediakan lingkungan lengkap; sedangkan bundler seperti esbuild menggabungkan kode menjadi satu berkas JavaScript — namun tetap menuntut Node terpasang di mesin sasaran. SEA berada di antara keduanya: satu berkas, tanpa sistem operasi tambahan, dan benar-benar berdiri sendiri.
Skrip dan Konfigurasi #
Bahan pertama kita sederhana: satu skrip yang menyapa:
const nama = process.argv[2] ?? 'dunia';
console.log(`Halo, ${nama}!`);
console.log('Berjalan sebagai satu berkas executable');Perhatikan ekstensinya: .cjs, CommonJS. Ini bukan pilihan gaya — dokumen resmi menyatakan SEA saat ini hanya mendukung skrip tertanam yang memakai sistem module CommonJS, sehingga titik masuk berbentuk .cjs adalah keharusan. Aplikasi ESM tetap bisa ikut melalui strategi bundling terlebih dahulu — diubah menjadi satu berkas CommonJS oleh esbuild atau sejenisnya — namun untuk contoh ini skrip satu berkas sudah cukup.
Bahan kedua adalah berkas konfigurasi mini yang memberi tahu Node skrip mana yang akan dikemas dan ke mana blob ditulis:
{
"main": "salam.cjs",
"output": "sea-prep.blob",
"disableExperimentalSEAWarning": true
}Tiga kuncinya: main menunjuk titik masuk, output menamai berkas blob hasil persiapan, dan disableExperimentalSEAWarning mematikan peringatan eksperimental yang biasanya tercetak saat executable berjalan — kita memakainya agar keluaran demonstrasi tetap bersih. Daftar opsi lengkap — termasuk menyematkan aset dan skrip pra-eksekusi — terdokumentasi di halaman Single Executable Applications
.
Tiga Perintah Menjadi Satu Berkas #
Sekarang seluruh rangkaiannya, persis mengikuti urutan pada dokumentasi resmi. Salinan biner node dibuat, blob disuntikkan postject, hasilnya dijalankan dua kali — dengan dan tanpa argumen — lalu berkas kerja dibersihkan agar demonstrasi bisa diulang:
node --experimental-sea-config sea-config.json
cp $(command -v node) aplikasi-satu
npx --yes postject aplikasi-satu NODE_SEA_BLOB sea-prep.blob \
--sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
./aplikasi-satu Budi
./aplikasi-satuOutput yang Dihasilkan:
Wrote single executable preparation blob to sea-prep.blob
[36mStart injection of NODE_SEA_BLOB in aplikasi-satu...[0m
[32m💉 Injection done![0m
Halo, Budi!
Berjalan sebagai satu berkas executable
Halo, dunia!
Berjalan sebagai satu berkas executableMari kita bedah tiap langkahnya:
node --experimental-sea-config sea-config.json: Node membaca konfigurasi lalu menulissea-prep.blob— konfirmasinya tercetak pada baris pertama keluaran. Proses ini memeriksa skrip, menandai titik masuknya, dan menyiapkan muatan siap suntik.cp $(command -v node) aplikasi-satu: salinan murni biner runtime, dinamai sesuka kita.command -v nodemenemukan lokasi biner di mesin ini tanpa menuliskannya secara manual.npx --yes postject ... NODE_SEA_BLOB sea-prep.blob --sentinel-fuse ...: suntikan.NODE_SEA_BLOBadalah nama resource yang dicari Node;sea-prep.blobmuatannya; sentinel fuse adalah deretan penanda baku yang membuat Node mengenali berkas hasil sebagai pembawa aplikasi. Keluaran postject berisi peringatan teknis soal penamaan section pada biner — tersaring olehgrep -v ^warningkarena tidak relevan untuk dibaca../aplikasi-satu Budidan./aplikasi-satu: eksekusi sesungguhnya. Argumen baris perintah mengalir keprocess.argvseperti biasa, nilai bawaan'dunia'bekerja saat argumen absen — dua barisHalo, ...pada keluaran adalah buktinya.rm -f aplikasi-satu sea-prep.blob: pembersihan berkas kerja, pola idempotensi yang sama dengan seluruh demonstrasi Course ini.
Yang layak digarisbawahi dari keluaran: tidak ada satu pun baris dari Node.js “yang biasa” — tidak ada peringatan, tidak ada jejak instalasi. Berkas aplikasi-satu adalah program lengkap: runtime, skrip, dan titik masuk dalam satu paket sekitar 120 MB — ukuran yang jujur, karena memang berisi seluruh mesin JavaScript di dalamnya.
Kapan Kemasan Ini Layak #
| Situasi | Layak? | Alasan |
|---|---|---|
| CLI internal yang dijalankan di mesin tanpa Node | ya | satu berkas, tanpa instalasi apa pun |
| Alat yang dibagikan ke pengguna non-teknis | ya | klik dua kali atau satu perintah, selesai |
| Peladen di cloud yang sudah mengelola Node | tidak | Docker atau process manager lebih ringan dan terkontrol |
| Aplikasi dengan banyak dependencies dinamis | hati-hati | SEA membawa satu skrip — bundling dulu, dan kompleksitas ikut pindah |
Dua batas praktis melengkapi tabel. Pertama, SEA tidak bisa menyilang platform: executable untuk Linux dibangun di Linux, untuk Windows di Windows — tidak ada kompilasi silang, sehingga pipeline rilis multi-platform membangun masing-masing di mesinnya. Kedua, fitur ini masih menyandang status eksperimental: perintahnya berawalan --experimental-sea-config, dan meski sudah dipakai luas, bentuk konfigurasinya masih bisa berubah antar versi besar. Untuk alat kecil yang dibagikan terbatas, keduanya risiko yang wajar; untuk produk yang dijual, pantau pembaruan dokumentasi
sebelum melekat terlalu jauh.
Kita telah melihat Node membenamkan aplikasi ke dalam binernya sendiri. Chapter penutup section ini melihat kebalikannya: Web API — antarmuka yang dahulu milik browser kini hidup di dalam runtime, membuat kode Node dan kode browser semakin sulit dibedakan.