转载

探索 React 服务器端加载

探索 React 服务器端加载

迅雷下载宝官网使用 React + react-router + redux 构建,出于 SEO 考虑,决定使用 Node.js 搭建一套服务端渲染的环境(Universal app),在此记录遇到的问题和解决方案。

为什么可以同构渲染?

在 react 中,react 组件和渲染的概念已经分离出来了。比如从 v0.14 开始,最常用的浏览器端渲染 render() 方法分离到 react-dom 中,而在服务器端,我们想要得到的不是 DOM 对象,而是字符串形式而已,因此我们可以使用 renderToString() 方法,该方法位于 react-dom/server 中。正是因为这样的分离思路,react 才标榜自己 “learn once, use everywhere.”(虽然代码还不能完全复用)。

浏览器环境和 Node 环境的差异

Node 环境没有 window 对象, window 下面的子对象包括 location , navigator 等,直接在 node 环境使用会报错。

浏览器路由

React-router 使用 browserHistory 代替 hashHistory

URL 中的 hash 部分不会发送到服务器,因此服务器端不能根据 hash 区分请求 URL,还好 react-router 支持 browserHistory + HTML5 history API 方式的路由。注意的是,组件的 <a> 标签需要使用 react-router 的 <Link> 标签代替,这样改变路由很方便。

ES6 语法转换

Node.js v4 对 ES6 和 ES7 的支持还不全面(参见 https://nodejs.org/en/docs/es6 ),因此需要使用 babel v6 对源码作转换,方法也很简单,在入口加一句 require('babel-core/register') 即可。

Express

使用 Express 框架处理请求,注意区分开发模式和生产模式,开发模式需要引入 Webpack 中间件(见下文),生产模式对于静态资源直接读取磁盘文件。

Webpack

其实服务器端加载可以不使用 Webpack,直接加载打包后的静态文件亦可,在这里为了开发环境的方便,也在服务器端引入了 Webpack。

Webpack 要在服务器端使用,需要用到下面三个库。

webpack-isomorphic-tools

地址: https://github.com/halt-hammerzeit/webpack-isomorphic-tools

模仿了 Webpack 的 require() 方法,由于 Node.js 环境中本身不支持 require(‘../image.png’) 这样的用法,所以需要这个库提供支持。

webpack-dev-middleware

地址: https://github.com/webpack/webpack-dev-middleware

Webpack 的一个包裹层中间件,注意仅在开发环境使用。用法参考项目 readme。

webpack-hot-middleware

地址: https://github.com/glenjamin/webpack-hot-middleware

配合 webpack-dev-middleware 使用,目的是实现热加载。用法参考项目 readme。

参考资料

  • 玩转 React 服务器端渲染
  • isomorphic-redux-app 的源代码
原文  http://blog.zhangjd.me/2016/08/11/react-server-side-rendering/
正文到此结束
Loading...