Skip to content

Commit e54fd54

Browse files
authored
Allows preload to be determined by provided entry_point (#253)
* Allows preload to be determined by provided entry_point * entry point defaults and fix * Tests for various preload values * Update README.md
1 parent 11e59ae commit e54fd54

File tree

4 files changed

+52
-8
lines changed

4 files changed

+52
-8
lines changed

Diff for: README.md

+19
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,25 @@ pin "md5", preload: false # file lives in vendor/javascript/md5.js
141141
...
142142
```
143143

144+
You can also specify which entry points to preload a particular dependency in by providing `preload:` a string or array of strings.
145+
146+
Example:
147+
148+
```ruby
149+
# config/importmap.rb
150+
pin "@github/hotkey", to: "@github--hotkey.js", preload: 'application'
151+
pin "md5", preload: ['application', 'alternate']
152+
153+
# app/views/layouts/application.html.erb
154+
<%= javascript_importmap_tags 'alternate' %>
155+
156+
# will include the following link before the importmap is setup:
157+
<link rel="modulepreload" href="/assets/javascript/md5.js">
158+
...
159+
```
160+
161+
162+
144163
## Composing import maps
145164

146165
By default, Rails loads import map definition from the application's `config/importmap.rb` to the `Importmap::Map` object available at `Rails.application.importmap`.

Diff for: app/helpers/importmap/importmap_tags_helper.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Importmap::ImportmapTagsHelper
33
def javascript_importmap_tags(entry_point = "application", importmap: Rails.application.importmap)
44
safe_join [
55
javascript_inline_importmap_tag(importmap.to_json(resolver: self)),
6-
javascript_importmap_module_preload_tags(importmap),
6+
javascript_importmap_module_preload_tags(importmap, entry_point:),
77
javascript_import_module_tag(entry_point)
88
], "\n"
99
end
@@ -24,8 +24,8 @@ def javascript_import_module_tag(*module_names)
2424
# Link tags for preloading all modules marked as preload: true in the `importmap`
2525
# (defaults to Rails.application.importmap), such that they'll be fetched
2626
# in advance by browsers supporting this link type (https://caniuse.com/?search=modulepreload).
27-
def javascript_importmap_module_preload_tags(importmap = Rails.application.importmap)
28-
javascript_module_preload_tag(*importmap.preloaded_module_paths(resolver: self))
27+
def javascript_importmap_module_preload_tags(importmap = Rails.application.importmap, entry_point: "application")
28+
javascript_module_preload_tag(*importmap.preloaded_module_paths(resolver: self, entry_point:))
2929
end
3030

3131
# Link tag(s) for preloading the JavaScript module residing in `*paths`. Will return one link tag per path element.

Diff for: lib/importmap/map.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ def pin_all_from(dir, under: nil, to: nil, preload: true)
4040
# resolver that has been configured for the `asset_host` you want these resolved paths to use. In case you need to
4141
# resolve for different asset hosts, you can pass in a custom `cache_key` to vary the cache used by this method for
4242
# the different cases.
43-
def preloaded_module_paths(resolver:, cache_key: :preloaded_module_paths)
43+
def preloaded_module_paths(resolver:, entry_point: "application", cache_key: :preloaded_module_paths)
4444
cache_as(cache_key) do
45-
resolve_asset_paths(expanded_preloading_packages_and_directories, resolver: resolver).values
45+
resolve_asset_paths(expanded_preloading_packages_and_directories(entry_point:), resolver:).values
4646
end
4747
end
4848

@@ -118,8 +118,8 @@ def resolve_asset_paths(paths, resolver:)
118118
end.compact
119119
end
120120

121-
def expanded_preloading_packages_and_directories
122-
expanded_packages_and_directories.select { |name, mapping| mapping.preload }
121+
def expanded_preloading_packages_and_directories(entry_point:)
122+
expanded_packages_and_directories.select { |name, mapping| mapping.preload.in?([true, false]) ? mapping.preload : (Array(mapping.preload) & Array(entry_point)).any? }
123123
end
124124

125125
def expanded_packages_and_directories

Diff for: test/importmap_test.rb

+26-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ def setup
88
pin "editor", to: "rich_text.js", preload: false
99
pin "not_there", to: "nowhere.js", preload: false
1010
pin "md5", to: "https://cdn.skypack.dev/md5", preload: true
11+
pin "leaflet", to: "https://cdn.skypack.dev/leaflet", preload: 'application'
12+
pin "chartkick", to: "https://cdn.skypack.dev/chartkick", preload: ['application', 'alternate']
13+
pin "tinyMCE", to: "https://cdn.skypack.dev/tinymce", preload: 'alternate'
1114

1215
pin_all_from "app/javascript/controllers", under: "controllers", preload: true
1316
pin_all_from "app/javascript/spina/controllers", under: "controllers/spina", preload: true
@@ -78,10 +81,32 @@ def setup
7881
end
7982
end
8083

81-
test "preloaded modules are included in preload tags" do
84+
test "preloaded modules are included in preload tags when no entry_point specified" do
8285
preloading_module_paths = @importmap.preloaded_module_paths(resolver: ApplicationController.helpers).to_s
8386
assert_match /md5/, preloading_module_paths
8487
assert_match /goodbye_controller/, preloading_module_paths
88+
assert_match /leaflet/, preloading_module_paths
89+
assert_no_match /application/, preloading_module_paths
90+
assert_no_match /tinymce/, preloading_module_paths
91+
end
92+
93+
test "preloaded modules are included in preload tags based on single entry_point provided" do
94+
preloading_module_paths = @importmap.preloaded_module_paths(resolver: ApplicationController.helpers, entry_point: "alternate").to_s
95+
assert_no_match /leaflet/, preloading_module_paths
96+
assert_match /tinymce/, preloading_module_paths
97+
assert_match /chartkick/, preloading_module_paths
98+
assert_match /md5/, preloading_module_paths
99+
assert_match /goodbye_controller/, preloading_module_paths
100+
assert_no_match /application/, preloading_module_paths
101+
end
102+
103+
test "preloaded modules are included in preload tags based on multiple entry_points provided" do
104+
preloading_module_paths = @importmap.preloaded_module_paths(resolver: ApplicationController.helpers, entry_point: ["application", "alternate"]).to_s
105+
assert_match /leaflet/, preloading_module_paths
106+
assert_match /tinymce/, preloading_module_paths
107+
assert_match /chartkick/, preloading_module_paths
108+
assert_match /md5/, preloading_module_paths
109+
assert_match /goodbye_controller/, preloading_module_paths
85110
assert_no_match /application/, preloading_module_paths
86111
end
87112

0 commit comments

Comments
 (0)