From 60a6c5a5401f1961a825db6a534438e1e214573a Mon Sep 17 00:00:00 2001 From: Dan Laffan Date: Wed, 20 Oct 2021 15:57:52 +0100 Subject: [PATCH 1/7] Added a new section to the README for engine builders --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f9a917b..bc4b0f8 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ There's [native support for import maps in Chrome/Edge 89+](https://caniuse.com/ ## Installation +### a) Rails apps + Importmap for Rails is automatically included in Rails 7+ for new applications, but you can also install it manually in existing applications: 1. Add `importmap-rails` to your Gemfile with `gem 'importmap-rails'` @@ -17,12 +19,22 @@ Importmap for Rails is automatically included in Rails 7+ for new applications, Note: In order to use JavaScript from Rails frameworks like Action Cable, Action Text, and Active Storage, you must be running Rails 7.0+. This was the first version that shipped with ESM compatible builds of these libraries. +### b) Rails engines + +Importmap for Rails is automatically included in Rails 7+ for new applications, but you can also install it manually in existing applications: + +1. Add `importmap-rails` to your Gemfile with `gem 'importmap-rails'` +2. Run `./bin/bundle install` +3. Run `./bin/rails app:importmap:install` + +Note: In order to use JavaScript from Rails frameworks like Action Cable, Action Text, and Active Storage, you must be running Rails 7.0+. This was the first version that shipped with ESM compatible builds of these libraries. + ## Usage The import map is setup through `Rails.application.importmap` via the configuration in `config/importmap.rb`. This file is automatically reloaded in development upon changes, but note that you must restart the server if you remove pins and need them gone from the rendered importmap or list of preloads. -This import map is inlined in the `` of your application layout using `<%= javascript_importmap_tags %>`, which will setup the JSON configuration inside a ``. That logical entrypoint, `application`, is mapped in the importmap script tag to the file `app/javascript/application.js`. +This import map is inlined in the `` of your application layout using `<%= javascript_importmap_tags %>`, which will set up the JSON configuration inside a ``. That logical entrypoint, `application`, is mapped in the importmap script tag to the file `app/javascript/application.js`. It's in `app/javascript/application.js` you setup your application by importing any of the modules that have been defined in the import map. You can use the full ESM functionality of importing any particular export of the modules or everything. From a77ffb0a2db05e86f47fdd5b50767674428bd402 Mon Sep 17 00:00:00 2001 From: Dan Laffan Date: Wed, 20 Oct 2021 15:58:16 +0100 Subject: [PATCH 2/7] Removed trailing spaces --- app/helpers/importmap/importmap_tags_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/importmap/importmap_tags_helper.rb b/app/helpers/importmap/importmap_tags_helper.rb index d249f3b..737d8d5 100644 --- a/app/helpers/importmap/importmap_tags_helper.rb +++ b/app/helpers/importmap/importmap_tags_helper.rb @@ -20,7 +20,7 @@ def javascript_inline_importmap_tag(importmap_json = Rails.application.importmap # Configure es-modules-shim with nonce support if the application is using a content security policy. def javascript_importmap_shim_nonce_configuration_tag if content_security_policy? - tag.script({ nonce: content_security_policy_nonce }.to_json.html_safe, + tag.script({ nonce: content_security_policy_nonce }.to_json.html_safe, type: "esms-options", nonce: content_security_policy_nonce) end end @@ -34,7 +34,7 @@ def javascript_importmap_shim_tag(minimized: true) # Import a named JavaScript module(s) using a script-module tag. def javascript_import_module_tag(*module_names) imports = Array(module_names).collect { |m| %(import "#{m}") }.join("\n") - tag.script imports.html_safe, + tag.script imports.html_safe, type: "module", nonce: content_security_policy_nonce end From b689e79ff57b5847e3aa48b7e8b605c91e29d5e1 Mon Sep 17 00:00:00 2001 From: Dan Laffan Date: Wed, 20 Oct 2021 16:08:07 +0100 Subject: [PATCH 3/7] Fix to enable namespace to be used in calling app:template --- lib/tasks/importmap_tasks.rake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/tasks/importmap_tasks.rake b/lib/tasks/importmap_tasks.rake index bb8c550..a5d90ff 100644 --- a/lib/tasks/importmap_tasks.rake +++ b/lib/tasks/importmap_tasks.rake @@ -1,6 +1,7 @@ namespace :importmap do desc "Setup Importmap for the app" - task :install do - system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/install.rb", __dir__)}" + task :install do |task| + namespace = task.name.split(/turbo:install/).first + system "#{RbConfig.ruby} ./bin/rails #{namespace}app:template LOCATION=#{File.expand_path("../install/install.rb", __dir__)}" end end From 397ab7653ed84e4937fab5a59e38a1e02720a127 Mon Sep 17 00:00:00 2001 From: Dan Laffan Date: Wed, 20 Oct 2021 16:14:31 +0100 Subject: [PATCH 4/7] Fixed typo --- lib/tasks/importmap_tasks.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/importmap_tasks.rake b/lib/tasks/importmap_tasks.rake index a5d90ff..9b57d31 100644 --- a/lib/tasks/importmap_tasks.rake +++ b/lib/tasks/importmap_tasks.rake @@ -1,7 +1,7 @@ namespace :importmap do desc "Setup Importmap for the app" task :install do |task| - namespace = task.name.split(/turbo:install/).first + namespace = task.name.split(/installmap:install/).first system "#{RbConfig.ruby} ./bin/rails #{namespace}app:template LOCATION=#{File.expand_path("../install/install.rb", __dir__)}" end end From 82c9fa2d4d8a98b3c7c017c0a528851d71f20bf8 Mon Sep 17 00:00:00 2001 From: Dan Laffan Date: Wed, 20 Oct 2021 16:18:35 +0100 Subject: [PATCH 5/7] Fixed typo again --- lib/tasks/importmap_tasks.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/importmap_tasks.rake b/lib/tasks/importmap_tasks.rake index 9b57d31..14e67a6 100644 --- a/lib/tasks/importmap_tasks.rake +++ b/lib/tasks/importmap_tasks.rake @@ -1,7 +1,7 @@ namespace :importmap do desc "Setup Importmap for the app" task :install do |task| - namespace = task.name.split(/installmap:install/).first + namespace = task.name.split(/importmap:install/).first system "#{RbConfig.ruby} ./bin/rails #{namespace}app:template LOCATION=#{File.expand_path("../install/install.rb", __dir__)}" end end From 256f975f8d78bc6e49ad5db7b8cb6e0ecb35908b Mon Sep 17 00:00:00 2001 From: Dan Laffan Date: Wed, 20 Oct 2021 20:10:45 +0100 Subject: [PATCH 6/7] Enable install.rb to handle Rails engines --- lib/install/install.rb | 44 ++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/install/install.rb b/lib/install/install.rb index 03d8dcc..64ace6c 100644 --- a/lib/install/install.rb +++ b/lib/install/install.rb @@ -1,32 +1,46 @@ -APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.erb") - -if APPLICATION_LAYOUT_PATH.exist? - say "Add Importmap include tags in application layout" - insert_into_file APPLICATION_LAYOUT_PATH.to_s, "\n <%= javascript_importmap_tags %>", before: /\s*<\/head>/ -else - say "Default application.html.erb is missing!", :red - say " Add <%= javascript_importmap_tags %> within the tag in your custom layout." +# frozen_string_literal: true + +# This file is called by +lib/tasks/importmap_tasks.rake+. + +rails_root = Pathname.new(Rails.root.to_s.split(%r{\/(spec|test)\/dummy}).first) +say "Adding configuration for the importmap-rails gem into: #{rails_root}" + +Dir.glob("#{rails_root}/**/application.html.*").each do |layout_path| + say "Add Importmap include tags in application layout file at #{layout_path}" + spaces = IO.foreach(layout_path).grep(/(\s*)body/).first.match(/(\s*)/)[1] + case layout_path.split('.html.').last + when 'erb' + insert_into_file layout_path.to_s, "\n#{spaces} <%= javascript_importmap_tags %>", before: /\s*<\/head>/ + when 'slim' + insert_into_file layout_path.to_s, "\n#{spaces} = javascript_importmap_tags", before: /\s*body/ + when 'haml' + insert_into_file layout_path.to_s, "\n#{spaces} =javascript_importmap_tags", before: /\s*%body/ + else + say "Couldn't find an application.html.erb|haml|slim file!", :red + say " Add <%= javascript_importmap_tags %> within the tag into your custom layout." + end end say "Create application.js module as entrypoint" -create_file Rails.root.join("app/javascript/application.js") do <<-JS +create_file rails_root.join("app/javascript/application.js") do <<-JS // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails JS end say "Use vendor/javascript for downloaded pins" -empty_directory "vendor/javascript" -keep_file "vendor/javascript" +empty_directory rails_root.join("vendor/javascript") +keep_file rails_root.join("vendor/javascript") -if (sprockets_manifest_path = Rails.root.join("app/assets/config/manifest.js")).exist? +sprockets_manifest_path = rails_root.join("app/assets/config/manifest.js") +if sprockets_manifest_path.exist? say "Ensure JavaScript files are in the Sprocket manifest" append_to_file sprockets_manifest_path, %(//= link_tree ../../javascript .js\n//= link_tree ../../../vendor/javascript .js\n) end say "Configure importmap paths in config/importmap.rb" -copy_file "#{__dir__}/config/importmap.rb", "config/importmap.rb" +copy_file "#{__dir__}/config/importmap.rb", rails_root.join("config/importmap.rb") say "Copying binstub" -copy_file "#{__dir__}/bin/importmap", "bin/importmap" -chmod "bin", 0755 & ~File.umask, verbose: false +copy_file "#{__dir__}/bin/importmap", rails_root.join("bin/importmap") +chmod rails_root.join("bin"), 0755 & ~File.umask, verbose: false From e588eb02cbb2d34adbb3d886f413538dd43b194f Mon Sep 17 00:00:00 2001 From: Dan Laffan Date: Wed, 20 Oct 2021 20:11:42 +0100 Subject: [PATCH 7/7] Updated the readme with instructions for installation into Engines --- README.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bc4b0f8..b67eb23 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ There's [native support for import maps in Chrome/Edge 89+](https://caniuse.com/ ## Installation +Note: In order to use JavaScript from Rails frameworks like Action Cable, Action Text, and Active Storage, you must be running Rails 7.0+. This was the first version that shipped with ESM compatible builds of these libraries. + ### a) Rails apps Importmap for Rails is automatically included in Rails 7+ for new applications, but you can also install it manually in existing applications: @@ -17,17 +19,27 @@ Importmap for Rails is automatically included in Rails 7+ for new applications, 2. Run `./bin/bundle install` 3. Run `./bin/rails importmap:install` -Note: In order to use JavaScript from Rails frameworks like Action Cable, Action Text, and Active Storage, you must be running Rails 7.0+. This was the first version that shipped with ESM compatible builds of these libraries. - ### b) Rails engines -Importmap for Rails is automatically included in Rails 7+ for new applications, but you can also install it manually in existing applications: - -1. Add `importmap-rails` to your Gemfile with `gem 'importmap-rails'` -2. Run `./bin/bundle install` -3. Run `./bin/rails app:importmap:install` - -Note: In order to use JavaScript from Rails frameworks like Action Cable, Action Text, and Active Storage, you must be running Rails 7.0+. This was the first version that shipped with ESM compatible builds of these libraries. +This gem behaves differently when it is loaded into a Rails Engine. We assume that you wish to load the gem's behaviour into the Engine's codebase rather than loading it into the **dummy** application's codebase. You may wish to copy the changes that the installer makes into the **dummy** application. + +Importmap for Rails is automatically included in Rails 7+ for new engines, but you can also install it manually in existing engines: + +1. In your `.gemspec` file, add the following: + ```ruby + spec.add_dependency 'importmap-rails' + ``` +2. Near the top of your `lib//engine.rb` file, add the following: + ```ruby + require 'importmap-rails' + ``` +3. If you wish to load a non-standard version of this gem, such as the latest unreleased version in the **main** + branch, add the following to your `Gemfile`: + ```ruby + gem 'importmap-rails' + ``` +4. Run `./bin/bundle install` +5. Run `./bin/rails app:importmap:install`. Please note the addition of `app:` in this command. ## Usage