发布于 2026-01-06 0 阅读
0

Rails 将引入视图组件,并支持第三方组件框架 #36388

Rails 将引入视图组件

引入对第三方组件框架的支持 #36388

引入对第三方组件框架的支持

在等待最新 PR 的测试通过期间,我决定查看一下邮箱。我订阅了一个 Ruby 新闻邮件列表,看到了一个有趣的标题:“ActionView::Component 简介:视图组件即将登陆 Rails?”标题中包含一个指向 Rails 上相关 PR 的链接:

引入对第三方组件框架的支持 #36388

注:此 PR 最初标题为:Introduce support for ActionView::Component。我已更新内容,以更好地反映我们最终发布的更改,使用 GitHub 库的新名称,ViewComponent并删除有关验证的内容,因为我们不再使用验证。 - @joelhawksley,2020 年 3 月

引入对第三方组件框架的支持

此 PR 引入了对第三方组件框架的结构支持,包括ViewComponent,GitHub 用于构建视图组件的框架。

具体来说,它进行了修改ActionView::RenderingHelper#render,以支持将对象传递给renderresponds_to render_in,从而使我们能够在 Rails 中将视图组件构建为对象。

自 3 月以来,我们一直在 GitHub 的生产环境中运行此补丁的一个变体,现在已有大约十几个组件在一百多个调用站点中使用。

该 PR 包含一个示例组件(TestComponent),它与我们在 GitHub 上使用的基础组件非常相似。

我在 RailsConf 大会上介绍了我们的项目,并收到了来自社区的许多宝贵反馈。不少人建议我们将该项目合并到 Rails 主干项目中。

为什么

在 GitHub 上开发 Rails 单体应用(拥有超过 4,000 个模板)的视图时,我们遇到了几个关键的痛点:

测试

目前,Rails 鼓励通过集成测试或系统测试来测试视图。这导致我们无法对视图进行彻底的测试,因为执行路由/控制器层会带来高昂的开销,而仅仅测试视图本身则成本更高。此外,这通常会导致每个包含局部视图的部分都需要进行测试,从而降低了视图 DRY 原则带来的益处。

代码覆盖率

许多常见的 Ruby 代码覆盖率工具无法正确处理视图的覆盖率,这使得审核我们的测试是否彻底变得困难,并导致我们的测试套件出现漏洞。

数据流

与对象的方法声明不同,视图并不声明它们预期接收的值,这使得确定渲染视图所需的上下文变得困难。当我们在不同的上下文中重用视图时,这通常会导致一些不易察觉的错误。

标准

我们的代码甚至连 Ruby 类最基本的代码质量标准都达不到:冗长的方法、深层的条件嵌套和莫名其妙的“访客”比比皆是。

视图组件

ViewComponent这是为了解决这些痛点,从而改进 Rails 视图层。

建筑构件

组件是子类,ViewComponent并且存在于其中app/components

它们包含一个与组件同名的边车模板文件。

例子

给定组件app/components/test_component.rb

class  TestComponent < ViewComponent
   def  initialize ( title: )
     @title  = title
   end 
end
Enter fullscreen mode Exit fullscreen mode

模板如下app/components/test_component.html.erb

< span  title = "   < %= @title %> " > <%= content % > </span>
Enter fullscreen mode Exit fullscreen mode

我们可以将其在视图中渲染为:

<%= render( TestComponent.new ( title :  "的标题" )) do  %>
  你好世界!
<% end %>  
Enter fullscreen mode Exit fullscreen mode

返回结果:

< span  title = "的标题" >你好,世界!</span>
Enter fullscreen mode Exit fullscreen mode

测试

组件直接基于其 HTML 输出进行单元测试。render_inline测试辅助工具支持使用 Capybara 断言:

def  test_render_component render_inline 
  ( TestComponent.new ( title :  "我的标题" )) { "你好,世界!" }

  assert_text " Hello, World " 
  assert_selector " span[title='my title'] "
 end
Enter fullscreen mode Exit fullscreen mode

好处

测试

ViewComponent允许对视图进行单元测试。我们的单元测试运行时间约为 25 毫秒/次,而集成测试则约为 6 秒/次。

代码覆盖率

ViewComponent它至少部分兼容代码覆盖率工具。我们已经看到它在 SimpleCov 上取得了一些成功。

数据流

通过明确定义渲染组件所需的上下文,我们发现它们比局部视图更容易重用。

现有实现

ViewComponent这并非什么新颖的想法。Ruby 中常见的视图组件实现方式包括但不限于:

行动中

我创建了一个指向此分支的演示仓库。

共同作者

一个由工程师和我们设计系统团队成员组成的跨职能工作组参与了这项工作,其中包括但不限于:@natashau、@tenderlove、@shawnbot、@emplums、@broccolini、@jhawthorn、@myobie 和 @zawaideh。

此外,社区的许多成员也分享了他们的想法ViewComponent,包括但不限于:@cgriego、@xdmx、@skyksandr、@jcoyne、@dylanahsmith、@kennyadsl、@cquinones100、@erikaxel、@zachahn 和 @trcarden。

我看到的一些亮点包括:

表现

在早期基准测试中,我们发现性能相比现有渲染管线有所提升。对于一个嵌套渲染深度为 10 层的测试页面,我们发现速度比局部渲染提升了约 5 倍:

Comparison:
           component:     6515.4 i/s
             partial:     1251.2 i/s - 5.21x  slower

Rails 6.1.0.alpha,joelhawksley/actionview-component-demo/benchmark 路由,通过RAILS_ENV=production rails s,使用evanphx/benchmark-ips

测试

ActionView::Component 允许对视图进行单元测试。我们的单元测试运行时间约为 25 毫秒/次,而集成测试则约为 6 秒/次。

我以前从没听说过视图组件,至少在 Rails 里没听说过。不过看起来挺酷的;你觉得怎么样?

文章来源:https://dev.to/andy/rails-to-introduce-view-components-3ome