ES-модули (ECMAScript Modules, ESM) представляют собой современный стандарт организации кода в JavaScript. Они позволяют разделять проект на отдельные файлы с чётко определёнными зависимостями и экспортами. Основные конструкции ES-модулей:
export function greet(name) {
return `Hello, ${name}!`;
}
export const PI = 3.14159;
import { greet, PI } from './utils.js';
console.log(greet('Stimulus'));
console.log(PI);
Каждый модуль имеет собственную область видимости. Глобальные переменные не передаются автоматически между модулями, что предотвращает коллизии имён.
ES-модули поддерживают два типа экспорта:
export function add(a, b) { return a + b; }
export function subtract(a, b) { return a - b; }
Импортируются через фигурные скобки:
import { add, subtract } from './math.js';
export default class Logger {
log(message) {
console.log(message);
}
}
Импортируется без фигурных скобок и с любым именем:
import Logger from './logger.js';
const logger = new Logger();
logger.log('Stimulus');
Динамический импорт (import()) позволяет загружать
модули во время выполнения. Это ключевой инструмент для
оптимизации производительности и ленивой загрузки ресурсов.
button.addEventListener('click', async () => {
const module = await import('./feature.js');
module.runFeature();
});
Особенности динамических импортов:
async/await.const moduleName = 'utils';
import(`./${moduleName}.js`).then(module => module.init());
Stimulus организует код через контроллеры, которые сами по себе являются ES-модулями. Каждый контроллер хранится в отдельном файле, что идеально сочетается с подходом модульности:
// controllers/hello_controller.js
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["name"];
greet() {
console.log(`Hello, ${this.nameTarget.value}`);
}
}
Использование контроллеров в HTML через data-атрибуты:
<div data-controller="hello">
<input data-hello-target="name" type="text">
<button data-action="click->hello#greet">Say Hello</button>
</div>
Динамические импорты в Stimulus позволяют загружать контроллеры только при взаимодействии пользователя с определёнными элементами:
document.addEventListener('mouseover', async () => {
const { default: TooltipController } = await import('./tooltip_controller.js');
application.register('tooltip', TooltipController);
});
Преимущества такого подхода:
ES-модули хорошо интегрируются с современными сборщиками: Webpack, Vite, Rollup. Основные моменты:
import() без
ручной настройки..js при импорте в
браузере, иначе модуль не будет найден.try/catch:try {
const module = await import('./optional_feature.js');
module.init();
} catch (error) {
console.warn('Feature not loaded', error);
}
В Stimulus каждый контроллер — это отдельный модуль, а динамические импорты позволяют строить интерфейс из маленьких, независимых компонентов. Такой подход:
Использование ES-модулей совместно с динамическими импортами создаёт современный, модульный и высокоэффективный фронтенд, полностью совместимый с принципами Stimulus.