Соглашения по именованию и организации кода

Stimulus — это легковесный JavaScript-фреймворк, ориентированный на улучшение HTML через декларативные контроллеры. Ключевым аспектом эффективной работы с ним является строгая организация кода и соблюдение соглашений по именованию. Это упрощает поддержку проектов, делает код предсказуемым и читаемым, а также снижает вероятность ошибок при масштабировании приложений.


Именование контроллеров

Контроллеры в Stimulus регистрируются через метод application.register. Имя контроллера состоит из двух частей, разделённых дефисом:

application.register("user-profile", UserProfileController)

Правила:

  • Имя всегда в нижнем регистре, слова разделяются дефисом (kebab-case).
  • Оно должно отражать конкретную функциональность контроллера.
  • Контроллерный класс обычно именуется в стиле PascalCase (каждое слово с заглавной буквы, без дефисов) и оканчивается на Controller: UserProfileController.

Пример соответствия:

HTML имя контроллера JS класс контроллера
data-controller="cart-items" CartItemsController
data-controller="search-form" SearchFormController

Именование действий

Stimulus использует синтаксис data-action для привязки событий к методам контроллера:

<button data-action="click->user-profile#toggleDetails">Показать детали</button>

Правила:

  • Событие указывается первым (click, submit, input).
  • Имя контроллера пишется в kebab-case.
  • Метод контроллера в camelCase (toggleDetails).
  • Названия методов должны быть глагольно-ориентированными, отражать конкретное действие.

Именование целевых элементов

Целевые элементы объявляются через data-<controller>-target:

<div data-controller="user-profile">
  <p data-user-profile-target="name"></p>
  <button data-user-profile-target="button">Изменить</button>
</div>

Правила:

  • Имя цели в camelCase.
  • Имена должны быть краткими, отражать смысл элемента: inputField, submitButton, modalContent.
  • Множественные элементы допускаются, но следует использовать массивы через метод this.targets.findAll("targetName").

Организация методов контроллера

Контроллер Stimulus обычно разделяется на несколько категорий методов:

  1. Lifecycle методы

    • connect() — вызывается при подключении контроллера к DOM.
    • disconnect() — вызывается при удалении контроллера из DOM.
    • initialize() — вызывается до connect(), подходит для установки начальных состояний.
  2. Методы действий

    • Привязаны к событиям через data-action.
    • Должны быть короткими, делегировать сложную логику в приватные методы или сервисы.
  3. Приватные методы

    • Обычно начинаются с _ или помечаются как приватные через соглашение.
    • Используются для инкапсуляции вспомогательных операций.
  4. Геттеры и сеттеры для целей

    • Для удобного доступа к элементам через this.targetNameTarget или коллекциям через this.targetNameTargets.

Пример структуры контроллера:

import { Controller } from "@hotwired/stimulus"

export default class UserProfileController extends Controller {
  static targets = ["name", "button"]

  initialize() {
    this._setupDefaults()
  }

  connect() {
    console.log("Контроллер подключен")
  }

  disconnect() {
    console.log("Контроллер отключен")
  }

  toggleDetails(event) {
    event.preventDefault()
    this._toggleVisibility(this.nameTarget)
  }

  _setupDefaults() {
    this.nameTarget.textContent = "Неизвестный пользователь"
  }

  _toggleVisibility(element) {
    element.hidden = !element.hidden
  }
}

Статические свойства контроллера

Stimulus поддерживает несколько статических свойств:

  • targets — список имен целевых элементов.
  • values — декларация значений контроллера для автоматической синхронизации с атрибутами.
  • classes — набор CSS-классов для динамического управления стилями.

Пример использования values:

static values = {
  count: Number,
  visible: Boolean
}

increment() {
  this.countValue++
  this.visibleValue = !this.visibleValue
}

Свойства countValue и visibleValue автоматически синхронизируются с HTML атрибутами data-user-profile-count-value и data-user-profile-visible-value.


Организация HTML структуры

  • Контроллер привязывается к блокам, а не отдельным элементам, чтобы минимизировать количество подключений.
  • Все цели объявляются внутри контроллера, что делает структуру DOM логичной и самодокументируемой.
  • Используется единообразное именование атрибутов: data-controller, data-<controller>-target, data-action, data-<controller>-value.

Пример:

<div data-controller="user-profile" data-user-profile-count-value="0">
  <p data-user-profile-target="name"></p>
  <button data-user-profile-target="button" data-action="click->user-profile#increment">
    Увеличить
  </button>
</div>

Разделение логики

  • Контроллеры Stimulus должны быть тонкими, содержащими только логику взаимодействия с DOM.
  • Сложные операции рекомендуется выносить в отдельные классы или сервисы.
  • Это повышает тестируемость и облегчает повторное использование компонентов.

Итоги соглашений

  • kebab-case для имен контроллеров в HTML.
  • PascalCase для классов контроллеров.
  • camelCase для методов и целей.
  • Строгая структура методов: lifecycle → действия → приватные методы.
  • Использование статических свойств targets, values, classes для декларативного управления.
  • Минимизация логики в контроллерах, разделение ответственности.

Эти соглашения обеспечивают предсказуемость, читаемость и поддержку кода, особенно в крупных проектах с множеством контроллеров.