Enable caching in development, but discard on each request.
This is the same strategy as followed by ActionView. This prevents multiple recompiles during the same request Closes: #345
This commit is contained in:
Родитель
990b9bae7c
Коммит
f1215bec05
|
@ -1,5 +1,9 @@
|
|||
# master
|
||||
|
||||
* Cache components per-request in development, preventing unnecessary recompilation during a single request.
|
||||
|
||||
*Felipe Sateler*
|
||||
|
||||
# 2.8.0
|
||||
|
||||
* Add `before_render`, deprecating `before_render_check`.
|
||||
|
|
|
@ -778,10 +778,10 @@ ViewComponent is built by:
|
|||
|@blakewilliams|@seanpdoyle|@tclem|@nashby|@jaredcwhite|
|
||||
|Boston, MA|New York, NY|San Francisco, CA|Minsk|Portland, OR|
|
||||
|
||||
|<img src="https://avatars.githubusercontent.com/simonrand?s=256" alt="simonrand" width="128" />|<img src="https://avatars.githubusercontent.com/fugufish?s=256" alt="fugufish" width="128" />|<img src="https://avatars.githubusercontent.com/cover?s=256" alt="cover" width="128" />|<img src="https://avatars.githubusercontent.com/franks921?s=256" alt="franks921" width="128" />|
|
||||
|:---:|:---:|:---:|:---:|
|
||||
|@simonrand|@fugufish|@cover|@franks921|
|
||||
|Dublin, Ireland|Salt Lake City, Utah|Barcelona|South Africa|
|
||||
|<img src="https://avatars.githubusercontent.com/simonrand?s=256" alt="simonrand" width="128" />|<img src="https://avatars.githubusercontent.com/fugufish?s=256" alt="fugufish" width="128" />|<img src="https://avatars.githubusercontent.com/cover?s=256" alt="cover" width="128" />|<img src="https://avatars.githubusercontent.com/franks921?s=256" alt="franks921" width="128" />|<img src="https://avatars.githubusercontent.com/fsateler?s=256" alt="fsateler" width="128" />|
|
||||
|:---:|:---:|:---:|:---:|:---:|
|
||||
|@simonrand|@fugufish|@cover|@franks921|fsateler|
|
||||
|Dublin, Ireland|Salt Lake City, Utah|Barcelona|South Africa|Chile|
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ Incomplete test coverage
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
/app/controllers/view_components_controller.rb: 97.22% (missed: 49)
|
||||
/lib/view_component/base.rb: 97.75% (missed: 169,254,282,332)
|
||||
/lib/view_component/base.rb: 97.78% (missed: 170,253,281,331)
|
||||
/lib/view_component/preview.rb: 92.31% (missed: 32,42,78)
|
||||
/lib/view_component/render_to_string_monkey_patch.rb: 83.33% (missed: 9)
|
||||
/lib/view_component/test_helpers.rb: 95.45% (missed: 17)
|
||||
/test/view_component/integration_test.rb: 97.16% (missed: 14,15,16,18,20)
|
||||
/lib/view_component/test_helpers.rb: 95.65% (missed: 17)
|
||||
/test/view_component/integration_test.rb: 97.55% (missed: 14,15,16,18,20)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require "action_view"
|
||||
require "active_support/configurable"
|
||||
require "view_component/collection"
|
||||
require "view_component/compile_cache"
|
||||
require "view_component/previewable"
|
||||
|
||||
module ViewComponent
|
||||
|
@ -192,9 +193,7 @@ module ViewComponent
|
|||
end
|
||||
|
||||
def compiled?
|
||||
@compiled ||= false
|
||||
|
||||
@compiled && ActionView::Base.cache_template_loading
|
||||
CompileCache.compiled?(self)
|
||||
end
|
||||
|
||||
# Compile templates to instance methods, assuming they haven't been compiled already.
|
||||
|
@ -270,7 +269,7 @@ module ViewComponent
|
|||
RUBY
|
||||
end
|
||||
|
||||
@compiled = true
|
||||
CompileCache.register self
|
||||
end
|
||||
|
||||
# we'll eventually want to update this to support other types
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ViewComponent
|
||||
# Keeps track of which templates have already been compiled
|
||||
# This is not part of the public API
|
||||
module CompileCache
|
||||
mattr_accessor :cache, instance_reader: false, instance_accessor: false do
|
||||
Set.new
|
||||
end
|
||||
module_function
|
||||
|
||||
def register(klass)
|
||||
cache << klass
|
||||
end
|
||||
|
||||
def compiled?(klass)
|
||||
cache.include? klass
|
||||
end
|
||||
|
||||
def invalidate!
|
||||
cache.clear
|
||||
end
|
||||
end
|
||||
end
|
|
@ -69,6 +69,10 @@ module ViewComponent
|
|||
get "#{options.preview_route}/*path", to: "view_components#previews", as: :preview_view_component, internal: true
|
||||
end
|
||||
end
|
||||
|
||||
app.executor.to_run :before do
|
||||
CompileCache.invalidate! unless ActionView::Base.cache_template_loading
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,3 +30,14 @@ def with_preview_route(new_value)
|
|||
Rails.application.config.view_component.preview_route = old_value
|
||||
app.reloader.reload!
|
||||
end
|
||||
|
||||
def modify_file(file, content)
|
||||
filename = Rails.root.join(file)
|
||||
old_content = File.read(filename)
|
||||
begin
|
||||
File.open(filename, "wb+") { |f| f.write(content) }
|
||||
yield
|
||||
ensure
|
||||
File.open(filename, "wb+") { |f| f.write(old_content) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,6 +38,49 @@ class IntegrationTest < ActionDispatch::IntegrationTest
|
|||
assert_includes inline_response, baseline_response
|
||||
end
|
||||
|
||||
test "template changes are not reflected on new request when cache_template_loading is true" do
|
||||
# cache_template_loading is set to true on the initializer
|
||||
|
||||
get "/controller_inline"
|
||||
assert_select("div", "bar")
|
||||
assert_response :success
|
||||
|
||||
modify_file "app/components/controller_inline_component.html.erb", "<div>Goodbye world!</div>" do
|
||||
get "/controller_inline"
|
||||
assert_select("div", "bar")
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
get "/controller_inline"
|
||||
assert_select("div", "bar")
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "template changes are reflected on new request when cache_template_loading is false" do
|
||||
begin
|
||||
old_cache = ViewComponent::CompileCache.cache
|
||||
ViewComponent::CompileCache.cache = Set.new
|
||||
ActionView::Base.cache_template_loading = false
|
||||
|
||||
get "/controller_inline"
|
||||
assert_select("div", "bar")
|
||||
assert_response :success
|
||||
|
||||
modify_file "app/components/controller_inline_component.html.erb", "<div>Goodbye world!</div>" do
|
||||
get "/controller_inline"
|
||||
assert_select("div", "Goodbye world!")
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
get "/controller_inline"
|
||||
assert_select("div", "bar")
|
||||
assert_response :success
|
||||
ensure
|
||||
ActionView::Base.cache_template_loading = true
|
||||
ViewComponent::CompileCache.cache = old_cache
|
||||
end
|
||||
end
|
||||
|
||||
test "rendering component in a controller using #render_to_string" do
|
||||
get "/controller_inline_baseline"
|
||||
|
||||
|
|
|
@ -275,9 +275,7 @@ class ViewComponentTest < ViewComponent::TestCase
|
|||
assert_text(%r{http://assets.example.com/assets/application-\w+.css})
|
||||
end
|
||||
|
||||
def test_template_changes_are_not_reflected_in_production
|
||||
old_value = ActionView::Base.cache_template_loading
|
||||
ActionView::Base.cache_template_loading = true
|
||||
def test_template_changes_are_not_reflected_if_cache_is_not_cleared
|
||||
|
||||
render_inline(MyComponent.new)
|
||||
|
||||
|
@ -290,29 +288,6 @@ class ViewComponentTest < ViewComponent::TestCase
|
|||
end
|
||||
|
||||
render_inline(MyComponent.new)
|
||||
|
||||
ActionView::Base.cache_template_loading = old_value
|
||||
end
|
||||
|
||||
def test_template_changes_are_reflected_outside_production
|
||||
old_value = ActionView::Base.cache_template_loading
|
||||
ActionView::Base.cache_template_loading = false
|
||||
|
||||
render_inline(MyComponent.new)
|
||||
|
||||
assert_text("hello,world!")
|
||||
|
||||
modify_file "app/components/my_component.html.erb", "<div>Goodbye world!</div>" do
|
||||
render_inline(MyComponent.new)
|
||||
|
||||
assert_text("Goodbye world!")
|
||||
end
|
||||
|
||||
render_inline(MyComponent.new)
|
||||
|
||||
assert_text("hello,world!")
|
||||
|
||||
ActionView::Base.cache_template_loading = old_value
|
||||
end
|
||||
|
||||
def test_that_it_has_a_version_number
|
||||
|
@ -548,17 +523,4 @@ class ViewComponentTest < ViewComponent::TestCase
|
|||
|
||||
assert_match(/MissingDefaultCollectionParameterComponent initializer must accept `missing_default_collection_parameter` collection parameter/, exception.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def modify_file(file, content)
|
||||
filename = Rails.root.join(file)
|
||||
old_content = File.read(filename)
|
||||
begin
|
||||
File.open(filename, "wb+") { |f| f.write(content) }
|
||||
yield
|
||||
ensure
|
||||
File.open(filename, "wb+") { |f| f.write(old_content) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче