I have opened an issue in the importmap-rails gem github repository here about this but thought I'd throw the question out here in case anyone might have a workaround
This is what I have discovered so far
A new engine with Rails 7 alpha 2 or Rails 7.0, generated using rails plugin new custom_page --mountable --full
generates a new engine that includes the importmap-rails gem in the bundled gems but there is no ability to use it. Adding spec.add_dependency 'importmap-rails'
to the enginename.gemspec makes no difference, nor does adding a require importmap-rails
to engine.rb. There is no importmap executable in the bin directory.
A call to bundle info importmap-rails
Produces a promising result showing that the gem is installed by default
* 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
A call to rails --tasks
shows
rails app:importmap:install # Setup Importmap for the app
But I believe this is coming from the test application generated by the --full option rather than being available to the rails command for the engine. I was expecting to see the same without app: prefix A call to this task resolves to a template error as shown
rails app:importmap:install
Don't know how to build task 'app:template' (See the list of available tasks with
rails --tasks
) Did you mean? app:tmp:create
If there is a workaround solution to this I'd be grateful to hear it and I'm sure others will too. The reason for me wanting this is that I totally failed to introduced webpacker in a rails 6.1.4 engine and I was hoping this was going to be my, much improved, solution
Update in response to Alex
Running bin/importmap json
within the engine directory results in
importmap-rails-1.2.1/lib/importmap/commands.rb:63:in json': undefined method
join' for nil:NilClass (NoMethodError)
require Rails.root.join("config/environment")
^^^^^
from /home/jamie/.rvm/gems/ruby-3.2.2@custom_page/gems/thor-1.2.2/lib/thor/command.rb:27:in `run'
from /home/jamie/.rvm/gems/ruby-3.2.2@custom_page/gems/thor-1.2.2/lib/thor/invocation.rb:127:in `invoke_command'
from /home/jamie/.rvm/gems/ruby-3.2.2@custom_page/gems/thor-1.2.2/lib/thor.rb:392:in `dispatch'
from /home/jamie/.rvm/gems/ruby-3.2.2@custom_page/gems/thor-1.2.2/lib/thor/base.rb:485:in `start'
from /home/jamie/.rvm/gems/ruby-3.2.2@custom_page/gems/importmap-rails-1.2.1/lib/importmap/commands.rb:147:in `<top (required)>'
from <internal:/home/jamie/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
from <internal:/home/jamie/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
from bin/importmap:24:in `<main>'
This engine functionality is not in an app yet
There are no importmap error messages in my logs, searched for "Importmap skipped missing path" and "skipped" and "importmap", the last did throw up errors from an earlier bug but nothing since that bug was resolved
I have a standard assets setup, I do have a feature that updates css files which may be what you are thinking of.
I have no compiled assets and all files are named import and import.rb in the singular
The following code in my application.js is as follows
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
my manifest
//= link_directory ../stylesheets/ccs_cms/custom_page .css
//= link_tree ../javascripts/ccs_cms/custom_page .js
//= link_tree ../javascripts/new_ckeditor
//= link ccs_cms/custom_page/jqtree.css
//= link ccs_cms/custom_page/public.css
my application.js looks like
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
//= require ccs_cms/custom_page/jquery-3.6.0.min
//= require ccs_cms/custom_page/jquery-ui.min
//= require ccs_cms/custom_page/tree.jquery
//= require ccs_cms/custom_page/sortable
//= require ccs_cms/custom_page/nested_fields/addFields
//= require_tree .
//require("./nested-forms/addFields");
//require("./nested-forms/removeFields");
// do some javascript
document.querySelector("h1").innerText = "Hi!, i'm your engine";
console.log("hi, again");
importmap.rb contains the following
# my_engine/config/importmap.rb
# NOTE: this pin works because `my_engine/app/assets/javascripts
# is in the `Rails.application.config.assets.paths`
pin "ccs_cms/custom_page/application"
The following is generated in the head
<script type="importmap" data-turbo-track="reload">{
"imports": {
}
}</script>
along with
<script type="module">import "application"</script>
<script type="module">import "ccs_cms/custom_page/application"</script>
A further update: I do see the hi again message in the console so the console.log("hi, again");
works but the document.querySelector("h1").innerText = "Hi!, i'm your engine";
has no effect
Finally, adding
initializer :append_importmap_paths do |app|
app.config.importmap.paths << root.join("config/importmap.rb")
end
to the engine.rb resolved the last piece of the jigsaw
app:template
, but you should haveapp:app:template
. My workaround is to create an alias rake task to bypass this error. in your rake file :desc 'Alias to app:app:template' task template: :environment do Rake::Task['app:app:template'].invoke end