Rails Rails 5.2 新功能详解

lyfi2003 for 深圳市百分之八十网络技术有限公司 · 2018年04月30日 · 最后由 lyfi2003 回复于 2019年11月15日 · 12083 次阅读
本帖已被管理员设置为精华贴

不知不觉 Rails 已经有 14 年的历史了。这次 Rails 5.2 更新说大不大,但也说小不小。论坛里对此讨论不是很多,我这里正好有一些时间,把 Rails5.2 试着讲的更明白一些。一方面确认自己团队的项目升级顺利,另一方面也期许对论坛的朋友们有所帮助。

核心特性更新:ActiveStorage 让文件上传高效优雅

文件上传这个功能一直是 web 开发的一个痛。它既可以十分简单,又可以复杂的让 Rails 高手都觉得有些棘手。这一切取决于用户对文件上传的体验要求。例如以下需求:

  1. 上传过程可预览,可裁剪
  2. 上传有进度
  3. 能直传到云端(例如又拍,七牛,阿里等云存储)

随着世界的发展,传统的一个 file_field 已经不能满足我们对产品的要求了。于是 ActiveStorage 来了。

  1. 直接支持直传
  2. 默认支持云端存储
  3. 一键安装

整个 ActiveStorage 是非常易用和强大的,可以作为 Rails 5.2 的杀手级特性发布。

不过作为老鸟对于以下两个问题有所担扰:

  1. 迁移成本,Rails 5.1 升级时需要仔细调整,例如将 carrierwave 改为 ActiveStorage
  2. ActiveStorage 与 ActionCable 类似,都是前后端紧急配合,并与 Rails 框架绑的非常深,对于一般工程师掌控它,并想有所定制并不太轻松。

即便如此,ActiveStorage 对于新项目来说,是一个必用特性,推荐大家好好掌握。

Bootsnap 技术应用,Rails 服务启动速度节省 50%

Bootsnap 与 Spring 属于相似技术目标:节省 Rails 开发阶段的启动速度。随着 Rails 的变大变强,需要加载的 gem 越来越多,其中大量的 Ruby 文件需要解释器现编译现启动。所以 Rails 服务(现在缺省是 puma)重启一次就越来越慢了,严重影响了我们开发的速度。

Bootsnap 可以让 Rails 服务首次启动速度降低 50%,并与 Spring 完美协同工作,第二次重启将会更快。其技术核心是:

  1. 路径预扫描

    通过改进 Kernel#requireKernel#load 的实现借以提高加载文件的速度

  2. 编译过程缓存技术

    借助 Ruby 编译器的接口 RubyVM::InstructionSequence.load_iseq 可以达到缓存 Ruby 编译过程的二进制代码,避免重复编译。同时改进了 YAML.load_file 缓存 yml 对象。

以上都是非常针对性的改进 Rails 加载代码中最消耗时间的地方。这些本在普通 Ruby 项目不是什么大的问题,但却能由 Shopify 团队以精细打磨的心态帮助 Rails 生态改进它的加载速度,让每一个 Railser 更幸福一点,谢谢他们。

其他改进

  1. 加密配置文件支持

    通过设定一个 master.key 和 一个 credentials.yml.enc 加密配置,就可以将某些关键的配置直接签入版本控制中,解决一些配置文件的问题。与之前的备份方案先进一些。

  2. Redis Cache Store 内建支持

    应该说这个改进是与 dalli 之类的产生了竞争,是不是“官进民退”由使用者决定:)

  3. webpacker 升级支持

    Rails 5.1 增加的 webpacker 支持非常方便了 Rails 内安装前端的库,这次升级应该说是情所应当。

  4. 增加 HTTP/2 的 early hints 特性

    零成本开启这个功能,让我们的 Rails 页面在 HTTP/2 支持的浏览器中加载的更快。

  5. 内容安全策略 ( Content Security Policy )

    Rails 现在可以通过 DSL 语法定义内容安全策略,确保避免注入型漏洞,使得 Rails 应用更加安全。详见 PR 和内容安全策略解释

  6. 其他细节 API 调整,不再细说

总结

Rails5.2 发布的核心主题是进一步以用户需求驱动,完善文件上传功能的内建支持,以及继续就速度一项进行改进,加载更快,启动更快。

这就是整个 Rails5.2 的改进内容。如果准备升级至 Rails5.2,请执行:

rails app:update 开始你的升级之旅。

如果打算全新开一个 Rails5.2 项目,中国的玩家们可以试试 80percent/rails-template,更快更好地调整好默认配置。

huacnlee 将本帖设为了精华贴。 05月01日 09:31

学习了,去试试。

感谢讲解,一个小小的 typo,dali -> dalli

谢谢反馈,已修正

需要注意的一个点:use_authenticated_cookie_encryption cookies 不兼容,需要重新登录

lyfi2003 回复

赞! 👍 ,还有个小 typo 😄 : file_filed => file_field

lifuzho 回复

谢谢,已修正

刚刚安装了 5.2.0,赞~

新项目用的 5.2.rc1,升到 5.2 之后已经遇到了一车的 bug…不过我还是觉得要升 😐

ActiveStorage 挺好用,不过会导致 rspec 在 MySQL transactional 下随机出错(数据库连接断开)…我看 github 上已经有人提了 issue,就只是附和了下。

bootsnap 导致我的 rake 命令在 development 下疯狂输出报错信息…但任务又是能完成的,没什么实质影响,于是我把 bootsnap 注释掉了…不过 rails 命令是正常的,索性就用 rails 命令吧

更新之后 webpacker 最好也更新一下版本,否则跑测试也会有些蛋疼问题

typo carrerwave -> carrierwave

@lyfi2003 rails5.2 中 lock! 的机制有变化,导制以前正常的代码,时不时的出现(不是每次都出现),以什么办法兼容吗

RuntimeError (Locking a record with unpersisted changes is not supported. Use `save` to persist the changes, or `reload` to discard them explicitly.)

不是机制变化,是你的代码有隐性 bug, 好好查查。

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