Rails 用现代 Rails 逃离单页面应用 “兔子洞”

JGpirateKing · 2018年09月21日 · 最后由 Rei 回复于 2018年10月05日 · 134 次阅读
本帖已被设为精华帖!

用现代Rails逃离单页面应用“兔子洞”

译者Disclaimers: 翻译本文并非试图引发Full Stack Rails和SPA或Microservices支持者们之间的口水战,只是单纯觉得文章中的很多观点值得思考并与各位分享和讨论。文章下方评论区的一些不同意见也值得一看。

关于Rails Monolith这篇文章也非常推荐大家阅读:The Modular Monolith: Rails Architecture

medium原文链接 DHH鼓掌(看来很和他monolith的胃口😄)。最近很忙,一直没翻完,文章很长,内容丰富且作者文笔风格“飘逸”,加之本人非专业翻译(中英文差😅),错误或辞不达意之处请见谅并指出。以下是正文。

(注: 英语里兔子洞会被用来比喻奇怪的,令人困惑的或荒谬的情况)

TL;DR. 单页面应用(SPA)之路黑暗且充满恐惧。你可以勇敢地和它们战斗。。。或者另选一条可以带你到相近目的地的路:现代Rails。

rabbit hole

记得当DHH在2012年宣布Turbolinks时,我曾认为Rails在关注错误的目标。我当时的信念是,为用户交互提供即时响应时间是优秀用户体验的关键。由于网络延迟,这种交互性只有在你最小化对它的依赖,并在客户端上管理大量状态时才有可能。

我认为这对我当时正在开发的应用是必要的。考虑到这一点,我尝试了许多方法和框架来实现相同的模式:单页面应用(SPA)。我相信SPA wagon才是未来™。经历几年之后,我并不确定未来是啥,但是我真心想要一个替代方案。

单页面应用"兔子洞"

单页面应用是一个javascript应用,完成加载后,不再额外加载页面,完全负责接下来将发生的一切:渲染,从服务器下载数据,处理用户交互,执行屏幕更新。

此类应用感觉更像是原生应用程序,而非传统依赖服务器来响应交互的网页。 例如,如果你用过Trello,你可以看到创建卡片的速度快到爆。

当然,能力越大责任越大。 在传统的Web应用中,您的服务器应用程序包括您的领域模型和规则,一些与数据库交互的数据访问技术,以及一个控制器层,安排如何根据HTTP requests渲染HTML responses。

SPA则比较复杂。你仍然需要一个服务器端应用程序,包括您的领域模型和规则,Web服务器,数据库和一些数据访问技术… 和一些额外的东西:

对于服务器:

  • 满足新客户端数据需求的API
  • 用于客户端交换数据的JSON序列化系统和支持它的缓存系统

对于新的Javascript客户端:

  • 用于将数据转换为HTML的模板系统
  • 你的领域模型和规则的表示
  • 新的客户端持久层,用来将变动传递到服务器
  • 在数据更改时更新视图的系统
  • 用于将URL路由关联到页面的系统(除非你想所有都用相同的URL,感觉不够Web)
  • 引导所有渲染屏幕所需的组件,以及获取必要的数据的系统
  • 一种新的模式/架构来组织所有这些代码
  • 用于处理错误,记录,异常跟踪等的系统
  • 用于为服务器请求生成JSON的系统
  • 支持SPA的自动化测试框架
  • 一套额外的用编写和维护的测试套件
  • 额外的用于构建,打包和部署新应用程序的附加工具链

总而言之,SPA让你需要维护一个额外的应用。 还有一系列新的问题需要处理。 注意,你没有替换任何一个应用。 你仍然需要服务器端应用程序(它现在只渲染JSON而不是HTML)。

如果你从未使用单页应用程序,你可能会低估将面临的困难。 因为我过去犯了同样的错误所以我知道。 渲染JSON? 我可以应付。 一个领域对象的富Javascript模型? 听起来很有趣。 而且,Hey,这个框架将完成所有繁重的工作。 小菜一碟!

错了。

API和数据交换

新应用程序和服务器之间的数据交换是一个需要解决的复杂问题。有两种相反的力量:

  1. 由于性能原因,你将希望尽可能少地向服务器发出请求。
  2. 将单种记录序列化成JSON很容易。 但组合包含不同记录的大型模型,最小化请求数量则不然。 你需要仔细设计序列化逻辑,以优化数据库查询并保持高性能。

最重要的是,你需要考虑何时在每个页面上获取什么内容。 我的意思是,你需要平衡加载时间,什么是立即需要的,可以懒惰获取,以及想出满足这一要求的API设计。

一些标准可能会有所帮助。JSON api,用于标准化您用于数据的JSON格式; 或GraphQL,用于在单个请求中精确地获取你所需的数据,想多复杂都行。 但是没有一个可以从这些里拯救你:

  • 设计每个数据交换
  • 在你的服务器上有效地实现满足每个交换的查询。

这两个方面代表了相当多的额外工作。

初始加载时间

人们将单页应用程序与速度联系起来,但事实是让它们快速加载是具有挑战性的。原因有多方面:

  • 应用需要在渲染任何内容之前加载,并且解析大量的Javascript需要时间。
  • 除了加载应用的初始HTTP请求之外,它们通常还需要一个或多个请求来获取渲染页面所需的JSON数据。
  • 客户端需要在呈现任何内容之前将JSON转换为HTML。根据要转换的设备和JSON数量,这可能会引入明显的延迟。

这并不意味着不可能使SPA加载速度快。我只是说它很难以及你需要计划一些东西,因为不会自然而然地因这种模式出现。

例如,基于Ember的SPA应用Discourse启动时间非常棒,但除这些以外,它们预先加载了一堆JSON数据作为初始HTML的一部分,以防止进一步的请求。 并注意discourse团队自豪地痴迷于速度,他们的技能高于平均水平。在假设你可以轻松地在SPA中复制此类性能之前,请记住这一点。

对这个问题的一个雄心勃勃的想法是Isomorphic Javascript:在服务器上渲染你的初始页面并快速提供它,而在后台,SPA加载并在准备就绪时进行控制。

这种方法要求在服务器上运行JS运行时,并且并非没有技术挑战。 例如,开发人员必须计划SPA中使用的加载时事件,因为加载过程现在会改变。

我喜欢这个想法带来的共享代码可能性,但我还没有看到一个实现可以让我不走在相反的方向上。 我也发现这个页面渲染过程有点可笑:

  • 服务器:查询服务器端API
  • 服务器:查询数据库
  • 服务器:生成JSON
  • 服务器:将JSON转换为HTML
  • 客户端:渲染初始HTML
  • 客户端:加载SPA
  • 客户端:解析初始HTML并hydrate DOM

难道你不能只查询数据库,生成HTML并运行?

这并不完全公平,因为你将不会获得SPA并因为大部分魔法被框架所隐藏,但我仍觉得不妥。

架构

编写有丰富GUI的应用很难。有充分理由认为它们是激发面向对象和许多其他设计模式的问题之一。

在客户端管理很多状态很困难。传统网站通常关注特定目的的页面,这些页面在重加载时会得到全新状态。另一方面,SPA负责在使用期间管理所有状态和页面更新,并且必须确保一切都一致且平稳地移动。

实际上,如果您来自编写轻量,小段的Javascript代码以增强某些交互,而SPA会把这转化成你必须编写的大量额外的Javascript代码。你最好确保正确地设计。

SPA框架有许多不同的架构:

  • 大多数框架分支于传统的MVC。 Ember最初深受Cocoa MVC的启发,但在最近的版本中改变了它的编程模型。

  • 与传统的控制器/视图分割相比,有一种支持组件的倾向(其中一些,如Ember和Angular,在后面的主要修订版中做到了这一点)。

  • 它们都支持某种单向数据绑定。不鼓励双向数据绑定,因为它引入了副作用。

  • 大多数框架都包含一些路由系统,它可以将URL映射到屏幕,并确定如何实例化组件以进行渲染。这对于Web来说是非常独特的,也是传统桌面GUI中不存在的东西。

  • 大多数框架将HTML模板与Javascript代码分开,但React下赌注在Javascript中混合HTML生成并获得成功,因为它被社区大量采用。这些天也有关于在JS中嵌入CSS的炒作。

  • Facebook的flux架构在业界产生了相当大的影响,像Redux,vuex和其他许多容器都受到了很大的启发。

在我见过的所有框架中,Ember是我的最爱。我喜欢它的凝聚力,而且它是固执己见的。我也喜欢它的编程模型在最近版本中的演变,混合了传统的MVC,组件和路由。

另一方面,我非常不喜欢Flux/Redux阵营。我见过这么多聪明人采用它,我多次努力学习和理解它。当我看到代码时,我无法避免难以置信地摇头。我不认为自己在遵循这样的模式编写代码并且同时感到中度快乐。

最后,我很难接受在充满javascript逻辑的组件中混合使用HTML和CSS是一个好主意。 我理解这样解决的问题,但是我认为它引入的问题不会使这种方法值得。

除了个人偏好之外,最重要的是,如果您选择SPA路线,则需要解决一个非常复杂的问题:正确构建您的新应用。行业中远未就如何做到这一点达成共识。每年都会出现新的框架,模式和框架修订版本,这些框架修订版本会在很大程度上改变编程模型。您必须根据您的架构选择编写和维护大量代码,因此请务必仔细考虑这一点。

代码重复

写SPA时,代码重复可能会是一个问题。

对于SPA逻辑,你需要一个丰富的对象模型来表示你的域及其规则。 而且你的服务器逻辑仍需要相同的功能。 这套做法只是一个等待发生的重复。

例如,假设你正在处理发票。你可能有一个javascript Invoice类,它公开了一个方法总和,它把所有明细相加,以便你渲染数量。 在服务器上,你还需要一个带有总和方法的Invoice类,用于在通过电子邮件发送发票时计算该金额。看到了吗? 客户端和服务器实现相同逻辑的Invoice类。重复的代码。

如上所述,Isomorphic Javascript可以通过更容易共享代码来缓解此问题。我说缓解因为客户端和服务器对象之间的映射并不总是1对1。你将会想要确保某些代码永远不会放弃你的服务器。很多代码只会在客户端有意义。而且,一些需要考虑的点不同(例如,服务器元素可能会将数据持久保存到数据库,但客户端对应方可能会使用某些远程API)。即使可能,共享代码也是一个棘手问题。

你可以辩称你并不真正需要SPA中的丰富域模型,而是直接处理原始JSON / javascript对象,通过视图组件分发逻辑代码。你现在拥有相同的重复逻辑,但与你的视图代码混合在一起,只能祝您好运。

如果要在服务器和客户端之间共享渲染模板,也会发生同样的情况。 例如,对于SEO目的,如果你想在检测到网络爬虫时发送服务器端生成的网站版本,该怎么办? 你必须在服务器上再次编写模板,并确保它们从那一刻起保持同步。 再次重复代码。

根据我的经验,不得不在客户端和服务器中复制逻辑或模板是增加编程不满的根源。你第一次这样做还行。当你做到的第20次,你会摇头。当你做到的第50次是,你会想知道所有这些SPA的东西是否都是必要的。

脆性

根据我的经验,构建强健的SPA比编写强健的服务器端生成的Web应用程序要困难得多。

首先,无论你多么小心,无论你写多少次测试。你编写的代码越多,你将拥有的bug就越多。如果我坚持太多,SPA意味着一大堆额外的代码来编写和维护。

其次,如前所述,构建丰富的GUI很困难,导致由许多彼此交互的元素组成的复杂的系统。你编写的系统越复杂,你将拥有的错误就越多。与使用MVC的Model-2变体的传统Web应用程序相比,SPA的复杂性是疯狂的。

例如,为了保持服务器中的数据一致性,你可以利用数据库约束,模型验证和事务。如果出现问题,你将回复错误消息。在客户端中,事情有点复杂。很多地方都可能出错,只是因为很多事情正在发生。也许某些记录成功保存,其他一些记录失败。也许你在某些操作过程中断线了。你需要确保UI始终保持一致,并且当错误发生时应用程序会正常恢复。 这一切都是可行的,当然,只是更难。

组织挑战

这听起来很愚蠢但是,对于构建SPA,你需要了解如何执行它的开发人员。同样,你不应低估SPA的复杂性,你不应该假设任何有经验的Web开发人员具有正确的动机和常识,可以从头开始编写优秀的SPA。你需要正确的技能和经验,或者假设将要做出重大错误。我知道这是因为这正是我的情况。

这对你的公司来说可能比你想象的更具挑战性。SPA方法鼓励专家团队而不是多面手:

  • SPA框架是复杂的软件,可以使无数的飞行时间变得高效。只有你公司花费这些时间的人才能维护这些应用程序。
  • SPA框架需要全面且高性能的API。构建这些需求的技能完全不同于SPA框架所需的技能。

有可能你最终会遇到无法在SPA上工作的人以及无法在服务器端工作的人,只因为他们不知道如何。

这种专业化可能非常适合Facebook或Google以及由多层工程兵力组成的团队。但这会是你的6人开发团队吗?

现代Rails

现代Rails中包含三个部分可能让你在设计现代Web应用时重新思考:

  • 一个是Turbolinks,我认为它吊炸天。
  • 另一个是最近经常被忽视的老朋友:SJR Responses和简单的AJAX渲染调用。
  • 最后一个是最近的补充:Stimulus

不使用就很难体会一些方法感觉如何。 因此,我将在以下部分中对Basecamp进行一些引用。 我与Basecamp无关,除了是一个快乐的用户。 关于这篇文章,它只是现代Rails的一个很好的实例,你可以免费试用。

Turbolinks背后的想法很简单:通过执行

替换的ajax请求整页重载,从而加速应用。使其工作的内部巫术被隐藏起来。 作为开发人员,您可以专注于传统的服务器端流程。

Turbolinks很大地受到pjax的启发,并经历了多次修订。

我曾经担心它的表现。我错了。速度大幅提高。说服我的是在一个项目中使用它,但你可以试用Basecamp并玩一玩。尝试使用某些元素创建项目,然后点击不同的部分进行导航。这将让您对Turbolinks的感受有所了解。

我不认为Turbolinks的新鲜性是令人兴奋的(pjax是8岁)。或者因为它的技术复杂性。让我感到惊讶的是,与SPA替代方案相比,如此简单的想法能够数量级地提高生产力。

让我重点介绍它消除的一些问题:

  • 数据交换。你没有它们。无需序列化JSON,设计API或考虑以高效的方式满足客户端需求的数据查询。

  • 初始加载。与SPA不同,它通过设计鼓励快速加载。对于渲染页面,您可以直接从数据库中获取所需的数据。有效地查询关系数据库或缓存HTML等问题都被很好解决了。

  • 架构:您不需要复杂的架构来组织您的Javascript代码。您只需要专注于正确构建您的服务器端应用,你用SPA也得做这些。

服务器上的MVC,在Rails和许多其他框架使用的变体中,比用于构建丰富的GUI的任何模式简单得多:接收请求,处理数据库以满足它并呈现HTML页面作为回应。

最后,总是替换

的约束有一个很好的效果:你可以专注于页面的初始渲染,而不是更新特定的部分(或更新一些状态,在SPA世界中)。在一般情况下,它只是再次呈现一切。
  • 代码重复。 您的应用程序只有服务器上的一种代表。您的域模型,规则,应用页面等。无需在客户端中复制概念。
  • 脆性。 与SPA相比,在您的页面中运行的Javascript及其复杂性大幅降低,bugs的数量也一样。最重要的是,你可以依赖于原子地执行服务器中的操作,利用数据库事务,约束和模型验证。

请注意,我不是在讨论解决问题,而是在消灭问题。例如,GraphQL或SPA Rehydration是解决非常复杂问题的超聪明解决方案。但是,会不会不是试图找到解决方案,而是将自己置于不存在这些问题的情况下呢?这是工作中的问题重述。我花了很多年才完全理解这种问题解决方案的力量

当然,Turbolinks不是一个没有问题的银弹。 最大的抱怨是它可以破坏现有的Javascript代码:

  • Turbolinks带有自己的自定义“页面加载”事件,依赖于常规页面加载的现有插件将无法工作。今天有更好的方法将行为附加到DOM,但遗留的组件除非经过调整才能工作。
  • 因为Javascript修改DOM的代码可能被重复执行,所以应该保证这部分代码是幂等idempotent的。同样,这使许多现有的Javascript无效。
  • 速度非常好,但它不像SPA那样可以在不获取服务器的情况下处理某些交互。我稍后会谈论更多的权衡。

AJAX渲染和SJR responses

还记得15年前通过Ajax渲染HTML时很性感吗? 猜猜怎么了? 它仍然是你工具箱中的绝佳资源:

  • 从服务器获取一些HTML片段并将其添加到dom感觉超快(像100ms那么快)。
  • 你可以在服务器端渲染HTML,使你可以视图复用并直接从数据库中获取所需的数据。

你可以通过点击右上角的按钮打开个人资料菜单,了解这种方法在basecamp中的感受:

turbolink-load 通过Ajax在Basecamp中打开一个下拉菜单,其中包含GET请求

感觉很快。从开发方面来说,你不必关心JSON序列化和客户端渲染的东西。你可以用所有Rails goodies在服务器上渲染该片段。

Rails多年来一直使用的类似资源是服务器生成的JavaScript响应(SJR)。它们让你用被在客户端中执行的javascript响应Ajax请求(通常是表单提交)。它提供了与ajax渲染HTML片段相同的好处:它感觉非常快,你可以重用服务器端代码,并且可以直接访问数据库以构建回应。

如果你去Basecamp尝试创建一个新的todo,你可以感觉一下。单击“Add this todo”后,服务器将保存todo并返回Javascript片段将新todo附加到dom。

我认为今天许多开发人员都不屑一顾地看待Ajax渲染和SJR响应。我记得我也是一样一样的。它们是一种工具,因此可能被滥用和错用。但如果使用得当,它们就是一个了不起的解决方案。让你以极低的成本提供出色的用户体验和互动性。可悲的是,除非你先打一些SPA战斗,否则很难欣赏Turbolinks。

Stimulus

Stimulus是几个月前发布的Javascript框架。它不关心渲染,也不关心基于Javascript的状态管理。相反,它只是一种很好的,现代的组织你用来增强HTML的JavaScript的方式:

  • 利用MutationObserver将行为附加到DOM,这意味着它不关心HTML在页面中如何显示。当然它与Turbolinks完美搭配。
  • 它为你节省了大量用于将行为附加到DOM的样板代码,用于将处理程序附加到事件以及定位给定容器中的元素。
  • 它旨在保持您的HTML可读性和自解,这很棒,如果你曾经遇到过发现哪个Javascript在操作这个该死的元素的问题。
  • 它鼓励将状态保持在DOM中。同样,这意味着它不关心如何生成HTML,这适用于许多场景,包括Turbolinks。

如果你拥抱Rails way,你的Javascript将专注于增强服务器端生成的HTML和增强交互(Rails称之为Javascript sprinkle)。Stimulus意在组织这样的代码。它不是SPA框架,也不假装是一个。

我在一些项目中使用了Stimulus,我非常喜欢它。它删除了一堆样板代码,它基于最新的Web标准,读起来很爽。我特别喜欢的东西:它现在是做某事的标准方式,直到现在,每个应用程序决定如何做。

权衡的游戏

Turbolinks通常以“获得SPA的所有好处而没有任何不便”来营销。我不认为这是完全正确的:

  • 使用现代Rails构建的应用程序感觉很快,但对于不依赖于服务器的交互,SPA仍然会感觉更快。

  • 有些情况下SPA更合理。如果你需要提供高层次的交互性,必须管理大量状态,执行复杂的客户端逻辑等,SPA框架将使您的生活更轻松。

现在,开发是权衡的游戏,并且在此游戏中:

  • Modern Rails可让你构建足够快且感觉很棒的应用程序。

  • 对于各种各样的应用程序,Rails使你能够以很少的代码和复杂性实现相同的功能。

我相信使用Rails可以通过10%的工夫而达到SPA可提供的90%。Rails在生产力上杀死了SPA。在UX方面,我认为许多开发人员犯了和我同样的错误,认为SPA UX是不可战胜的。不是这样。实际上,如上所述,你最好在构建SPA时知道自己在做什么,否则UX实际上会更糟。

总结

我观察到大量采用SPA框架的公司,以及无数关于用SPA方式做花哨事的文章。我认为有很多“不使用正确的工具”的现象,因为我坚信认为适用于SPA的应用类型是有限的。

我提到合理,是因为SPA很难。我希望我在本文中已经在一些事上说服了你。我并不是说创建优秀的SPA是不可能的,或者现代Rails应用就一定很棒,或是只有一条路径超级难,另一条路径容易很多。

在研究写这篇文章时,我偶然发现了这条推文:

这让我大笑,因为我会选第一个选项,除非替代方案是合理的。这也代表了一种开发者思维方式,喜欢复杂性并在其中蓬勃发展,知道认为其他有不同标准的人是疯狂的。

多年来,我艰难地学会了复杂性通常是一种选择。但是在编程世界中,选择简单是非常困难的。 我们非常尊重复杂性,接受简单性通常意味着思维不同,根据定义,这很难。

请记住,你可以选择让自己摆脱困境。如果你选择SPA之路,确保其合理且你了解挑战。如果你不确定,尝试不同的方法并亲眼看看。也许Facebook或谷歌在他们的规模上没有做出这样决定的奢侈,但你很可能有。

如果你是多年前放弃Rails方式的Rails开发人员,我建议您重新审视它。我想你会感到愉快的。

写在最后的个人想法:用过React之后尝试rails-ujs + turbolinks + stimulus感觉出乎意料的舒服顺畅,效率也不错,配合webpack,是rails社区应对SPA的一套替代方案,基本可以确定将成为标配。和React, Vue, Angular相比各有利弊,要看应用场景和需求。不过jquery这套思路被边缘化的趋势难以阻挡。

共收到 37 条回复
jasl 将本帖设为了精华贴 09月22日 03:31

The Modular Monolith: Rails Architecture 这篇文章非常值得一读: 主要围绕着他们在开发Root 中应用到的技巧以及依赖管理等内容。(其实我翻译了,但是质量觉得太差没发出来🤣)

其中最有启发的一点就是他们把项目拆分成 gems/engines/,这个和shageman 说的 CBRA 多少有点不同。

但是这类实践毫无疑问是可以适用于大规模的Rails 应用开发的,但是The Modular Monolith 里最终指向的,还是DDD。

idempotent 可以翻译成 幂等的 https://en.wikipedia.org/wiki/Idempotence

Javascript code modifying the DOM needs to be idempotent since it can be run multiple times.

原文这句话应该可以翻译成

因为 Javascript 修改 DOM 的代码可能被重复执行,所以应该保证这部分代码是幂等的。

ian2hao 回复

感谢,已经修改

chrishyman 回复

同意,非常干货的文章。gems不依赖rails, engines依赖rails。不需要为了一个功能,修改多个依赖的项目。即使未来项目遇到瓶颈,单独一部分拆分成microservices也更方便。有空时候我把这篇也翻出来。

很多项目是rails5以下的,对于一个正在运行的项目,要升级到5不是容易的事情

rails 5以上的项目我想我会尝试使用 rails-ujs + turbolinks + stimulus

heroyct 回复

这几个前端组件在 Rails 4 环境就能用了。

@Rei stimulus 好像不行?没具体试
https://github.com/stimulusjs/stimulus/issues/59
看这里说好像需要5.1以上

heroyct 回复

这是个纯前端库,把构建好的 js 放到 vendor,通过 assets pipeline 引入,cofferscript 写就行(ES5 也行)。

heroyct 回复

5.1以上是指自带Webpacker的Rails版本,不用额外配置

更早版本的Rails可以添加Webpacker gem, 再按照Stimulus官方教程安装。Turbolink, Rails-ujs等也可以一并用webpack安装

当然也可以用assets pipeline, 例如https://github.com/bricesanchez/stimulusjs-rails

不过貌似Rails 6.0要default Webpacker

JGpirateKing 回复

Webpacker 的维护者似乎不在 Basecamp 去创业了,4 目前看是难产状态,维护者在一个他在做的时间很久的 WIP PR 里表示近期也没有精力来搞... 这个比较意外

jasl 回复

这。。。DHH还说等Webpacker default之后有个“brand-new exciting framework for Rails 6.0“ https://twitter.com/dhh/status/1028355448808792064?lang=en

前端的实现方案还在摸索之中,现在的SPA的实现方式已经比后端渲染还要复杂了,一些前端狂热者为了SPA而SPA,就像当年ajax刚刚流行的时候,很多内容展示网站都用纯ajax加载。随着时间的流逝,大浪淘沙,会沉淀下来真正适合的技术。

JGpirateKing 回复

Rails 6 发布还早,年底或明年初 Alpha 了,时间还有,而且 Webpacker 本身做的事情并不多,所以还是可以观望的。

我是本来希望等 Webpacker 4 出来(Webpack 4 + Babel 7)在动手做个前端的东西,所以每周都关注他们的进度

Webpack is now the default JavaScript compiler for the upcoming Rails 6 🎉 https://twitter.com/dhh/status/1046634277985611776

目前自己搞还是不少麻烦事的,我等 Rails 6 发布再上。

Rei 回复

Webpacker 3 开始没啥麻烦的了,但是 Webpack 这套和 jQuery-based 还有老式的 JS 模块化风格的库配合起来要搞好多配置 而且未必能用。比如我直接问你的 Selectize.js 怎么能跑起来

这个以后也解决不了,所以更大的问题是更新前端技术栈适配新时代

jasl 回复

我遇到个 docker 的问题,docker 共享目录的性能遇上庞大的 node_modules 简直爆炸,执行 bin/rails test 先要卡 30 秒。https://github.com/docker/for-mac/issues/77

Rei 回复

那也是 NPM 的问题了吧,归到 Webpacker 上倒也没没错,不过我觉得这个问题应该不会在 Webpacker 这层去解决的

Rei 回复

看了下应该是 docker 的问题,底下的讨论看所有的包管理工具都有可能触发这个问题

jasl 回复

是 docker 的问题,如果有限度的用 yarn 让 node_modules 维持在比较小的体积可以缓解这个问题(Webpakcer 默认依赖700+)。所以我还在用 assets pipeline,等 Rails 6 出了,各个组件的协调不用自己摸索了再去想怎么解决这个问题。

Rei 回复

试试把 tmp/cache 目录设置 Docker Volume

huacnlee 回复

不懂,在 docker compose 里面配置:

volumes:
  - .:/app

不是 volume 了么?

官方文档关于性能部分 https://docs.docker.com/docker-for-mac/osxfs/#performance-issues-solutions-and-roadmap ,看完还是不知道怎么解决。

不想现在处理 Webpacker 另一个原因是怕正式版前还有变动,想想被砍的 Turbolinks partial replacement

Rei 回复

你在 volume 的地方加上

  • public/packs
  • tmp/cache

两个路径,这样之前 Webpacker 的编译结果就有缓存可以重复利用了

huacnlee 回复

额,我是指在开发环境,整个项目目录都作为 volume mount 进去的,但是文件太多了导致执行缓慢。

jasl 回复

ruby社区现在也大量使用npm了?

posee 回复

Rails新项目用npm/yarn是趋势,不光ruby社区,python, go等等社区,和JS/前端有关都会用到npm/yarn吧

JGpirateKing 回复

数据库操作用Rails?其他都用npm?

posee 回复

即使是传统 Server side rendering 也一样可以用 yarn、npm 来管理前端资源,Rails 在 5.1开始 可以Yarn包管理+Assets Pipeline 引用资源。

现在争议比较大的是要不要全盘前后端分离

看了眼 Webpacker 的提交记录,感觉 Basecamp 团队又接管了了啊,接近半年后 Pre3 发布了

jasl 回复

对啊,现在社区都对DHH透露的“brand-new exciting framework for Rails 6.0”充满想象,我好像看到这里有个人猜是active_blockchain 😂

@heroyct @jasl docker-sync 完美解决 docker for mac 性能问题!

向 Webpakcer 低头!

Rei 回复

另外完全剥离 Assets Pipeline 用 Webpacker 处理前端资源后,部署时前端的速度提升明显,assets pipeline 熟悉不直接支持力度es6,样式 sass-ruby 停止开发,sassc-rails 缺乏维护,长期看还是堪忧的

jasl 回复

看 DHH 什么时候改口去掉 Assets Pipeline 了,装了 Webpacker 之后看到两个 asset 类目录感觉很分裂。

Rei 回复

回头我写过帖子吧

Rei 回复

他这个 precompile 还会先启动 sprockets 这个耗时还是挺久的

jasl 回复

完事了就可以把组件去掉了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册