You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
最后,就可以通过 npm run start的方式实现启动server.js,server.js是经过babel处理,可以支持ES6和jsx.
在server.js中,我们利用了express的路由和中间件模块。
let express=require('express');
let app=express();
import React from 'react';
import {renderToString,renderToStaticMarkup} from 'react-dom/server';
import HomePage from '../src/components/homepage/index.js';
var server=app.listen(8080,()=>{
var host=server.address().address;
var port=server.address().port;
console.log('server is start at',host,port);
});
//static
app.use('/dist',express.static('dist'));
app.get('/',(req,res)=>{
res.write('<!DOCTYPE html><html><head><title>Hello HomePage</title></head><body>');
res.write('<div id="app">');
res.write(renderToString(<HomePage/>));
res.write('</div></body>');
res.write('<script type="text/javascript" src="../dist/vendor.bundle.js"></script><script type="text/javascript" src="../dist/js/app.js"></script>');
res.write('</html>');
})
import {hydrate} from 'react-dom';
hydrate(<HomePage/>,document.getElementById('app'));
运行后发现提示:
Warning: render(): Calling ReactDOM.render() to hydrate server-rendered markup will stop working in React v17. Replace the ReactDOM.render() call with ReactDOM.hydrate() if you want React to attach to the server HTML.
简要介绍:为了SEO和加快首屏加载速度,React提供了服务端渲染(Server Side Render)。本文结合express,来介绍一下React16.x中的SSR。
本例代码:https://github.com/forthealllight/react16.0-ssr
一、为什么要SSR
单页应用将UI层和内容都由javascript来渲染,搜索引擎或网页爬虫需要完成的HTML结构,因此单页应用如果只在客户端渲染,不利于SEO,此外尽管我们可以通过按需加载的形式来减少首页加载的js,但是通过js来渲染DOM的时候还是会有一定的时间延迟。
因此SSR解决的问题有两个:
SEO
加速首屏加载
在React和Vue等前端框架中,SSR的本质就是由服务端执行渲染,直接将渲染结果以HTML结构的形式返回给客户端。也就是将Virtual DOM转化成字符串的形式返回给客户端。
二、React15.x中的SSR
在React15.x中,有两个方法来处理SSR:
renderToString
renderToStaticMarkup
这两个方法都是在react-dom/server中提供的,用来在服务端将virtual dom渲染成字符串。
(1) 相同点
renderToString和renderToStaticMarkup都接受一个参数,这个参数是react的组件,返回一段HTML字符串。
此外react-dom中给浏览器端提供了一个render方法,render方法将react组件,添加到真实的DOM节点中。render实现的就是浏览器端渲染。
归类一下:
服务端渲染:renderToString、renderToStaticMarkup——>string
客户端渲染:render——>HTML结构
(2) SSR实现
下面我们以renderToString为例,通过express来实现一个服务端渲染的例子。
首先node最新版本为8.9.3,还不支持es6语法,同时为了使node支持jsx,我们需要安装babel,本文为了方便,采用了babel-cli。
首先安装babel-cli:
接着安装presets:
接着我们在script中:
最后,就可以通过 npm run start的方式实现启动server.js,server.js是经过babel处理,可以支持ES6和jsx.
在server.js中,我们利用了express的路由和中间件模块。
结构很简单,因为返回的html页面要加载静态资源,因此我们在上述的代码中还使用了express内置的静态文件模块express.static.
最后,通过npm start就能启动本地服务器,在浏览器中打开:
http://localhost:8080/ 就能看到我们SSR的例子。
(3) renderToString和renderToStaticMarkup的区别
renderToString:渲染的结果是带有data-reactid属性的,此时,在服务端的基础上,客户端的render不会重新渲染,只会执行组件componetDidmout中的业务,以及绑定事件等等。
renderToStaticMarkup:渲染的结果是不带有data-reactid属性的,此时不管服务端有没有渲染,在客户端中都会重新渲染该组件。
比如在renderToString的关于HomePage的返回HTML字符串结果为:
而在renderToStaticMarkup中,关于HomePage的返回HTML字符串结果为:
三、React16.x中的SSR
(1) hydrate
在React16.x中,在客户端渲染的render的方法的基础上,增加了一个新的方法hydrate.
简单来说,如果在仅在客户端呈现内容,那么使用render方法就已经足够,如果客户端要在服务端的基础上进行渲染,那么可以使用hydrate.
使用的方法和render一样:
运行后发现提示:
说明React16.x中,客户端“水合”服务端,是兼容之前的render方法的,之后的版本中会移除render方法,完全用hydrate来代替。
hydrate方法,解决的是如何复用server端,ReactDOMServer的结果。
(2) stream
此外React16.x中,针对renderToString和renderToStaticMarkup提供了stream的方法:
这两个方法同样接受的参数为react element,但是返回的不是HTML字符串,而是一个可读流。
最后给出完整代码的地址,直接npm start就可以运行:
https://github.com/forthealllight/react16.0-ssr
四、注意事项
如果不用babel-cli的方法,来babel node文件,用webpack的话可能会报一下错误:
也就是webpack在打包的时候找不到 node自带的模块,比如fs等,解决的方法是在webpack的配置文件里面增加:
The text was updated successfully, but these errors were encountered: