From 2af83b3d128a869a046e7158c56a713776f0431a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 19 Dec 2024 17:44:21 -0800 Subject: [PATCH 1/2] Encapsulate stale_when_importmap_changes --- README.md | 6 ++++-- app/controllers/concerns/importmap/freshness.rb | 5 +++++ lib/importmap/engine.rb | 7 +++++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 app/controllers/concerns/importmap/freshness.rb diff --git a/README.md b/README.md index f4c5bee..9828dcd 100644 --- a/README.md +++ b/README.md @@ -226,14 +226,16 @@ Import your module on the specific page. Note: you'll likely want to use a `cont ## Include a digest of the import map in your ETag -If you're using [ETags](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) generated by Rails helpers like `stale?` or `fresh_when`, you need to include the digest of the import map into this calculation. Otherwise your application will return [304](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304) cache responses even when your JavaScript assets have changed. You can avoid this with something like: +If you're using [ETags](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) generated by Rails helpers like `stale?` or `fresh_when`, you need to include the digest of the import map into this calculation. Otherwise your application will return [304](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304) cache responses even when your JavaScript assets have changed. You can avoid this using the `stale_when_importmap_changes` method: ```ruby class ApplicationController < ActionController::Base - etag { Rails.application.importmap.digest(resolver: helpers) if request.format&.html? } + stale_when_importmap_changes end ``` +This will add the digest of the importmap to the etag calculation when the request format is HTML. + ## Sweeping the cache in development and test diff --git a/app/controllers/concerns/importmap/freshness.rb b/app/controllers/concerns/importmap/freshness.rb new file mode 100644 index 0000000..0820a2f --- /dev/null +++ b/app/controllers/concerns/importmap/freshness.rb @@ -0,0 +1,5 @@ +module Importmap::Freshness + def stale_when_importmap_changes + etag { Rails.application.importmap.digest(resolver: helpers) if request.format&.html? } + end +end diff --git a/lib/importmap/engine.rb b/lib/importmap/engine.rb index 1c823f4..83e7471 100755 --- a/lib/importmap/engine.rb +++ b/lib/importmap/engine.rb @@ -48,6 +48,13 @@ class Engine < ::Rails::Engine end end + initializer "importmap.concerns" do + ActiveSupport.on_load(:action_controller_base) do + require_relative "../../app/controllers/concerns/importmap/freshness" + extend Importmap::Freshness + end + end + initializer "importmap.helpers" do ActiveSupport.on_load(:action_controller_base) do helper Importmap::ImportmapTagsHelper From df856d065435952e4842f4da46ea00a1766b859e Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Dec 2024 17:01:35 -0800 Subject: [PATCH 2/2] Use autoload instead of relative require --- app/controllers/{concerns => }/importmap/freshness.rb | 0 lib/importmap/engine.rb | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) rename app/controllers/{concerns => }/importmap/freshness.rb (100%) diff --git a/app/controllers/concerns/importmap/freshness.rb b/app/controllers/importmap/freshness.rb similarity index 100% rename from app/controllers/concerns/importmap/freshness.rb rename to app/controllers/importmap/freshness.rb diff --git a/lib/importmap/engine.rb b/lib/importmap/engine.rb index 83e7471..337c7fe 100755 --- a/lib/importmap/engine.rb +++ b/lib/importmap/engine.rb @@ -11,7 +11,7 @@ class Engine < ::Rails::Engine config.importmap.cache_sweepers = [] config.importmap.rescuable_asset_errors = [] - config.autoload_once_paths = %W( #{root}/app/helpers ) + config.autoload_once_paths = %W( #{root}/app/helpers #{root}/app/controllers ) initializer "importmap" do |app| app.importmap = Importmap::Map.new @@ -50,7 +50,6 @@ class Engine < ::Rails::Engine initializer "importmap.concerns" do ActiveSupport.on_load(:action_controller_base) do - require_relative "../../app/controllers/concerns/importmap/freshness" extend Importmap::Freshness end end