importmap-rails icon indicating copy to clipboard operation
importmap-rails copied to clipboard

Are there proposals for importmap-rails to work in rails 7 engines?

Open jamesw opened this issue 3 years ago • 14 comments

A new engine with Rails 7 alpha 2, generated usingrails plugin new custom_page --mountable --fullgenerates 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 gemspec makes no difference. there is no importmap executable in the bin directory. A call to bundle info importmap-rails Produces

* 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 lists rails app:importmap:install # Setup Importmap for the app I was expecting to see the same without app: prefix A call to this task resolves to a template error 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

Hope this is a clear enough question for you. 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 Cheers James

jamesw avatar Oct 19 '21 14:10 jamesw

Still getting nowhere with this nor am I able to introduce webpacker. I have opened a query on Stackoverflow here and here, will see if anything comes from it

jamesw avatar Oct 25 '21 02:10 jamesw

@jamesw As far as I can tell, having used the gem for testing and understanding purposes, engines and plugins are not supposed to provide their own config/importmap.rb. Instead, if the engine/plugin is providing assets, they should be processed through the Asset Pipeline, and the users of your engine/plugin would then map the files in the actual app's config/importmap.rb.

I might be wrong though.

radiantshaw avatar Nov 11 '21 11:11 radiantshaw

I've been trying to get my engines working with Rails 7 and importmap and asset pipeline. It's really not clear between rails documentation and import-rails documentation what is the correct approach and where to put things (ie app/assets/javascripts or app/javascript) and what to include where (ie. index.js). Perhaps my confusion comes from never having to use webpacker (ever!). I did discover that pulling the javascripts directory out of the named space directory worked but the images and css still need to be namespaced. Not looking for any solution just yet just letting someone know the difficulties being encountered.

cpanderson avatar Dec 06 '21 16:12 cpanderson

I have tried again with the new Rails 7.0 release and I have still found no way to use impotmap-rails in an engine, surely this is going to be fixed? Can anyone on the rails team respond to this or give me pointers as to how to fix this, happy to do some work on it.

jamesw avatar Dec 17 '21 16:12 jamesw

Have you read the README? Is there an issue that this doesn't work?

https://github.com/rails/importmap-rails#composing-import-maps

leehericks avatar Dec 18 '21 02:12 leehericks

@leehericks The link to that section of the README does not explain how to use importmap-rails inside an engine. Only how to make use of importmap-rails functionality provided by an engine, If you can follow my steps outlined in my opening post and make it work I would love to know how as would many others I suspect. There is NO documentaion at all as to how to set this up inside an engine whatsoever anywhere. I am not even able to find any github projects that might be doing this as, I guess, it is early days yet.

jamesw avatar Dec 18 '21 05:12 jamesw

I have an outstanding stackoverflow question here with a bounty if anyone cares to take a look

jamesw avatar Dec 18 '21 05:12 jamesw

hey @cpanderson @jamesw did you guys manage to make some progress with this issue?

Still there is no documentation. I am able to nest/compose importmaps from the engine like @leehericks said, but I am not able to , for example , register stimulus controllers from a gem/engine. If you guys know how to do it and/or a repo with some examples would be great.

I am willing to help/improve the documentation, but I need to understand things first :rofl:

Many thanks

muriloime avatar Feb 13 '22 00:02 muriloime

In case someone is interested, there are a couple nice ideas in this repo https://github.com/creditario/nopassword . In particular the following engine importmap allows to load controllers the normal way ( eagerloading in controllers/index.js, etc)

pin "application", to: "my_engine/application.js", preload: true

pin_all_from MyEngine::Engine.root.join("app/assets/javascripts/my_engine/controllers"), under: "controllers", to: "my_engine/controllers"

muriloime avatar Feb 14 '22 01:02 muriloime

That seems to work but some official documentation would be great.

cpanderson avatar Feb 21 '22 19:02 cpanderson

Related, it looks like there's an importmap failure when running rails new. See "Don't know how to build task 'importmap:install'" when running "rails new" (#44651).

getaaron avatar Mar 10 '22 01:03 getaaron

I was doing this in a rails 6 engine and had to add the following within engine.rb


  initializer "my_engine.precompile" do |app|
    app.config.assets.paths << MyEngine.root.join("app/javascripts")
    app.config.assets.precompile << "my_engine/application.js"
  end

sclarson avatar Jul 29 '22 19:07 sclarson

I was doing this in a rails 6 engine and had to add the following within engine.rb


  initializer "my_engine.precompile" do |app|
    app.config.assets.paths << MyEngine.root.join("app/javascripts")
    app.config.assets.precompile << "my_engine/application.js"
  end

confirmed, I had to add similar entries on rails 7 too

I had to import stimulus controllers from my custom engine,

in engine' importmap.rb

   controllers_path = File.expand_path("../app/javascript/controllers", __dir__)
   pin_all_from controllers_path, to: 'controllers', under: 'controllers'

and in engine.rb

initializer 'my_engine.assets.precompile' do |app|
  app.config.assets.paths << Engine.root.join('app/javascript')
  app.config.assets.paths << Engine.root.join('app/javascript/controllers')

  file_names = Dir.entries(Engine.root.join('app/javascript/controllers')).select do |file|
    file.end_with?('_controller.js')
  end
  file_names.each {|file_name| app.config.assets.precompile << file_name }
end

artur79 avatar Jan 25 '24 13:01 artur79

For what it's worth, I've got the same issue in the test environment:

my_engine/spec/dummy
❯ ./bin/importmap json
{
  "imports": {
    "@hotwired/stimulus": "/assets/@hotwired--stimulus-8460570e.js",
    "@hotwired/stimulus-loading": "/assets/@hotwired--stimulus-loading-25917588.js",
    "application": "/assets/application-befe7753.js",
    "controllers/application": "/assets/controllers/application-1b22bc5a.js",
    "controllers/hello_controller": "/assets/controllers/hello_controller-0234a591.js",
    "controllers": "/assets/controllers/index-d8684923.js"
  }
}

my_engine/spec/dummy
❯ RAILS_ENV=test ./bin/importmap json           
{
  "imports": {
    "@hotwired/stimulus": "/@hotwired--stimulus.js",
    "@hotwired/stimulus-loading": "/@hotwired--stimulus-loading.js",
    "application": "/application.js",
    "controllers/application": "/controllers/application.js",
    "controllers/hello_controller": "/controllers/hello_controller.js",
    "controllers": "/controllers/index.js"
  }
}

This is Rails 7, so no concept of app.config.assets or the precompile task.

jfi avatar Jul 01 '24 21:07 jfi