Post

Rails Engine with Importmap and TailwindCSS

Rails Engine with Importmap and TailwindCSS

Create engine

1
rails plugin new blorgh --mountable

Importmap configuration

1
2
3
spec.add_dependency 'importmap-rails'
spec.add_dependency 'turbo-rails'
spec.add_dependency 'stimulus-rails'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require "importmap-rails"
require "turbo-rails"
require "stimulus-rails"

module Blorgh
  class Engine < ::Rails::Engine
    isolate_namespace Blorgh

    initializer "blorgh.assets" do |app|
      app.config.assets.paths << root.join("app/javascript")
    end

    initializer "blorgh.importmap", before: "importmap" do |app|
      app.config.importmap.paths << root.join("config/importmap.rb")
      app.config.importmap.cache_sweepers << root.join("app/javascript")
    end
  end
end
1
2
import "@hotwired/turbo-rails"
import "controllers"
1
2
3
4
5
6
7
8
9
import { Application } from "@hotwired/stimulus"

const application = Application.start()

// Configure Stimulus development experience
application.debug = false
window.Stimulus = application

export { application }
1
2
3
4
// Import and register all your controllers from the importmap via controllers/**/*_controller
import { application } from "controllers/application"
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)
1
2
3
4
5
pin "application", to: "blorgh/application.js", 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 Blorgh::Engine.root.join("app/javascript/blorgh/controllers"), under: "controllers", to: "blorgh/controllers"
1
2
3
4
5
6
7
8
9
10
module Blorgh
  class Configuration
    attr_accessor :importmap

    def initialize
      @importmap = Importmap::Map.new
      @importmap.draw(Engine.root.join("config/importmap.rb"))
    end
  end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
require "blorgh/version"
require "blorgh/engine"
require "blorgh/configuration"

module Blorgh
  class << self
    attr_writer :configuration

    def configuration
      @configuration ||= Configuration.new
    end

    def configure
      yield(configuration) if block_given?
    end
  end
end
1
2
3
4
5
6
7
def blorgh_importmap_tags(entry_point = "application")
  safe_join [
    javascript_inline_importmap_tag(Blorgh.configuration.importmap.to_json(resolver: self)),
    javascript_importmap_module_preload_tags(Blorgh.configuration.importmap),
    javascript_import_module_tag(entry_point)
  ].compact, "\n"
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
  <head>
    <title>Blorgh</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= yield :head %>
    <%= stylesheet_link_tag    "blorgh/application", media: "all" %>
+   <%= blorgh_importmap_tags %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>
1
rails g controller home index
1
2
3
Blorgh::Engine.routes.draw do
  root "home#index"
end
1
2
3
4
5
6
7
8
9
10
11
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="engine"
export default class extends Controller {
  connect() {
    console.log("Connected")
    this.element.textContent = "Hello World! This is a Javascript from the Engine"
  }
}

console.log("Loaded")
1
2
<h1>Engine's Stimulus controller (Engine)</h1>
<div data-controller="engine"></div>

Create host app

1
rails new demo
1
gem "blorgh", path: "path/to/engine"
1
mount Blorgh::Engine => "/blorgh"

open browser: http://localhost:3000/blorgh

TailwindCSS configuration

1
spec.add_dependency "tailwindcss-rails"
1
<%= stylesheet_link_tag "blorgh", "data-turbo-track": "reload" %>
1
2
<h1 class="text-red-500">Engine's Stimulus controller (Engine)</h1>
<div data-controller="engine"></div>
1
cp $(bundle show tailwindcss-rails)/lib/install/tailwind.config.js config/tailwind.config.js
1
cp $(bundle show tailwindcss-rails)/lib/install/application.tailwind.css app/assets/stylesheets/blorgh/application.tailwind.css

Build engine Tailwind CSS

1
$(bundle show tailwindcss-ruby)/exe/tailwindcss -i app/assets/stylesheets/blorgh/application.tailwind.css -o app/assets/builds/blorgh.css -c config/tailwind.config.js --minify

Watch and build engine Tailwind CSS on file changes

1
$(bundle show tailwindcss-ruby)/exe/tailwindcss -i app/assets/stylesheets/blorgh/application.tailwind.css -o app/assets/builds/blorgh.css -c config/tailwind.config.js --minify -w

References

  • https://mariochavez.io/desarrollo/2023/08/23/working-with-rails-engines-importmap-tailwindcss/
  • https://stackoverflow.com/questions/71232601/how-to-use-tailwind-css-gem-in-a-rails-7-engine
This post is licensed under CC BY 4.0 by the author.