В моем проекте Rails 7 я использовал importmap
для импорта модулей JS. вот конфиг:
# config/importmap
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin_all_from "app/javascript/lib", under: "lib"
pin "@yaireo/tagify", to: "@yaireo--tagify.js" # @4.26.5
pin "@simonwep/pickr", to: "@simonwep--pickr.js" # @1.9.1
Каталог JS выглядит так (app/javascript
):
├── javascript
│ ├── application.js
│ ├── controllers
│ │ ├── file1.js
│ │ └── file2.js
│ └── lib
│ ├── file3.js
│ └── file4.js
в asset.rb
я также включил это:
Rails.application.config.assets.precompile += %w( lib/file3.js )
Rails.application.config.assets.precompile += %w( lib/file4.js )
Rails.application.config.assets.precompile += %w( controllers/file1.js )
Rails.application.config.assets.precompile += %w( controllers/file2.js )
А app/javascript/application.js
выглядит так (возможно, проблема именно в этом):
import { Turbo } from "@hotwired/turbo-rails"
Turbo.start();
import { Application } from '@hotwired/stimulus';
import File1Controller from './controllers/file1.js'
import File2Controller from './controllers/file2.js'
const application = Application.start();
application.register('file1', File1Controller);
application.register('file2', File2Controller);
И, наконец, app/assets/config/mainfest.js
выглядит так:
//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
//= link_tree ../builds
Все отлично работает при разработке на локальном хосте, но на производстве это показывает:
Loading module from “https://mysweet.domain/assets/controllers/file1.js” was blocked because of a disallowed MIME type (“text/html”).
Как я мог это решить?
@max, спасибо за быстрый ответ. Я нашел немного странным во вкладке сети. на самом деле есть 2 запроса: 1. на file1-<something>.js
(хороший ответ) и 2. file1.js
(который не работает)
Я не совсем понимаю, почему у вас есть файлы в lib и javascripts с одним и тем же именем.
@max не уверен, что правильно тебя понял - в lib
есть file3
и file4
, а внутри controllers
есть file1
и file2
. не те же файлы
Что случилось с картой импорта по умолчанию, настроенной при создании приложения? Я предлагаю вам создать образец приложения и посмотреть.
... blocked because of a disallowed MIME type (“text/html”)
Потому что вы получаете ошибку 404 для этого файла.
Вам не нужно прекомпилировать каждый файл в assets.rb
, это уже сделано в manifest.js
:
// link_tree ../../javascript .js
https://github.com/rails/sprockets#link_tree
Не используйте относительный импорт './controllers/file1.js'
, это работает только в разработке. Относительный путь не соответствует ничему в вашей карте импорта, это означает, что запрос поступает для непереваренных /assets/controllers/file1.js
это работает только в разработке, потому что sprockets
обслуживает активы и может обрабатывать как переваренные, так и непереваренные URL-адреса. В рабочей среде у вас есть предварительно скомпилированные ресурсы, которые можно получить только по переваренному URL-адресу.
Вы должны использовать импорт, который будет соответствовать вашей карте импорта:
$ bin/importmap json
{
"imports": {
...
"controllers/file1": "/assets/controllers/file1-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",
"controllers/file2": "/assets/controllers/file2-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",
"lib/file3": "/assets/lib/file3-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",
"lib/file4": "/assets/lib/file4-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",
}
}
import File1Controller from 'controllers/file1'
import File2Controller from 'controllers/file2'
import File3Lib from 'lib/file3'
import File4Lib from 'lib/file4'
Turbo.start();
- В этом нет необходимости, я не знаю, откуда у вас такая идея.
ты просто потрясающий чувак! Do not use relative imports
все получилось!
Откройте вкладку «Сеть» в веб-инспекторе браузера. Вы должны увидеть запросы на загрузку файлов JS. Я подозреваю, что вместо этого вы попадаете на страницу с ошибкой.