2026'da Rails Stimulus ve Importmaps: Build Araçları Olmadan Modern JavaScript
Rails 8'de Stimulus ve Importmaps için kapsamlı bir rehber - webpack, esbuild veya herhangi bir bundler olmadan interaktif web uygulamaları geliştirme.

Rails her zaman yapılandırma yerine konvansiyon ilkesini benimsemiş bir framework olmuştur ve JavaScript yaklaşımı da bunun bir istisnası değildir. 2026 yılında Rails 8, webpack, esbuild veya herhangi bir bundler yapılandırması gerektirmeden interaktif uygulamalar oluşturmak için olgun bir teknoloji yığını sunmaktadır. Stimulus ve Importmaps, Rails ekosisteminde modern JavaScript yaklaşımının temelini oluşturmaktadır.
Stimulus ve Importmaps, her yeni Rails 8 uygulamasında varsayılan olarak etkindir. Bu, sıfır yapılandırma anlamına gelir - rails new komutunu çalıştırmak ve interaktif JavaScript kodu yazmaya başlamak yeterlidir.
Importmaps Nedir ve Neden Kullanılmalı
Importmaps, JavaScript modül adlarını doğrudan URL'lere eşlemeye olanak tanıyan yerleşik bir tarayıcı özelliğidir. Tüm dosyaları tek bir büyük dosyada paketlemek yerine tarayıcı, modülleri talep üzerine indirir. Rails, bu teknolojiyi importmap-rails gem'i aracılığıyla kullanmaktadır.
Bu yaklaşımın temel avantajları arasında build adımının ortadan kaldırılması, geliştirme sırasında anında yenileme ve yapılandırma basitliği yer almaktadır. Node.js kurulumu veya npm paket yönetimi gerekmemektedir.
# config/importmap.rb
pin "application"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"Yukarıdaki yapılandırma, tüm gerekli modülleri tanımlamaktadır. pin direktifi bir modül adını belirli bir dosyaya eşlerken, pin_all_from belirtilen dizindeki tüm Stimulus controller'larını otomatik olarak kaydetmektedir.
Harici Kütüphaneler Ekleme
JavaScript kütüphaneleri eklemek, geleneksel bundler'larda olduğu kadar basittir. bin/importmap pin komutu, CDN'den kütüphaneyi indirir ve yapılandırmaya uygun girişi ekler.
# lodash kütüphanesini ekleme
bin/importmap pin lodash
# Belirli bir sürümle kütüphane ekleme
bin/importmap pin lodash@4.17.21
# Mevcut pin'leri görüntüleme
bin/importmap pinsKomut çalıştırıldıktan sonra kütüphane, JavaScript kodunda import için hemen kullanılabilir hale gelmektedir:
import _ from "lodash"
console.log(_.chunk([1, 2, 3, 4, 5], 2))
// Output: [[1, 2], [3, 4], [5]]Stimulus'a Giriş
Stimulus, sunucu tarafından oluşturulan HTML ile çalışmak için özel olarak tasarlanmış bir JavaScript framework'üdür. React veya Vue'nun aksine Stimulus, render işlemini devralmazken mevcut HTML'i interaktivite ile zenginleştirmektedir.
Stimulus'un temel yapı taşları controller'lardır. Her controller, sayfadaki belirli bir davranıştan sorumlu bir JavaScript sınıfıdır.
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["name", "output"]
greet() {
this.outputTarget.textContent = `Merhaba, ${this.nameTarget.value}!`
}
}Yukarıdaki controller, iki target (DOM öğesi) ve output öğesinin içeriğini güncelleyen bir greet metodu tanımlamaktadır. Controller'ı HTML'e bağlamak için data attribute'ları kullanılmaktadır:
<div data-controller="hello">
<input data-hello-target="name" type="text" placeholder="İsminizi girin">
<button data-action="click->hello#greet">Selamla</button>
<p data-hello-target="output"></p>
</div>Stimulus Controller'ları Oluşturma
Rails, yeni Stimulus controller'ları oluşturmak için bir generator sağlamaktadır. Bu, proje yapısı tutarlılığını korumaya ve controller'ı sisteme otomatik olarak kaydetmeye yardımcı olmaktadır.
# Yeni bir controller oluşturma
bin/rails generate stimulus dropdown
# Sonuç:
# create app/javascript/controllers/dropdown_controller.jsOluşturulan controller, genişletilmeye hazır temel bir yapı içermektedir:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
// Controller DOM'a bağlandığında çağrılır
}
}Stimulus'ta Lifecycle Callback'leri
Stimulus controller'ları, controller yaşam döngüsünün belirli anlarında çağrılan bir dizi lifecycle metodu sunmaktadır. Bu callback'leri anlamak, durum ve kaynakların düzgün yönetimi için kritik öneme sahiptir.
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = { interval: { type: Number, default: 1000 } }
static targets = ["display"]
connect() {
this.count = 0
this.startTimer()
}
disconnect() {
this.stopTimer()
}
startTimer() {
this.timer = setInterval(() => {
this.count++
this.displayTarget.textContent = this.count
}, this.intervalValue)
}
stopTimer() {
if (this.timer) {
clearInterval(this.timer)
}
}
}connect() metodu, controller'lı öğe DOM'a eklendiğinde çağrılırken, disconnect() öğe kaldırıldığında çağrılmaktadır. Bunlar, başlatma ve temizleme işlemleri için ideal yerlerdir.
Values - Reaktif Özellikler
Stimulus Values, yapılandırma verilerini doğrudan HTML attribute'larında saklamak için bir mekanizmadır. Values, veri türlerini otomatik olarak ayrıştırır ve değişiklik callback'leri aracılığıyla reaktivite sunmaktadır.
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = {
index: { type: Number, default: 0 },
autoplay: { type: Boolean, default: false },
images: Array
}
static targets = ["slide"]
indexValueChanged() {
this.showCurrentSlide()
}
autoplayValueChanged() {
if (this.autoplayValue) {
this.startAutoplay()
} else {
this.stopAutoplay()
}
}
next() {
if (this.indexValue < this.imagesValue.length - 1) {
this.indexValue++
} else {
this.indexValue = 0
}
}
previous() {
if (this.indexValue > 0) {
this.indexValue--
} else {
this.indexValue = this.imagesValue.length - 1
}
}
showCurrentSlide() {
this.slideTarget.src = this.imagesValue[this.indexValue]
}
startAutoplay() {
this.autoplayTimer = setInterval(() => this.next(), 3000)
}
stopAutoplay() {
if (this.autoplayTimer) {
clearInterval(this.autoplayTimer)
}
}
}HTML yapılandırması aşağıdaki gibi görünmektedir:
<div data-controller="slideshow"
data-slideshow-index-value="0"
data-slideshow-autoplay-value="true"
data-slideshow-images-value='["img1.jpg", "img2.jpg", "img3.jpg"]'>
<img data-slideshow-target="slide" src="">
<button data-action="slideshow#previous">Önceki</button>
<button data-action="slideshow#next">Sonraki</button>
</div>Outlets - Controller'lar Arası İletişim
Outlet'ler, controller'ların sayfadaki diğer controller'lara referans vermesine olanak tanımaktadır. Bu, bileşenler arasında karmaşık etkileşimler oluşturmanın zarif bir yoludur.
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static outlets = ["results"]
static targets = ["input"]
search() {
const query = this.inputTarget.value
if (this.hasResultsOutlet) {
this.resultsOutlet.filter(query)
}
}
}import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["item"]
filter(query) {
this.itemTargets.forEach(item => {
const visible = item.textContent.toLowerCase().includes(query.toLowerCase())
item.classList.toggle("hidden", !visible)
})
}
}Bağlantı yapılandırması outlet attribute'u aracılığıyla gerçekleştirilmektedir:
<div data-controller="search" data-search-results-outlet="#search-results">
<input data-search-target="input" data-action="input->search#search">
</div>
<div id="search-results" data-controller="results">
<div data-results-target="item">Öğe 1</div>
<div data-results-target="item">Öğe 2</div>
<div data-results-target="item">Öğe 3</div>
</div>Pratik Örnek: Formlu Modal
Aşağıdaki örnek, animasyonlar ve doğrulama dahil olmak üzere formlu bir modal'ı işleyen daha karmaşık bir controller'ı göstermektedir.
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["dialog", "form"]
static values = { open: Boolean }
connect() {
this.boundHandleKeydown = this.handleKeydown.bind(this)
}
open() {
this.openValue = true
this.dialogTarget.showModal()
document.addEventListener("keydown", this.boundHandleKeydown)
this.dialogTarget.classList.add("opacity-100")
this.dialogTarget.classList.remove("opacity-0")
}
close() {
this.openValue = false
this.dialogTarget.classList.add("opacity-0")
this.dialogTarget.classList.remove("opacity-100")
setTimeout(() => {
this.dialogTarget.close()
}, 200)
document.removeEventListener("keydown", this.boundHandleKeydown)
}
handleKeydown(event) {
if (event.key === "Escape") {
this.close()
}
}
submitForm(event) {
if (!this.formTarget.checkValidity()) {
event.preventDefault()
this.formTarget.reportValidity()
}
}
clickOutside(event) {
if (event.target === this.dialogTarget) {
this.close()
}
}
}<div data-controller="modal">
<button data-action="modal#open">Formu Aç</button>
<dialog data-modal-target="dialog"
data-action="click->modal#clickOutside"
class="opacity-0 transition-opacity duration-200 backdrop:bg-black/50">
<form data-modal-target="form" data-action="submit->modal#submitForm">
<h2>İletişim Formu</h2>
<input type="email" required placeholder="E-posta">
<textarea required placeholder="Mesaj"></textarea>
<div>
<button type="button" data-action="modal#close">İptal</button>
<button type="submit">Gönder</button>
</div>
</form>
</dialog>
</div>Turbo ile Entegrasyon
Stimulus, Hotwire'ın ikinci temel bileşeni olan Turbo ile mükemmel bir şekilde çalışmaktadır. Turbo, sayfa navigasyonunu ve güncellemelerini yönetirken, Stimulus istemci tarafı interaktivitesini eklemektedir.
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["submit", "spinner"]
submitting() {
this.submitTarget.disabled = true
this.spinnerTarget.classList.remove("hidden")
}
submitted() {
this.submitTarget.disabled = false
this.spinnerTarget.classList.add("hidden")
}
}<%= form_with model: @contact,
data: {
controller: "form",
action: "turbo:submit-start->form#submitting turbo:submit-end->form#submitted"
} do |f| %>
<%= f.text_field :name %>
<%= f.email_field :email %>
<%= f.submit "Gönder", data: { form_target: "submit" } %>
<span data-form-target="spinner" class="hidden">Gönderiliyor...</span>
<% end %>Ruby on Rails mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Hata Ayıklama ve Geliştirici Araçları
Geliştirme sırasında Stimulus controller'larının hata ayıklaması için araçlar oldukça faydalıdır. Uygulamada debug modu etkinleştirilebilir:
import { Application } from "@hotwired/stimulus"
const application = Application.start()
// Debug modunu etkinleştirme
application.debug = true
// Tarayıcı konsolundan uygulamaya erişim
window.Stimulus = applicationDebug modu etkinleştirildiğinde, tarayıcı konsolu controller'ların bağlanması ve bağlantısının kesilmesi hakkında bilgi görüntüler, bu da sorunların teşhisini önemli ölçüde kolaylaştırmaktadır.
Stimulus Controller'larını Test Etme
Stimulus controller'larının test edilmesi, JavaScript test sistemi veya Rails sistem testleri kullanılarak gerçekleştirilebilir.
import { Application } from "@hotwired/stimulus"
import HelloController from "controllers/hello_controller"
describe("HelloController", () => {
let application
beforeEach(() => {
document.body.innerHTML = `
<div data-controller="hello">
<input data-hello-target="name" value="Ahmet">
<button data-action="click->hello#greet">Selamla</button>
<p data-hello-target="output"></p>
</div>
`
application = Application.start()
application.register("hello", HelloController)
})
afterEach(() => {
application.stop()
})
it("tıklandığında selamlama görüntüler", () => {
const button = document.querySelector("button")
const output = document.querySelector("[data-hello-target='output']")
button.click()
expect(output.textContent).toBe("Merhaba, Ahmet!")
})
})Büyük Projelerde Kod Organizasyonu
Büyük uygulamalarda controller'ları işlevselliğe göre alt dizinlerde organize etmek faydalıdır. Importmaps, iç içe geçmiş yapıları otomatik olarak işlemektedir.
# config/importmap.rb
pin_all_from "app/javascript/controllers", under: "controllers"
pin_all_from "app/javascript/controllers/admin", under: "controllers/admin"
pin_all_from "app/javascript/controllers/shared", under: "controllers/shared"Dizin yapısı:
app/javascript/controllers/
├── application.js
├── index.js
├── hello_controller.js
├── admin/
│ ├── dashboard_controller.js
│ └── users_controller.js
└── shared/
├── modal_controller.js
└── dropdown_controller.jsHTML'de alt dizinlerden controller'lar önek ile referans verilmektedir:
<div data-controller="admin--dashboard">...</div>
<div data-controller="shared--modal">...</div>Sonuç
Rails 8'de Stimulus ve Importmaps, geleneksel JavaScript bundler'larının karmaşıklığı olmadan interaktif web uygulamaları oluşturmak için zarif bir çözüm sunmaktadır. Bu yaklaşım, Rails felsefesine mükemmel bir şekilde uymaktadır - yapılandırma yerine konvansiyon.
Temel faydalar arasında sıfır yapılandırma, geliştirme sırasında anında yenileme, sunucu tarafından oluşturulan HTML ile tam uyumluluk ve Hotwire yığınının diğer öğeleriyle mükemmel entegrasyon yer almaktadır.
Rails ile çalışan ekipler için Stimulus, mevcut mimarinin doğal bir uzantısını temsil etmekte ve uygulamayı SPA framework'üne yeniden yazmadan kademeli olarak interaktivite eklemeye olanak tanımaktadır. Turbo ile birleştirildiğinde, modern web uygulamaları oluşturmak için eksiksiz bir araç seti oluşturmaktadır.
Ruby on Rails kodundaki hatayı bulabilir misin?
Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Yazan:
Anthony Fillion-MailletSharpSkill kurucusu
10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.
29 Ağustos 2026 tarihinde güncellendi
Paylaş
İlgili makaleler

2026'da Rails GraphQL API: graphql-ruby, Abonelikler ve Mülakat Soruları
Rails 8 ve graphql-ruby ile üretim düzeyinde GraphQL API oluşturma rehberi. Şema tasarımı, mutasyonlar, ActionCable ile abonelikler ve mülakat hazırlığı.

Rails 2026'da Arka Plan Görevleri: Sidekiq vs Good Job Karşılaştırması ve Mülakat Soruları
Rails 8'de Sidekiq, Good Job ve Solid Queue karşılaştırması. Performans analizi, özellik karşılaştırması ve Ruby on Rails background jobs konusunda sık sorulan mülakat soruları.

2026'da Rails Active Storage: Dosya Yükleme, S3 Entegrasyonu ve Mülakat Soruları
2026'da Rails Active Storage için kapsamlı rehber. S3 yapılandırması, doğrudan yükleme, görüntü işleme ve iş görüşmelerinde sıkça sorulan sorular.