Rails Stimulus dan Importmaps 2026: JavaScript Modern Tanpa Build Tools
Stimulus dan Importmaps di Rails 8.1 memungkinkan penulisan JavaScript modern tanpa bundler. Tutorial ini membahas controller, action, target, dan package npm.

Rails Stimulus dan Importmaps menghilangkan kebutuhan webpack, esbuild, atau langkah build JavaScript apapun. Rails 8.1 hadir dengan importmap-rails dan stimulus-rails secara default, memungkinkan pengembang menambahkan perilaku interaktif ke HTML yang di-render server tanpa mengelola node_modules atau konfigurasi bundler yang kompleks.
Importmaps menggunakan ES modules browser native. Menjalankan bin/importmap pin chart.js mengambil package dari CDN dan mendaftarkannya di config/importmap.rb. Tidak perlu npm install, tidak ada kompilasi, tidak perlu menunggu.
Bagaimana Importmaps Menggantikan Bundler Tradisional
Importmaps memanfaatkan dukungan ES module native browser untuk memuat file JavaScript secara langsung. Alih-alih menggabungkan semua dependency menjadi satu file, browser mengambil setiap module sesuai kebutuhan. JSPM CDN menyelesaikan package npm ke URL yang kompatibel dengan browser.
File config/importmap.rb berfungsi sebagai manifest:
# config/importmap.rb
pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"Konfigurasi ini memberi tahu browser di mana menemukan setiap module. Direktif pin_all_from secara otomatis mendaftarkan semua controller Stimulus dari direktori yang ditentukan.
Browser yang mendukung importmaps termasuk Chrome 89+, Edge 89+, Firefox 108+, dan Safari 16.4+. Untuk browser lama, Rails menyuntikkan polyfill es-module-shims secara otomatis.
Membuat Controller Stimulus untuk UI Interaktif
Controller Stimulus menghubungkan perilaku JavaScript ke elemen HTML melalui atribut data. Setiap controller adalah class yang meng-extend Controller dari @hotwired/stimulus.
import { Controller } from "@hotwired/stimulus"
// Mengelola visibilitas dropdown dengan dukungan keyboard
export default class extends Controller {
static targets = ["menu", "button"]
static values = { open: Boolean }
// Toggle dropdown saat tombol diklik
toggle() {
this.openValue = !this.openValue
}
// Tutup saat mengklik di luar dropdown
clickOutside(event) {
if (!this.element.contains(event.target)) {
this.openValue = false
}
}
// Dipanggil otomatis saat openValue berubah
openValueChanged() {
this.menuTarget.classList.toggle("hidden", !this.openValue)
this.buttonTarget.setAttribute("aria-expanded", this.openValue)
}
// Connect lifecycle callback
connect() {
document.addEventListener("click", this.clickOutside.bind(this))
}
// Disconnect lifecycle callback - pembersihan
disconnect() {
document.removeEventListener("click", this.clickOutside.bind(this))
}
}HTML yang sesuai menggunakan atribut data untuk menghubungkan controller:
<%# app/views/components/_dropdown.html.erb %>
<div data-controller="dropdown" data-dropdown-open-value="false">
<button data-dropdown-target="button"
data-action="click->dropdown#toggle"
aria-haspopup="true">
Opsi
</button>
<ul data-dropdown-target="menu" class="hidden">
<li>Edit</li>
<li>Hapus</li>
</ul>
</div>Stimulus 3.2.2 memperkenalkan Outlets API dan keyboard event modifiers. Fitur-fitur ini mengurangi boilerplate saat mengkoordinasikan antar controller atau memfilter keystroke.
Menambahkan Package npm dengan Importmaps
Menambahkan library JavaScript hanya memerlukan satu perintah:
# Pin chart.js dari JSPM CDN
bin/importmap pin chart.jsIni menambahkan entri ke config/importmap.rb:
# config/importmap.rb
pin "chart.js", to: "https://ga.jspm.io/npm:chart.js@4.4.1/dist/chart.js"Library kemudian dapat diimpor di controller manapun:
import { Controller } from "@hotwired/stimulus"
import { Chart, registerables } from "chart.js"
Chart.register(...registerables)
export default class extends Controller {
static targets = ["canvas"]
static values = {
type: { type: String, default: "bar" },
data: Object
}
connect() {
this.chart = new Chart(this.canvasTarget, {
type: this.typeValue,
data: this.dataValue,
options: { responsive: true }
})
}
disconnect() {
this.chart.destroy()
}
}Dokumentasi importmap-rails membahas vendoring package secara lokal untuk pengembangan offline atau ketika akses CDN dibatasi.
Beberapa package npm memiliki dependency tree yang dalam. Gunakan bin/importmap pin package-name --download untuk vendor semua dependency secara lokal. Pendekatan ini lebih baik untuk package dengan banyak transitive imports.
Action Parameters dan Event Modifiers
Stimulus 3.x memperkenalkan action parameters, memungkinkan nilai diteruskan langsung dari HTML ke method controller:
<%# Meneruskan parameter via atribut data %>
<button data-controller="item"
data-action="click->item#delete"
data-item-id-param="42"
data-item-confirm-param="true">
Hapus
</button>import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
delete(event) {
const { id, confirm } = event.params
if (confirm && !window.confirm("Hapus item ini?")) {
return
}
// Lanjutkan penghapusan menggunakan parameter id
fetch(`/items/${id}`, { method: "DELETE" })
}
}Keyboard event modifiers memfilter tombol mana yang memicu action:
<%# Hanya trigger pada tombol Enter %>
<input type="text"
data-controller="search"
data-action="keydown.enter->search#submit">
<%# Kombinasikan beberapa modifier %>
<input type="text"
data-controller="shortcuts"
data-action="keydown.ctrl+s->shortcuts#save:prevent">Modifier :prevent memanggil event.preventDefault(), dan :stop memanggil event.stopPropagation(). Ini menggantikan penanganan event manual di method controller.
Siap menguasai wawancara Ruby on Rails Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Target Lifecycle Callbacks dan Default Values
Stimulus memanggil method lifecycle saat target muncul atau menghilang dari DOM:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["panel"]
static values = {
index: { type: Number, default: 0 }
}
// Dipanggil saat target panel baru ditambahkan ke DOM
panelTargetConnected(element) {
element.hidden = this.panelTargets.indexOf(element) !== this.indexValue
}
// Dipanggil saat target panel dihapus dari DOM
panelTargetDisconnected(element) {
// Pembersihan jika diperlukan
}
select(event) {
this.indexValue = event.params.index
}
indexValueChanged() {
this.panelTargets.forEach((panel, index) => {
panel.hidden = index !== this.indexValue
})
}
}Default values menghilangkan null checks. Opsi default dalam definisi value memastikan value selalu ada, bahkan ketika atribut data tidak ada di HTML.
Mengkoordinasikan Controller dengan Outlets API
Outlets API, diperkenalkan di Stimulus 3.2, memungkinkan controller mereferensikan controller lain di halaman:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static outlets = ["validation"]
submit(event) {
// Akses semua instance validation controller
const allValid = this.validationOutlets.every(v => v.isValid())
if (!allValid) {
event.preventDefault()
}
}
}import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["input", "error"]
static values = { pattern: String }
isValid() {
const valid = new RegExp(this.patternValue).test(this.inputTarget.value)
this.errorTarget.hidden = valid
return valid
}
}<%# Hubungkan outlets di HTML %>
<form data-controller="form"
data-form-validation-outlet=".validation-field">
<div class="validation-field"
data-controller="validation"
data-validation-pattern-value="^\S+@\S+$">
<input type="email" data-validation-target="input">
<span data-validation-target="error" hidden>Email tidak valid</span>
</div>
<button data-action="click->form#submit">Kirim</button>
</form>Outlets menyediakan alternatif yang lebih bersih daripada dispatching custom events ketika controller perlu berkomunikasi langsung.
Referensi outlet diselesaikan saat controller terhubung. Jika elemen target ditambahkan secara dinamis, referensi outlet tidak akan diperbarui secara otomatis. Gunakan callback outletConnected dan outletDisconnected untuk menangani skenario dinamis.
Pertanyaan Interview Teknis tentang Arsitektur Frontend Rails
Pewawancara sering bertanya tentang pendekatan Rails terhadap JavaScript untuk menilai pemahaman arsitektur:
Mengapa memilih Importmaps daripada bundler tradisional?
Importmaps mengurangi kompleksitas untuk aplikasi di mana JavaScript bersifat tambahan, bukan utama. Trade-off-nya: tree-shaking dan optimisasi lanjutan tidak tersedia, dan package dengan distribusi CommonJS-only memerlukan konversi manual atau vendoring. Untuk aplikasi yang berat JavaScript, jsbundling-rails dengan esbuild tetap menjadi pilihan valid.
Bagaimana Stimulus berbeda dari React atau Vue?
Stimulus memperkaya HTML yang sudah ada daripada menghasilkannya. Markup yang di-render server tetap menjadi sumber kebenaran, dengan Stimulus menambahkan perilaku melalui atribut data. Model ini bekerja baik dengan Turbo dan siklus request-response tradisional Rails. Kurva pembelajarannya lebih rendah, tetapi manajemen state sisi klien yang kompleks lebih sulit diimplementasikan.
Apa yang terjadi saat controller Stimulus terhubung?
Callback connect() dipicu setelah Stimulus mengidentifikasi atribut data-controller pada elemen. Target dan value sudah diselesaikan pada titik ini. Controller tetap aktif sampai elemen dihapus dari DOM, di mana disconnect() dipanggil.
Memahami konsep-konsep ini menandakan keakraban dengan filosofi Hotwire dan strategi frontend Rails.
Debugging Controller Stimulus dalam Development
Stimulus menyediakan mode debug yang mencatat event lifecycle controller ke console:
import { Application } from "@hotwired/stimulus"
const application = Application.start()
// Aktifkan mode debug di development
if (process.env.NODE_ENV === "development") {
application.debug = true
}
export { application }Dengan mode debug diaktifkan, console menunjukkan kapan controller terhubung, terputus, dan kapan value berubah. Output ini membantu melacak masalah dengan atribut data atau selector target.
Untuk debugging yang lebih kompleks, ekstensi browser Stimulus Devtools menampilkan semua controller aktif dan state mereka saat ini.
Mengintegrasikan Stimulus dengan Rails Modern Asset Pipeline
Rails 8.1 menggunakan Propshaft sebagai asset pipeline default, menggantikan Sprockets. Propshaft menangani aset statis seperti gambar dan CSS, sementara Importmaps mengelola JavaScript secara independen. Pelajari lebih lanjut tentang pendekatan asset pipeline Rails di modul khusus.
Pemisahan ini bersih: Propshaft mengompilasi dan menambahkan fingerprint file CSS, Importmaps menyelesaikan module JavaScript saat runtime. Tidak ada langkah kompilasi untuk JavaScript, mengurangi waktu deployment dan menghilangkan node_modules dari production image.
# Gemfile - Setup default Rails 8.1
gem "propshaft"
gem "importmap-rails"
gem "stimulus-rails"
gem "turbo-rails"Stack ini mewakili jawaban Rails yang opinionated untuk pengembangan frontend: HTML yang di-render server diperkaya dengan JavaScript tertarget, dikirimkan tanpa kompleksitas build-time.
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Poin-Poin Utama untuk Pengembangan JavaScript Rails
- Importmaps memuat package npm via CDN tanpa bundling. Gunakan
bin/importmap pin package-nameuntuk menambahkan dependency. Versi 2.2.2 importmap-rails adalah rilis terkini. - Controller Stimulus menghubungkan JavaScript ke HTML melalui atribut
data-controller,data-action, dandata-target. Framework menangani manajemen lifecycle secara otomatis. - Action parameters meneruskan data dari HTML ke method controller via atribut
data-*-param, mengurangi kebutuhan untuk query DOM. - Outlets API mengkoordinasikan beberapa controller di halaman tanpa custom events atau global state.
- Mode debug (
application.debug = true) mencatat semua aktivitas controller ke console selama development. - Propshaft menangani CSS dan aset statis, sementara Importmaps menangani JavaScript. Kedua sistem beroperasi secara independen.
- Untuk aplikasi yang berat JavaScript, jsbundling-rails menyediakan jalan keluar ke esbuild atau webpack sambil mempertahankan konvensi Rails.
Bisakah kamu menemukan bug di Ruby on Rails?
Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Ditulis oleh
Anthony Fillion-MailletPendiri SharpSkill
Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.
Diperbarui 29 Agustus 2026
Bagikan
Artikel terkait

Rails GraphQL API di 2026: graphql-ruby, Subscriptions, dan Pertanyaan Interview
Bangun GraphQL API siap produksi dengan Rails 8 dan graphql-ruby. Desain schema, mutations, subscriptions dengan ActionCable, dan persiapan interview.

Background Jobs Rails di 2026: Sidekiq vs Good Job dan Pertanyaan Interview
Panduan lengkap memilih queue backend untuk Rails: perbandingan Sidekiq 8.x, Good Job 4.x, dan Solid Queue dengan fokus pada throughput, fitur, dan pertanyaan interview teknis.

Rails Active Storage 2026: Upload File, Integrasi S3, dan Pertanyaan Interview
Panduan lengkap Rails Active Storage untuk upload file, integrasi Amazon S3, dan persiapan pertanyaan interview Ruby on Rails.