Rails Stimulus va Importmaps 2026: JavaScript Hien Dai Khong Can Build Tools

Stimulus va Importmaps trong Rails 8.1 cho phep viet JavaScript hien dai ma khong can bundler. Huong dan nay bao gom controller, action, target va cac package npm.

Rails Stimulus va Importmaps 2026: JavaScript Hien Dai Khong Can Build Tools

Rails Stimulus va Importmaps loai bo nhu cau su dung webpack, esbuild, hoac bat ky buoc build JavaScript nao. Rails 8.1 di kem voi importmap-rails va stimulus-rails mac dinh, cho phep cac nha phat trien them hanh vi tuong tac vao HTML duoc render tu server ma khong can quan ly node_modules hoac cau hinh bundler phuc tap.

Khong Can Buoc Build

Importmaps su dung ES modules goc cua trinh duyet. Chay bin/importmap pin chart.js se tai package tu CDN va dang ky no trong config/importmap.rb. Khong can npm install, khong can bien dich, khong can cho doi.

Cach Importmaps Thay The Bundler Truyen Thong

Importmaps tan dung ho tro ES module goc cua trinh duyet de tai cac file JavaScript truc tiep. Thay vi gop tat ca cac dependency vao mot file duy nhat, trinh duyet tai tung module theo yeu cau. JSPM CDN phan giai cac package npm thanh URL tuong thich voi trinh duyet.

File config/importmap.rb dong vai tro nhu mot manifest:

ruby
# 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"

Cau hinh nay cho trinh duyet biet noi tim moi module. Chi thi pin_all_from tu dong dang ky tat ca cac controller Stimulus tu thu muc duoc chi dinh.

Cac trinh duyet ho tro importmaps bao gom Chrome 89+, Edge 89+, Firefox 108+, va Safari 16.4+. Doi voi cac trinh duyet cu hon, Rails tu dong chen polyfill es-module-shims.

Tao Controller Stimulus cho UI Tuong Tac

Controller Stimulus ket noi hanh vi JavaScript voi cac phan tu HTML thong qua cac thuoc tinh data. Moi controller la mot class ke thua tu Controller cua @hotwired/stimulus.

app/javascript/controllers/dropdown_controller.jsjavascript
import { Controller } from "@hotwired/stimulus"

// Quan ly hien thi dropdown voi ho tro ban phim
export default class extends Controller {
  static targets = ["menu", "button"]
  static values = { open: Boolean }

  // Chuyen doi dropdown khi click nut
  toggle() {
    this.openValue = !this.openValue
  }

  // Dong khi click ben ngoai dropdown
  clickOutside(event) {
    if (!this.element.contains(event.target)) {
      this.openValue = false
    }
  }

  // Duoc goi tu dong khi openValue thay doi
  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 - don dep
  disconnect() {
    document.removeEventListener("click", this.clickOutside.bind(this))
  }
}

HTML tuong ung su dung cac thuoc tinh data de ket noi controller:

erb
<%# 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">
    Tuy chon
  </button>
  <ul data-dropdown-target="menu" class="hidden">
    <li>Chinh sua</li>
    <li>Xoa</li>
  </ul>
</div>

Stimulus 3.2.2 gioi thieu Outlets API va keyboard event modifiers. Cac tinh nang nay giam boilerplate khi phoi hop giua cac controller hoac loc keystroke.

Them Package npm voi Importmaps

Them mot thu vien JavaScript chi can mot lenh duy nhat:

bash
# Pin chart.js tu JSPM CDN
bin/importmap pin chart.js

Dieu nay them mot entry vao config/importmap.rb:

ruby
# config/importmap.rb
pin "chart.js", to: "https://ga.jspm.io/npm:chart.js@4.4.1/dist/chart.js"

Thu vien sau do co the duoc import trong bat ky controller nao:

app/javascript/controllers/chart_controller.jsjavascript
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()
  }
}

Tai lieu importmap-rails huong dan vendor package cuc bo cho phat trien offline hoac khi truy cap CDN bi han che.

Xu Ly Dependency Package

Mot so package npm co cay dependency sau. Su dung bin/importmap pin package-name --download de vendor tat ca dependency cuc bo. Cach tiep can nay tot hon cho cac package co nhieu transitive imports.

Action Parameters va Event Modifiers

Stimulus 3.x gioi thieu action parameters, cho phep truyen gia tri truc tiep tu HTML den cac method controller:

erb
<%# Truyen tham so qua thuoc tinh data %>
<button data-controller="item"
        data-action="click->item#delete"
        data-item-id-param="42"
        data-item-confirm-param="true">
  Xoa
</button>
app/javascript/controllers/item_controller.jsjavascript
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  delete(event) {
    const { id, confirm } = event.params
    
    if (confirm && !window.confirm("Xoa item nay?")) {
      return
    }
    
    // Tien hanh xoa su dung tham so id
    fetch(`/items/${id}`, { method: "DELETE" })
  }
}

Keyboard event modifiers loc phim nao kich hoat action:

erb
<%# Chi kich hoat khi nhan phim Enter %>
<input type="text"
       data-controller="search"
       data-action="keydown.enter->search#submit">

<%# Ket hop nhieu modifier %>
<input type="text"
       data-controller="shortcuts"
       data-action="keydown.ctrl+s->shortcuts#save:prevent">

Modifier :prevent goi event.preventDefault(), va :stop goi event.stopPropagation(). Cac modifier nay thay the viec xu ly event thu cong trong method controller.

Sẵn sàng chinh phục phỏng vấn Ruby on Rails?

Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.

Target Lifecycle Callbacks va Default Values

Stimulus goi cac method lifecycle khi target xuat hien hoac bien mat khoi DOM:

app/javascript/controllers/tabs_controller.jsjavascript
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["panel"]
  static values = {
    index: { type: Number, default: 0 }
  }

  // Duoc goi khi target panel moi duoc them vao DOM
  panelTargetConnected(element) {
    element.hidden = this.panelTargets.indexOf(element) !== this.indexValue
  }

  // Duoc goi khi target panel bi xoa khoi DOM
  panelTargetDisconnected(element) {
    // Don dep neu can
  }

  select(event) {
    this.indexValue = event.params.index
  }

  indexValueChanged() {
    this.panelTargets.forEach((panel, index) => {
      panel.hidden = index !== this.indexValue
    })
  }
}

Default values loai bo viec kiem tra null. Tuy chon default trong dinh nghia value dam bao value luon ton tai, ngay ca khi thuoc tinh data khong co trong HTML.

Phoi Hop Controller voi Outlets API

Outlets API, duoc gioi thieu trong Stimulus 3.2, cho phep controller tham chieu den cac controller khac tren trang:

app/javascript/controllers/form_controller.jsjavascript
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static outlets = ["validation"]

  submit(event) {
    // Truy cap tat ca cac instance validation controller
    const allValid = this.validationOutlets.every(v => v.isValid())
    
    if (!allValid) {
      event.preventDefault()
    }
  }
}
app/javascript/controllers/validation_controller.jsjavascript
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
  }
}
erb
<%# Ket noi outlets trong 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 khong hop le</span>
  </div>
  <button data-action="click->form#submit">Gui</button>
</form>

Outlets cung cap mot phuong an sach hon so voi viec dispatch custom events khi cac controller can giao tiep truc tiep.

Outlets Can Co Mat DOM

Cac tham chieu outlet duoc giai quyet khi controller ket noi. Neu phan tu dich duoc them dong, tham chieu outlet se khong tu dong cap nhat. Su dung callback outletConnected va outletDisconnected de xu ly cac tinh huong dong.

Cau Hoi Phong Van Ky Thuat ve Kien Truc Frontend Rails

Nha tuyen dung thuong hoi ve cach tiep can JavaScript cua Rails de danh gia hieu biet ve kien truc:

Tai sao chon Importmaps thay vi bundler truyen thong?

Importmaps giam do phuc tap cho cac ung dung ma JavaScript la bo sung, khong phai chinh. Doi danh: tree-shaking va cac toi uu hoa nang cao khong kha dung, va cac package chi co phan phoi CommonJS can chuyen doi thu cong hoac vendor. Doi voi ung dung nang JavaScript, jsbundling-rails voi esbuild van la lua chon hop le.

Stimulus khac React hoac Vue nhu the nao?

Stimulus nang cao HTML hien co thay vi tao ra no. Markup duoc render tu server van la nguon su that, voi Stimulus them hanh vi thong qua cac thuoc tinh data. Mo hinh nay hoat dong tot voi Turbo va chu ky request-response truyen thong cua Rails. Duong cong hoc thap hon, nhung quan ly state phia client phuc tap kho thuc hien hon.

Dieu gi xay ra khi controller Stimulus ket noi?

Callback connect() duoc kich hoat sau khi Stimulus xac dinh thuoc tinh data-controller tren phan tu. Target va value da duoc giai quyet tai thoi diem nay. Controller van hoat dong cho den khi phan tu bi xoa khoi DOM, luc do disconnect() duoc goi.

Hieu cac khai niem nay cho thay su quen thuoc voi triet ly Hotwire va chien luoc frontend Rails.

Debug Controller Stimulus trong Development

Stimulus cung cap che do debug ghi lai cac event lifecycle controller vao console:

app/javascript/application.jsjavascript
import { Application } from "@hotwired/stimulus"

const application = Application.start()

// Bat che do debug trong development
if (process.env.NODE_ENV === "development") {
  application.debug = true
}

export { application }

Voi che do debug duoc bat, console hien thi khi controller ket noi, ngat ket noi, va khi value thay doi. Output nay giup theo doi van de voi thuoc tinh data hoac selector target.

De debug phuc tap hon, extension trinh duyet Stimulus Devtools hien thi tat ca controller dang hoat dong va trang thai hien tai cua chung.

Tich Hop Stimulus voi Rails Modern Asset Pipeline

Rails 8.1 su dung Propshaft lam asset pipeline mac dinh, thay the Sprockets. Propshaft xu ly cac asset tinh nhu hinh anh va CSS, trong khi Importmaps quan ly JavaScript doc lap. Tim hieu them ve cach tiep can asset pipeline Rails trong module chuyen biet.

Su tach biet nay ro rang: Propshaft bien dich va them fingerprint cac file CSS, Importmaps giai quyet cac module JavaScript tai runtime. Khong co buoc bien dich cho JavaScript, giam thoi gian trien khai va loai bo node_modules khoi production image.

ruby
# Gemfile - Cau hinh mac dinh Rails 8.1
gem "propshaft"
gem "importmap-rails"
gem "stimulus-rails"
gem "turbo-rails"

Stack nay dai dien cho cau tra loi co quan diem cua Rails ve phat trien frontend: HTML duoc render tu server duoc nang cao voi JavaScript co muc tieu, duoc cung cap ma khong co do phuc tap build-time.

Bắt đầu luyện tập!

Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.

Nhung Diem Chinh cho Phat Trien JavaScript Rails

  • Importmaps tai cac package npm qua CDN ma khong can bundling. Su dung bin/importmap pin package-name de them dependency. Phien ban 2.2.2 importmap-rails la ban phat hanh hien tai.
  • Controller Stimulus ket noi JavaScript voi HTML thong qua cac thuoc tinh data-controller, data-action, va data-target. Framework tu dong xu ly quan ly lifecycle.
  • Action parameters truyen du lieu tu HTML den cac method controller qua thuoc tinh data-*-param, giam nhu cau truy van DOM.
  • Outlets API phoi hop nhieu controller tren mot trang ma khong can custom events hoac global state.
  • Che do debug (application.debug = true) ghi lai tat ca hoat dong controller vao console trong qua trinh phat trien.
  • Propshaft xu ly CSS va asset tinh, trong khi Importmaps xu ly JavaScript. Hai he thong hoat dong doc lap.
  • Doi voi ung dung nang JavaScript, jsbundling-rails cung cap loi thoat den esbuild hoac webpack trong khi van duy tri cac quy uoc Rails.
Thử thách hôm nay

Bạn có tìm ra lỗi trong Ruby on Rails không?

Một đoạn mã thật, một lỗi ẩn, mỗi ngày một lượt. Không cần tài khoản để thử.

Anthony Fillion-Maillet

Viết bởi

Anthony Fillion-Maillet

Người sáng lập SharpSkill

Lập trình viên fullstack hơn 10 năm. Anh điều hành SharpSkill và chịu trách nhiệm về mọi nội dung đăng tại đây.

Cập nhật ngày 29 tháng 8, 2026

Chia sẻ

Bài viết liên quan