includemap-rails в Rails 7 Alpha 2, возможно ли это?
Я открыл вопрос в includemap-рельсах гем хранилище GitHub здесь об этом , но думал , что я брошу вопрос здесь , в случае , если кто может иметь обходной путь
Это то, что я обнаружил до сих пор
Новый движок с Rails 7 alpha 2, созданный с использованием
rails plugin new custom_page --mountable --full
генерирует новый движок, который включает гем importmap-rails в связанные гемы, но нет возможности его использовать. Добавление
spec.add_dependency 'importmap-rails'
в gemspec не имеет значения. в каталоге bin нет исполняемого файла importmap. Звонок в
bundle info importmap-rails
Дает многообещающий результат, показывающий, что гем установлен по умолчанию
* importmap-rails (0.8.1)
Summary: Use ESM with importmap to manage modern JavaScript in Rails without transpiling or bundling.
Homepage: https://github.com/rails/importmap-rails
Source Code: https://github.com/rails/importmap-rails
Path: /home/jamie/.rvm/gems/ruby-3.0.0@custom_page/gems/importmap-rails-0.8.1
Звонок на шоу
rails app:importmap:install # Setup Importmap for the app
Я ожидал увидеть то же самое без префикса app :. Вызов этой задачи разрешает ошибку шаблона, как показано.
rails app:importmap:install
Не знаю, как создать задачу 'app: template' (См. Список доступных задач с
rails --tasks
) Ты имел ввиду? app: tmp: create Если есть обходное решение, я был бы благодарен за это, и я уверен, что другие тоже. Причина, по которой я хотел этого, заключается в том, что я полностью не смог внедрить веб-пакет в движке rails 6.1.4, и я надеялся, что это будет мое, значительно улучшенное решение.
2 ответа
Вам не нужно использовать задачу установки для настройки importmaps. Все, что он делает, это несколько операций копирования и вставки, и в любом случае это не помогает с настройкой движка.
Добавьте importmaps в файл gemspec движка:
# my_engine/my_engine.gemspec
spec.add_dependency "importmap-rails"
Обновите файл engine.rb:
# my_engine/lib/my_engine/engine.rb
require "importmap-rails"
module MyEngine
class Engine < ::Rails::Engine
isolate_namespace MyEngine
initializer "my-engine.importmap", before: "importmap" do |app|
# NOTE: this will add pins from this engine to the main app
# https://github.com/rails/importmap-rails#composing-import-maps
app.config.importmap.paths << root.join("config/importmap.rb")
# NOTE: something about cache; I did not look into it.
# https://github.com/rails/importmap-rails#sweeping-the-cache-in-development-and-test
app.config.importmap.cache_sweepers << root.join("app/assets/javascripts")
end
# NOTE: add engine manifest to precompile assets in production
initializer "my-engine.assets" do |app|
app.config.assets.precompile += %w[my_engine_manifest]
end
end
end
Обновите манифест активов:
# my_engine/app/assets/config/my_engine_manifest.js
//= link_tree ../javascripts/my_engine .js
При необходимости добавьте точку входа javascript для нашего движка. Пины будут доступны без этого файла.
# my_engine/app/assets/javascripts/my_engine/application.js
// do some javascript
document.querySelector("h1").innerText = "hi, i'm your engine";
console.log("hi, again");
Обновить компоновку движка:
# my_engine/app/views/layouts/my_engine/application.html.erb
<!DOCTYPE html>
<html>
<head>
<%#
NOTE: This loads/imports main app 'application.js' and all the pins from
the main app and from the engine (because we set it up in the engine.rb).
%>
<%= javascript_importmap_tags %>
<%#
NOTE: Too add engine's javascript functionality we have to load the
entrypoint here or `import` it in the main app `application.js`
%>
<%= javascript_import_module_tag "my_engine/application" %>
</head>
<body> <%= yield %> </body>
</html>
Создайте importmap.rb и закрепите
my_engine/application
, это имя должно совпадать с
javascript_import_module_tag
. Оно не может конфликтовать ни с каким другим именем в основном приложении, поэтому вы не можете просто использовать
application
:
# my_engine/config/importmap.rb
# NOTE: this pin works because `my_engine/app/assets/javascripts
# is in the `Rails.application.config.assets.paths`
pin "my_engine/application"
Некоторые дополнения для проверки настройки:
# app/config/routes.rb
Rails.application.routes.draw do
mount MyEngine::Engine => "/"
end
# my_engine/config/routes.rb
MyEngine::Engine.routes.draw do
get 'home', to: 'homes#index'
end
# my_engine/app/controllers/my_engine/homes_controller.rb
module MyEngine
class HomesController < ApplicationController
def index; end
end
end
# my_engine/app/views/my_engine/homes/index.html.erb
<h1>Home</h1>
На этом этапе у вас должно быть это в вашем отрендеренном макете
<head>
тег, среди прочего:
<script type="importmap" data-turbo-track="reload">{
"imports": {
"application": "/assets/application-66ce7505c61e3e4910ff16e7c220e1fbfb39251cd82e4bab8d325b3aae987cf9.js",
"my_engine/application": "/assets/my_engine/application-31ce493e8376b4c20703a50f38d419ae309ffe410b7ab7fec47440e02eef08a8.js",
}
}</script>
<script type="module">import "application"</script>
<script type="module">import "my_engine/application"</script>
H1
тег должен измениться на
<h1>hi, i'm your engine</h1>
при перезагрузке.
Дополнительные карты импорта можно добавить вручную с помощью https://generator.jspm.io/ .
Для получения бонусных баллов
bin/importmap
можно настроить для работы внутри двигателя. Создать новый
importmap
файл внутри каталога bin.
# my_engine/bin/importmap NOTE: don't forget to `chmod u+x bin/importmap` to make it executable.
#!/usr/bin/env ruby
# NOTE: make sure we are loading the correct versions of things
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
# NOTE: importmap requires some rails goodness that we don't have in the engine,
# because we don't have config/application.rb that loads the environment.
require "rails"
# importmap-rails is not loaded automatically
require "importmap-rails"
# the actual command runner
require "importmap/commands"
Запустите из каталога двигателя:
$ bin/importmap pin react
Pinning "react" to https://ga.jspm.io/npm:react@18.1.0/index.js
$ cat config/importmap.rb
pin "my_engine/application"
pin "react", to: "https://ga.jspm.io/npm:react@18.1.0/index.js"
Я не тестировал его слишком много, поэтому любые отзывы будут приветствоваться. Перезагружаем сервер, если что-то не отображается, не знаю, как ведет себя перезагрузка при всем этом.
Я возвращаюсь к старой школе Javascript, включаемой в html.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
Ну, это определенно работает во всех браузерах вместо того, чтобы выяснять, поддерживает ли браузер функцию, которую я мог бы использовать позже.
У меня есть полный контроль над тем, какую страницу разместить... но это может быть не то, что вам нужно...