Вопрос или проблема
Я создал новое приложение на Rails с нуля с
- Ruby 3.3.3
- Rails 7.1.3
1 контроллер Stimulus работает без проблем.
Однако, когда я добавляю второй контроллер, ничего не работает.
Я получаю
Uncaught SyntaxError: Identifier 'Controller' has already been declared
Uncaught SyntaxError: Identifier '.default' has already been declared
Я проверил скомпилированный JS, проблема в том, что import { Controller } from '@hotwired/stimulus'
и export default ...
объявлены дважды в application.js (вероятно, из-за добавления этого в 2 различных контроллера).
Вот мой код для 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 'bootstrap', to: 'bootstrap.min.js', preload: true
pin '@popperjs/core', to: 'popper.js', preload: true
pin_all_from 'app/javascript/controllers', under: 'controllers'
Код для controllers/index.js
import { Application } from "@hotwired/stimulus"
const application = Application.start()
application.debug = false
window.Stimulus = application
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)
Код для application.js
//= require jquery3
//= require jquery_ujs
//= require popper
//= require bootstrap
//= require_tree .
import "@hotwired/turbo-rails"
Код для 2 контроллеров с разными именами файлов.
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
...
}
Я попробовал добавить import ..
в index.js и убрать default
из строки экспорта, дав каждому классу имя.
Это привело к другим проблемам, и ничего не работает.
Я хочу, чтобы мои контроллеры работали безупречно, без необходимости вручную регистрировать каждый контроллер.
Буду признателен за любую помощь.
Ответ или решение
Проблема, с которой вы сталкиваетесь, возникает из-за конфликтов имен при импорте контроллеров Stimulus. Давайте подробно рассмотрим, как можно исправить эту ошибку, чтобы ваши контроллеры работали корректно, не требуя явной регистрации.
Проблема
Когда вы создаете несколько контроллеров Stimulus и каждый из них импортирует Controller
из @hotwired/stimulus
, при этом у вас в коде вызывается имя Controller
несколько раз, что вызывает ошибку Uncaught SyntaxError: Identifier 'Controller' has already been declared
. Это происходит по одной причине: JavaScript не позволяет объявлять одну и ту же переменную дважды в одной и той же области видимости.
Решение
-
Изменение Структуры Импортов:
Используйте именованные экспорты в ваших контроллерах, чтобы избежать конфликта. Вместо импорта
Controller
в каждом контроллере вы можете получить доступ к основному контроллеру черезindex.js
.Пример кода вашего контроллера:
import { Controller } from "@hotwired/stimulus" export default class YourControllerName extends Controller { // Ваш код }
Убедитесь, что вы используете уникальные имена классов для каждого контроллера.
-
Объединение Импортов:
В файле
controllers/index.js
вы можете импортировать все ваши контроллеры и регистрировать их автоматически:import { Application } from "@hotwired/stimulus" import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" const application = Application.start() application.debug = false window.Stimulus = application eagerLoadControllersFrom("controllers", application)
Убедитесь, что в вашей структуре проекта контроллеры находятся в папке
app/javascript/controllers
. -
Проверка Уникальности Имен:
Убедитесь, что каждое имя класса для контроллеров уникально. Например:
// controllers/first_controller.js import { Controller } from "@hotwired/stimulus" export default class FirstController extends Controller { // Ваш код } // controllers/second_controller.js import { Controller } from "@hotwired/stimulus" export default class SecondController extends Controller { // Ваш код }
-
Применение Стиля Импортов:
Старайтесь использовать единый стиль для импорта и экспорта, что поможет избежать неполадок в будущем.
Заключение
Следуя вышеизложенным рекомендациям, вы должны смочь успешно интегрировать несколько контроллеров Stimulus в ваше приложение без ошибок. Открывайте консоль разработчика в вашем браузере, чтобы проверить наличие новых ошибок, и убедитесь, что все ваши контроллеры загружаются корректно. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать их!