Rails React on Rails Way

rocLv1 · 发布于 2016年9月29日 · 最后由 hww 回复于 2016年12月18日 · 4246 次阅读
96
本帖已被设为精华帖!

最近有个项目要用到ant.design, 所以研究了一下React怎么和Rails结合。

目前React和Rails有两个比较流行的Gem,一个是React官方出的,react-rails, 一个是react_on_rails。最近根据对两个的试用,大概总结一下各自的优缺点。

首先我们团队需要解决的问题是:

  • 使用ant.design (需要依赖React)
  • 希望仍然可以使用Rails中各种helper
  • 希望能使用npm包

经过试用,对比如下:

特性 react-rails react_on_rails
可以用helper? 可以 不可以
包管理 browserify-rails webpack
rails way 6/10 0/10
前端way 4/10 10/10
安装难易 略复杂
上手难易 复杂
ES6 部分支持(不支持import) 支持

PS:react-rails 不支持直接在components的jsx文件里直接用import(官方的issue里发现很多人提了这个问题,最后有些自己解决了,但是我目前还没测试成功。本点存疑,疑似可以)。

Gem sprockets-es6是一个Sprockets 的ES6 transformer,是使用Babel JS把ES6的代码转位ES5的代码。但是这个Gem只是一个试验性的Gem。如果引入这个Gem应该可以解决 上面说的那个问题,但是估计会有不少坑。 。 (我的变通方法是在 app/assets/javascript/application.js中先import进来,然后通过window.Variant = Variant这样的方式把引入的Variant作为全局变量来用。这种方式对于小型项目没有问题,对于大型项目就需要注意变量污染的问题了。有更好解决方法的同学别忘了留言~)

目录结构对比

目录结构对比

react-rails会在app/assets/javascript下面创建一个components的目录,写好的组件无需注册,会自动注册为javascript的全局变量,在view里面可以直接使用。

react_on_rails则会在应用程序根目录下创建一个完整的前端目录结构,并且创建几个Procfileg(foreman会调用它。) 这个gem默认使用webpack来把前端的整体打包为webpack-bundle.js,使用时只需在application.js直接包含就可以了。

从目录组织结构就可以看出,react-rails会更加rails way一些,但是缺点也是显而易见的,就是不适合写太复杂的前端。但是,相比之前用jQuery来说,应该也是Rails社区的一大进步。

如果需要在jsx文件中使用helper,可以将jsx文件命名为../components/my_components.es6.jsx.erb 为了使用helper,我们还需要在文件开头添加:

<% environment.context_class.instance_eval { include Rails.application.routes.url_helpers } %>

这样就可以使用resources_path之类的路径helper。

对于controller中的变量,必须通过props传进去,然后再使用,略微增加了一点工作量。

react_on_rails则几乎是前后端分离的方式来写的。不过,在页面首次渲染的时候,都可以直接通过props将值传递进去。因为两者在view里的代码几乎是一样的。

# react-rails
<%= react_component 'ComponentName', { name: 'John' }, { html_options } , prerender: false %>

# react_on_rails
<%= react_component 'ComponentName', props:  {name: 'John'}, { html_options }, prerender: false %>

技术栈

react-rails

  • Rails
  • React
  • ES6 (非必需)

react_on_rails

  • Rails/Grape
  • React
  • react-route(页面内跳转,非必需,但是很要必要掌握)
  • redux (同上)
  • webpack (必须)

总结一下

react-rails适合小范围引入react的项目,更加rails way一些,对整个前端的工具链不需了解太多;而react_on_rails适合重前端的项目,数据通过ajax进行交互,甚至可以直接划分为两个项目。

共收到 12 条回复
445
stephen · #1 · 2016年9月29日 1 个赞

谢谢分享。但是我有点疑问,既然选择react了,为什么不直接前后端分离?rails只做为提供api,这样不是简单很多吗?

26939
alexneverpo · #2 · 2016年9月29日 1 个赞

#1楼 @stephen 可能开发人员大多偏后台

24319
lana · #3 · 2016年9月29日

也有可能是由很多页面不需要用 react 写,rails 的 view 写起来快。

1107 jasl 将本帖设为了精华贴 9月29日 17:43
3454
xwf286 · #5 · 2016年9月30日

react-rails 可以es6+ redux吗?

14099
roclv · #6 · 2016年9月30日

@xwf286 可以,redux也是一个npm包

28064
0x005a · #7 · 2016年10月01日 3 个赞

为啥我感觉两个软件包大同小异,并无多大区别,就我理解来看,其实现大概是这么个套路:

  1. 编写 react 组件(react-rails 组织在 app/components,react-on-rails 组织在 client/app/bundle)
  2. 编写页面,使用 react_component 方法设置顶层组件
  3. 使用 sprocket 打包成一个 application.js 文件
  4. 前端请求页面,返回基本的 HTML 页面;之后在某些事件发生时,通过 ReactDOM 渲染步骤 2 中设置的组件

至于区别的话,大概就是:

  • react-rails 更多的使用了 sprockets 的特性;而 react-on-rails 更多的使用了 webpack 的特性

对于楼主试用后的特性对比,不敢苟同:

  • viewer helper 应该是 sprockets 的功能,只会影响 erb 文件的渲染过程,然而在真正的 javascript 中并无法真正有所作为。试问使用 ant.design 的列表组件,如何渲染每个条目的链接?
  • browserify,webpack 不是包管理器,而是模块管理器,用以处理各个文件/模块间的依赖关系。两者所采用的包管理器都是 npm。
  • rails-way/front-end-way 为啥两者总和是10?这个应该并非非此即彼,而且随着不同使用方案可以相互转变。在我看来,react-on-rails 即可以 rails-way,也可以 front-end-way,都是能够达到 7/10 或者 8/10 分,你完全可以利用 ujs, turbolinks 来实现多页应用,也可以利用 react-router 实现单页应用,关键还是得看整个前端采用的设计方案。
  • 安装难易/上手难易,相对 react-rails,感觉 react-on-rails 主要复杂在 webpack 这个工具上。但也有很多优势,比如支持热替换,使用诸多代码压缩优化等插件(比如 es6/es7 的转译器 babel,比如 antd 官方推出的 babel-plugin-import 等)
  • es6,底层都是 babel js,从原理上看,应该都是支持的。而 import 这个特性,官方似乎推荐使用 require 来解决?而且事实上,babel 貌似也是转译成 require 来实现的。

前端苦手,一脸懵逼,,,

6764
42thcoder · #8 · 2016年10月02日

#7楼 @0x005a 👍

96
shaokun · #9 · 2016年10月21日 1 个赞

印象中react_rails性能差强人意,没修改一个文件都要等待几秒的刷新。对于很重的前端是不大适合的。 我们用webpack-rails,感觉比较溶于当前的前端主流技术,也支持hot-reload,开发起来挺方便的。

16154
hfpp2012 · #10 · 2016年10月21日

这两个我也有用过,也写过一篇文章,有兴趣可以看下,在rails中使用react教程,未及楼主写得详细,只是从使用层面进行了比较 😀

96
aelaa · #11 · 2016年10月21日
2880
luikore · #12 · 2016年10月27日 2 个赞

sprockets-es6 太粗糙了, 没法加各种 babel plugin...

我现在自己用 schmooze 搞终于完美支持各种 import export 和 amd ... 还能加 ng-annotate 什么的

14293
hww · #13 · 2016年12月18日

#12楼 @luikore 还真是。。。

Schmooze lets Ruby and Node.js work together intimately.

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