.使用rendertron实现SPA项目的服务端渲染
npm install vue vue-server-renderer --save在node中使用,代码如下:
const Vue = require('vue') const server = require('express')() const renderer = require('vue-server-renderer').createRenderer() server.get('*', (req, res) => { const app = new Vue({ data: { url: req.url }, template: `<div>趣谈前端:{{ url }}</div>` }) renderer.renderToString(app, (err, html) => { if (err) { res.status(500).end('Internal Server Error') return } res.end(` <!DOCTYPE html> <html lang="en"> <head><title>Hello</title></head> <body>${html}</body> </html> `) }) }) server.listen(8080)
当然实际情况比上面的案例要复杂很多, 我们可以专门写一个template.html,然后通过模板差值的方式导入后端数据,进而实现服务端渲染. 在使用这种方式的时候我们仍然要维护两套代码。
var express = require('express'); var app = express(); var React = require('react'), ReactDOMServer = require('react-dom/server'); var App = React.createFactory(require('./App')); app.get('/', function(req, res) { var html = ReactDOMServer.renderToStaticMarkup( React.DOM.body( null, React.DOM.div({id: 'root', dangerouslySetInnerHTML: { __html: ReactDOMServer.renderToStaticMarkup(App()) } }) ) ); res.end(html); }); app.listen(80, function() { console.log('running on port ' + 80); });以上使用了renderToStaticMarkup, 我们都知道react-dom提供了两种服务端渲染函数,如下:
Screenshot 用于将网站内容截图
使用Rendertron的好处在于我们可以不用考虑服务端渲染的部分,完全按照SPA的模式开发项目,也不用为了兼容服务端渲染而写多余的兼容代码。
npm install -g rendertron然后我们需要安装谷歌浏览器(作为合格的开发都应该有谷歌浏览器~),然后就可以用它的cli来启动服务了,我们只需要在命令行执行如下命令:
rendertron之后控制台会打印本地服务启动的地址,比如localhost:3000 这个时候我们只需要在地址后面输入我们想渲染的网站即可:localhost:3000:render/你的网站地址, 如下图所示:
const koa = require('koa'); const app = new koa(); app.use(async (ctx, next) => { ctx.type = "html"; if(/Baiduspider\/2\.0/g.ctx.header['user-agent']) { // 是百度爬虫,则转发到rendertron服务中 ctx.redirect(`http://localhost:3000/render/${ctx.url}`) }else { // 渲染正常的路由页面 } await next(); }) app.listen('80');当然如果我们后端技术栈采用的是express, rendertron有专门的中间件可以使用, 不仅仅可以拦截百度的爬虫,具体用法如下:
const express = require('express'); const rendertron = require('rendertron-middleware'); const app = express(); app.use(rendertron.makeMiddleware({ proxyUrl: 'http://your-rendertron-instance/render', })); // 正常的路由和页面渲染逻辑 app.use(...); app.listen(81);所以为了降低开发成本笔者建议可以采用rendertron的方案, 单独部署一套服务器用来实现ssr. 但是我们需要考虑当网站流量增加时的扩容问题,以及配置搭建反向代理或负载均衡等配套服务。