importmap-rails 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +32 -2
- data/app/controllers/importmap/freshness.rb +5 -0
- data/app/helpers/importmap/importmap_tags_helper.rb +3 -3
- data/lib/importmap/commands.rb +19 -1
- data/lib/importmap/engine.rb +7 -1
- data/lib/importmap/map.rb +15 -5
- data/lib/importmap/npm.rb +1 -1
- data/lib/importmap/packager.rb +11 -5
- data/lib/importmap/version.rb +1 -1
- data/lib/tasks/importmap_tasks.rake +4 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24bbd66810fcdeffe321841aa86a4308b0fa76749e9ec20105f8d74475634aa7
|
4
|
+
data.tar.gz: ea19b79e7701a7aafd6fe546edc88880aa5e68858999959d8e52005ce0be5a34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 741aab3cb6747eba7daf39dd5d311c126dfccfb55132c68d1e1cdaafe2b84a9e2596ea4746446cf6f1702d851a109cae3413b97a233889cd8855e347098ee592
|
7
|
+
data.tar.gz: 3b9ed94a737134bbfcd8be54f95fa5094539b2b6d56b7365362bdf7ac961bb1e727cef396eca0001629d45e2c50578c3af819559a521829f41b4e875733d3e80
|
data/README.md
CHANGED
@@ -141,6 +141,25 @@ pin "md5", preload: false # file lives in vendor/javascript/md5.js
|
|
141
141
|
...
|
142
142
|
```
|
143
143
|
|
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
|
+
|
144
163
|
## Composing import maps
|
145
164
|
|
146
165
|
By default, Rails loads import map definition from the application's `config/importmap.rb` to the `Importmap::Map` object available at `Rails.application.importmap`.
|
@@ -207,14 +226,16 @@ Import your module on the specific page. Note: you'll likely want to use a `cont
|
|
207
226
|
|
208
227
|
## Include a digest of the import map in your ETag
|
209
228
|
|
210
|
-
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
|
229
|
+
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:
|
211
230
|
|
212
231
|
```ruby
|
213
232
|
class ApplicationController < ActionController::Base
|
214
|
-
|
233
|
+
stale_when_importmap_changes
|
215
234
|
end
|
216
235
|
```
|
217
236
|
|
237
|
+
This will add the digest of the importmap to the etag calculation when the request format is HTML.
|
238
|
+
|
218
239
|
|
219
240
|
## Sweeping the cache in development and test
|
220
241
|
|
@@ -242,6 +263,15 @@ Importmap for Rails provides two commands to check your pinned packages:
|
|
242
263
|
- `./bin/importmap outdated` checks the NPM registry for new versions
|
243
264
|
- `./bin/importmap audit` checks the NPM registry for known security issues
|
244
265
|
|
266
|
+
## Supporting legacy browsers such as Safari on iOS 15
|
267
|
+
|
268
|
+
If you want to support [legacy browsers that do not support import maps](https://caniuse.com/import-maps) such as [iOS 15.8.1 released on 22 Jan 2024](https://support.apple.com/en-us/HT201222), insert [`es-module-shims`](https://github.com/guybedford/es-module-shims) before `javascript_importmap_tags` as below.
|
269
|
+
|
270
|
+
```erb
|
271
|
+
<script async src="https://ga.jspm.io/npm:es-module-shims@1.8.2/dist/es-module-shims.js" data-turbo-track="reload"></script>
|
272
|
+
<%= javascript_importmap_tags %>
|
273
|
+
```
|
274
|
+
|
245
275
|
## License
|
246
276
|
|
247
277
|
Importmap for Rails is released under the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -3,7 +3,7 @@ module Importmap::ImportmapTagsHelper
|
|
3
3
|
def javascript_importmap_tags(entry_point = "application", importmap: Rails.application.importmap)
|
4
4
|
safe_join [
|
5
5
|
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:),
|
7
7
|
javascript_import_module_tag(entry_point)
|
8
8
|
], "\n"
|
9
9
|
end
|
@@ -24,8 +24,8 @@ module Importmap::ImportmapTagsHelper
|
|
24
24
|
# Link tags for preloading all modules marked as preload: true in the `importmap`
|
25
25
|
# (defaults to Rails.application.importmap), such that they'll be fetched
|
26
26
|
# 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:, cache_key: entry_point))
|
29
29
|
end
|
30
30
|
|
31
31
|
# Link tag(s) for preloading the JavaScript module residing in `*paths`. Will return one link tag per path element.
|
data/lib/importmap/commands.rb
CHANGED
@@ -46,6 +46,24 @@ class Importmap::Commands < Thor
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
desc "pristine", "Redownload all pinned packages"
|
50
|
+
option :env, type: :string, aliases: :e, default: "production"
|
51
|
+
option :from, type: :string, aliases: :f, default: "jspm"
|
52
|
+
def pristine
|
53
|
+
packages = npm.packages_with_versions.map do |p, v|
|
54
|
+
v.blank? ? p : [p, v].join("@")
|
55
|
+
end
|
56
|
+
|
57
|
+
if imports = packager.import(*packages, env: options[:env], from: options[:from])
|
58
|
+
imports.each do |package, url|
|
59
|
+
puts %(Downloading "#{package}" to #{packager.vendor_path}/#{package}.js from #{url})
|
60
|
+
packager.download(package, url)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
puts "Couldn't find any packages in #{packages.inspect} on #{options[:from]}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
49
67
|
desc "json", "Show the full importmap in json"
|
50
68
|
def json
|
51
69
|
require Rails.root.join("config/environment")
|
@@ -92,7 +110,7 @@ class Importmap::Commands < Thor
|
|
92
110
|
desc "update", "Update outdated package pins"
|
93
111
|
def update
|
94
112
|
if (outdated_packages = npm.outdated_packages).any?
|
95
|
-
pin
|
113
|
+
pin(*outdated_packages.map(&:name))
|
96
114
|
else
|
97
115
|
puts "No outdated packages found"
|
98
116
|
end
|
data/lib/importmap/engine.rb
CHANGED
@@ -11,7 +11,7 @@ module Importmap
|
|
11
11
|
config.importmap.cache_sweepers = []
|
12
12
|
config.importmap.rescuable_asset_errors = []
|
13
13
|
|
14
|
-
config.autoload_once_paths = %W( #{root}/app/helpers )
|
14
|
+
config.autoload_once_paths = %W( #{root}/app/helpers #{root}/app/controllers )
|
15
15
|
|
16
16
|
initializer "importmap" do |app|
|
17
17
|
app.importmap = Importmap::Map.new
|
@@ -48,6 +48,12 @@ module Importmap
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
initializer "importmap.concerns" do
|
52
|
+
ActiveSupport.on_load(:action_controller_base) do
|
53
|
+
extend Importmap::Freshness
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
51
57
|
initializer "importmap.helpers" do
|
52
58
|
ActiveSupport.on_load(:action_controller_base) do
|
53
59
|
helper Importmap::ImportmapTagsHelper
|
data/lib/importmap/map.rb
CHANGED
@@ -40,9 +40,9 @@ class Importmap::Map
|
|
40
40
|
# resolver that has been configured for the `asset_host` you want these resolved paths to use. In case you need to
|
41
41
|
# resolve for different asset hosts, you can pass in a custom `cache_key` to vary the cache used by this method for
|
42
42
|
# 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)
|
44
44
|
cache_as(cache_key) do
|
45
|
-
resolve_asset_paths(expanded_preloading_packages_and_directories, resolver:
|
45
|
+
resolve_asset_paths(expanded_preloading_packages_and_directories(entry_point:), resolver:).values
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -118,8 +118,8 @@ class Importmap::Map
|
|
118
118
|
end.compact
|
119
119
|
end
|
120
120
|
|
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? }
|
123
123
|
end
|
124
124
|
|
125
125
|
def expanded_packages_and_directories
|
@@ -141,7 +141,17 @@ class Importmap::Map
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def module_name_from(filename, mapping)
|
144
|
-
|
144
|
+
# Regex explanation:
|
145
|
+
# (?:\/|^) # Matches either / OR the start of the string
|
146
|
+
# index # Matches the word index
|
147
|
+
# $ # Matches the end of the string
|
148
|
+
#
|
149
|
+
# Sample matches
|
150
|
+
# index
|
151
|
+
# folder/index
|
152
|
+
index_regex = /(?:\/|^)index$/
|
153
|
+
|
154
|
+
[ mapping.under, filename.to_s.remove(filename.extname).remove(index_regex).presence ].compact.join("/")
|
145
155
|
end
|
146
156
|
|
147
157
|
def module_path_from(filename, mapping)
|
data/lib/importmap/npm.rb
CHANGED
@@ -86,7 +86,7 @@ class Importmap::Npm
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def find_latest_version(response)
|
89
|
-
latest_version = response.dig('dist-tags', 'latest')
|
89
|
+
latest_version = response.is_a?(String) ? response : response.dig('dist-tags', 'latest')
|
90
90
|
return latest_version if latest_version
|
91
91
|
|
92
92
|
return unless response['versions']
|
data/lib/importmap/packager.rb
CHANGED
@@ -19,10 +19,10 @@ class Importmap::Packager
|
|
19
19
|
|
20
20
|
def import(*packages, env: "production", from: "jspm")
|
21
21
|
response = post_json({
|
22
|
-
"install" => Array(packages),
|
22
|
+
"install" => Array(packages),
|
23
23
|
"flattenScope" => true,
|
24
24
|
"env" => [ "browser", "module", env ],
|
25
|
-
"provider" => from
|
25
|
+
"provider" => normalize_provider(from)
|
26
26
|
})
|
27
27
|
|
28
28
|
case response.code
|
@@ -69,6 +69,10 @@ class Importmap::Packager
|
|
69
69
|
raise HTTPError, "Unexpected transport error (#{error.class}: #{error.message})"
|
70
70
|
end
|
71
71
|
|
72
|
+
def normalize_provider(name)
|
73
|
+
name.to_s == "jspm" ? "jspm.io" : name.to_s
|
74
|
+
end
|
75
|
+
|
72
76
|
def extract_parsed_imports(response)
|
73
77
|
JSON.parse(response.body).dig("map", "imports")
|
74
78
|
end
|
@@ -80,7 +84,7 @@ class Importmap::Packager
|
|
80
84
|
raise HTTPError, "Unexpected response code (#{response.code})"
|
81
85
|
end
|
82
86
|
end
|
83
|
-
|
87
|
+
|
84
88
|
def parse_service_error(response)
|
85
89
|
JSON.parse(response.body.to_s)["error"]
|
86
90
|
rescue JSON::ParserError
|
@@ -113,14 +117,16 @@ class Importmap::Packager
|
|
113
117
|
response = Net::HTTP.get_response(URI(url))
|
114
118
|
|
115
119
|
if response.code == "200"
|
116
|
-
save_vendored_package(package, response.body)
|
120
|
+
save_vendored_package(package, url, response.body)
|
117
121
|
else
|
118
122
|
handle_failure_response(response)
|
119
123
|
end
|
120
124
|
end
|
121
125
|
|
122
|
-
def save_vendored_package(package, source)
|
126
|
+
def save_vendored_package(package, url, source)
|
123
127
|
File.open(vendored_package_path(package), "w+") do |vendored_package|
|
128
|
+
vendored_package.write "// #{package}#{extract_package_version_from(url)} downloaded from #{url}\n\n"
|
129
|
+
|
124
130
|
vendored_package.write remove_sourcemap_comment_from(source).force_encoding("UTF-8")
|
125
131
|
end
|
126
132
|
end
|
data/lib/importmap/version.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
namespace :importmap do
|
2
2
|
desc "Setup Importmap for the app"
|
3
3
|
task :install do
|
4
|
-
|
4
|
+
previous_location = ENV["LOCATION"]
|
5
|
+
ENV["LOCATION"] = File.expand_path("../install/install.rb", __dir__)
|
6
|
+
Rake::Task["app:template"].invoke
|
7
|
+
ENV["LOCATION"] = previous_location
|
5
8
|
end
|
6
9
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: importmap-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- MIT-LICENSE
|
62
62
|
- README.md
|
63
63
|
- Rakefile
|
64
|
+
- app/controllers/importmap/freshness.rb
|
64
65
|
- app/helpers/importmap/importmap_tags_helper.rb
|
65
66
|
- lib/importmap-rails.rb
|
66
67
|
- lib/importmap/commands.rb
|
@@ -88,14 +89,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
89
|
requirements:
|
89
90
|
- - ">="
|
90
91
|
- !ruby/object:Gem::Version
|
91
|
-
version:
|
92
|
+
version: 3.1.0
|
92
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
94
|
requirements:
|
94
95
|
- - ">="
|
95
96
|
- !ruby/object:Gem::Version
|
96
97
|
version: '0'
|
97
98
|
requirements: []
|
98
|
-
rubygems_version: 3.
|
99
|
+
rubygems_version: 3.5.22
|
99
100
|
signing_key:
|
100
101
|
specification_version: 4
|
101
102
|
summary: Use ESM with importmap to manage modern JavaScript in Rails without transpiling
|