React 在 Rails 中使用 React 并实现 SSR 的一种实践

baurine · 2018年04月22日 · 最后由 cicholgricenchos 回复于 2018年04月26日 · 8038 次阅读

这个原理是什么?node 执行渲染结果返回给 Ruby?

@Littlesqx 是的,但 js 代码是不是由 node 来执行的我还不确定。

react-rails 文档上是这么说的:

Server rendering is powered by ExecJS and subject to some requirements

(https://github.com/reactjs/react-rails#server-side-rendering)

而 ExecJS 是支持多种服务端的运行时的:

ExecJS supports these runtimes:

  • therubyracer - Google V8 embedded within Ruby
  • therubyrhino - Mozilla Rhino embedded within JRuby
  • Duktape.rb - Duktape JavaScript interpreter
  • Node.js
  • Apple JavaScriptCore - Included with Mac OS X
  • Microsoft Windows Script Host (JScript)
  • Google V8
  • mini_racer - Google V8 embedded within Ruby

(https://github.com/rails/execjs)

😅 其实我和你遇到过很多一样的问题,只是我们 rails 版本升不动,webpacker 用不了

首先感谢楼主的分享,这对需要这样做的人很有参考价值。

但是我要反对这种做法,可以看到,转 React SSR 的需求不是用户体验要求,也不是产品功能要求,而仅仅是需求方的任性,而需要的 SEO 的网站就不适合前端渲染。万一哪天他们要求用深度学习和区块链来做网站呢?

@Rei 我之前看到你的评论了,没来得及回复,现在看好像你的内容已经改过了,我印象中你之前的评论中是说了关于前后端分离的情况,不过仔细看文章我话,其实我这个实践是没有做前后分离的,就用了 React 最最简单的一个功能,作为 view,用 react component 替代了原来的 html view 模板。router 也还是 rails 的 router,数据也都是在服务端产生,通过 props 传给 react component。这种用法几乎没有对原来的整体框架产生太大的变化。(即使不需要 SSR 也可以这么用)

一开始这样做我也是觉得有些拧巴的,但后来我体会到了一些好处,我说说我的感受。

  1. 用 react component (我一直用 jsx 语法) 替代原来的 html view 模板来写 view,表达能力和灵活性都大大加强了 (有待举个例子进行一下对比,但我觉得大家对这一点应该是认可的,毕竟一个是编程语言,一个是标记语言),阅读调试我觉得都更加方便了。在原来的模板中,以 haml 为例,你 include 另一个模板,你都没法直接在编辑器里跳转过去。
  2. 我觉得用 react 另一个最大的好处在于,组件终于能完全复用了。我把一个组件封装好后,放到 npm 上,别人 install, import 一下基本就能马上用起来了。而如果你用一个基于 jQuery 实现的组件,首先要把 js 引进来,然后你需要在 html 中至少声明一个特定的标签,还有可能必须是指定的类名或 id,然后可能还需要调一下某个 js 方法来进行一下初始化。相比 react 组件的使用就麻烦了不少。

这是 RateYo! 的使用示例:

<-- HTML -->

<head>
  <-- Basic styles of the plugin -->
  <link rel="stylesheet" href="jquery.rateyo.css"/>
</head>

<body>
  <div id="rateYo"></div>

  <script src="jquery.js"></script>
  <script src="jquery.rateyo.js"></script>
</body>

/* Javascript */

//Make sure that the dom is ready
$(function () {

  $("#rateYo").rateYo({
    rating: 3.6
  });

});

这是 React-Stars 的使用:

import ReactStars from 'react-stars'
import React from 'react'
import { render } from 'react-dom'

const ratingChanged = (newRating) => {
  console.log(newRating)
}

render(<ReactStars
  count={5}
  onChange={ratingChanged}
  size={24}
  color2={'#ffd700'} />,

  document.getElementById('where-to-render')
);

(代码行数上可能是没更少,但逻辑是集中在一起,没有割裂在不同的地方)

相比传统 html view 模板,我想缺点可能就是性能问题,这个有待 profile 一下到底差多少。但如果对性能需求不是那么高的话,又不喜欢写 html view 模板,那么值得尝试一下这种方式。

而且如果不需要考虑 SEO,那么就不需要为 React 做 SSR,那性能会和传统 html view 模板几乎没有差别。

以上是我的一些拙见。

非常赞,ssr 和 webpacker 结合在我看来是完美的方案,可以避开前端各种状态管理,路由的坑。之前看 webpacker 的 react ssr 好像有人在 WIP,原来 react-rails 就已经支持了。

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