Skip to content

Commit

Permalink
Add Append StyleSheet Pack Tag Helper (#144)
Browse files Browse the repository at this point in the history
Added `append_stylesheet_pack_tag` helper required for ROR's new filesystem-based Component Registry API.
  • Loading branch information
pulkitkkr authored Jun 30, 2022
1 parent 3ba9970 commit 7bf7b0f
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 4 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,36 +249,42 @@ While this also generally applies to `stylesheet_pack_tag`, you may use multiple
<%= stylesheet_pack_tag 'print', media: 'print' %>
```

#### View Helper `append_javascript_pack_tag`
#### View Helper `append_javascript_pack_tag` and `append_stylesheet_pack_tag`

If you need configure your pack names from the view for a route or partials, then you will need some logic to ensure you call the helpers only once with multiple arguments. The new view helper `append_javascript_pack_tag` can solve this problem. This helper will queue up packs when the `javascript_pack_tag` is finally used.
If you need configure your script pack names or stylesheet pack names from the view for a route or partials, then you will need some logic to ensure you call the helpers only once with multiple arguments. The new view helpers, `append_javascript_pack_tag` and `append_stylesheet_pack_tag` can solve this problem. The helper `append_javascript_pack_tag` will queue up script packs when the `javascript_pack_tag` is finally used. Similarly,`append_stylesheet_pack_tag` will queue up style packs when the `stylesheet_pack_tag` is finally used.

Main view:
```erb
<% append_javascript_pack_tag 'calendar' %>
<% append_stylesheet_pack_tag 'calendar' %>
```

Some partial:
```erb
<% append_javascript_pack_tag 'map' %>
<% append_stylesheet_pack_tag 'map' %>
```

And the main layout has:
```erb
<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>
```

is the same as using this in the main layout:

```erb
<%= javascript_pack_tag 'calendar', 'map', application' %>
<%= stylesheet_pack_tag 'calendar', 'map', application' %>
```

However, you typically can't do that in the main layout, as the view and partial codes will depend on the route.

Thus, you can distribute the logic of what packs are needed for any route. All the magic of splitting up the code was automatic!
Thus, you can distribute the logic of what packs are needed for any route. All the magic of splitting up the code and CSS was automatic!

**Important:** `append_javascript_pack_tag` can be used anywhere in your application as long as it is executed BEFORE the `javascript_pack_tag`. If you attempt to call `append_javascript_pack_tag` helper after `javascript_pack_tag`, an error will be raised. You should have only a single `javascript_pack_tag` invocation in your page load.

**Important** Similar to `append_javascript_pack_tag`, the `append_stylesheet_pack_tag` should be used anywhere in your application as long as it is executed BEFORE the `stylesheet_pack_tag`. However, if you attempt to call `append_stylesheet_pack_tag` helper after `stylesheet_pack_tag`, an error will be **NOT** be raised.

The typical issue is that your layout might reference some partials that need to configure packs. A good way to solve this problem is to use `content_for` to ensure that the code to render your partial comes before the call to `javascript_pack_tag`.

Expand Down
21 changes: 20 additions & 1 deletion lib/webpacker/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,22 @@ def preload_pack_asset(name, **options)
def stylesheet_pack_tag(*names, **options)
return "" if Webpacker.inlining_css?

stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
requested_packs = sources_from_manifest_entrypoints(names, type: :stylesheet)
appended_packs = available_sources_from_manifest_entrypoints(@stylesheet_pack_tag_queue || [], type: :stylesheet)

@stylesheet_pack_tag_loaded = true

stylesheet_link_tag(*(requested_packs | appended_packs), **options)
end

def append_stylesheet_pack_tag(*names)
if @stylesheet_pack_tag_loaded
raise "You can only call append_stylesheet_pack_tag before stylesheet_pack_tag helper. " \
"Please refer to https://github.com/shakacode/shakapacker/blob/master/README.md#usage for the usage guide"
end

@stylesheet_pack_tag_queue ||= []
@stylesheet_pack_tag_queue.concat names
end

def append_javascript_pack_tag(*names, defer: true)
Expand All @@ -184,6 +199,10 @@ def sources_from_manifest_entrypoints(names, type:)
names.map { |name| current_webpacker_instance.manifest.lookup_pack_with_chunks!(name.to_s, type: type) }.flatten.uniq
end

def available_sources_from_manifest_entrypoints(names, type:)
names.map { |name| current_webpacker_instance.manifest.lookup_pack_with_chunks(name.to_s, type: type) }.flatten.compact.uniq
end

def resolve_path_to_image(name, **options)
path = name.starts_with?("static/") ? name : "static/#{name}"
path_to_asset(current_webpacker_instance.manifest.lookup!(path), options)
Expand Down
40 changes: 40 additions & 0 deletions test/helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,5 +204,45 @@ def test_stylesheet_pack_tag_multiple_invocations_are_allowed
assert_equal \
hello_stimulus_stylesheet_chunks.map { |chunk| stylesheet_link_tag(chunk) }.join("\n"),
stimulus_style

assert_nothing_raised do
stylesheet_pack_tag(:application)
stylesheet_pack_tag(:hello_stimulus)
end
end

def test_stylesheet_pack_with_append
append_stylesheet_pack_tag(:hello_stimulus)

assert_equal \
(application_stylesheet_chunks + hello_stimulus_stylesheet_chunks).uniq.map { |chunk| stylesheet_link_tag(chunk) }.join("\n"),
stylesheet_pack_tag(:application)
end

def test_stylesheet_pack_with_duplicate_append
append_stylesheet_pack_tag(:hello_stimulus)
append_stylesheet_pack_tag(:application)

assert_equal \
(application_stylesheet_chunks + hello_stimulus_stylesheet_chunks).uniq.map { |chunk| stylesheet_link_tag(chunk) }.join("\n"),
stylesheet_pack_tag(:application)
end

def test_multiple_stylesheet_pack_with_different_media_attr
app_style = stylesheet_pack_tag(:application)
app_style_with_media = stylesheet_pack_tag(:application, media: "print")
hello_stimulus_style_with_media = stylesheet_pack_tag(:hello_stimulus, media: "all")

assert_equal \
application_stylesheet_chunks.map { |chunk| stylesheet_link_tag(chunk) }.join("\n"),
app_style

assert_equal \
application_stylesheet_chunks.map { |chunk| stylesheet_link_tag(chunk, media: "print") }.join("\n"),
app_style_with_media

assert_equal \
hello_stimulus_stylesheet_chunks.map { |chunk| stylesheet_link_tag(chunk, media: "all") }.join("\n"),
hello_stimulus_style_with_media
end
end

0 comments on commit 7bf7b0f

Please sign in to comment.