import App from '../src/App'; import Koa from 'koa'; import React from 'react'; import Router from 'koa-router'; import fs from 'fs'; import koaStatic from 'koa-static'; import path from 'path'; import { renderToString } from 'react-dom/server'; // 配置文件 const config = { port: 3030 }; // 实例化 koa const app = new Koa(); // 静态资源 app.use( koaStatic(path.join(__dirname, '../build'), { maxage: 365 * 24 * 60 * 1000, index: 'root' // 这里配置不要写成'index'就可以了,因为在访问localhost:3030时,不能让服务默认去加载index.html文件,这里很容易掉进坑。 }) ); // 设置路由 app.use( new Router() .get('*', async (ctx, next) => { ctx.response.type = 'html'; //指定content type let shtml = ''; await new Promise((resolve, reject) => { fs.readFile(path.join(__dirname, '../build/index.html'), 'utfa8', function(err, data) { if (err) { reject(); return console.log(err); } shtml = data; resolve(); }); }); // 替换掉 {{root}} 为我们生成后的HTML ctx.response.body = shtml.replace('{{root}}', renderToString(<App />)); }) .routes() ); app.listen(config.port, function() { console.log('服务器启动,监听 port: ' + config.port + ' running~'); });
config-overrides.js 因为我们用的是create-react-app,这里使用react-app-rewired去改下webpack的配置。因为执行npm run build的时候会自动给资源加了hash值,而这个hash值,我们在asset-require-hook的时候去掉了hash值,配置里面需要改下,不然会出现图片不显示的问题,这里也是一个坑,要注意下。module.exports = { webpack: function(config, env) { // ...add your webpack config // console.log(JSON.stringify(config)); // 去掉hash值,解决asset-require-hook资源问题 config.module.rules.forEach(d => { d.oneOf && d.oneOf.forEach(e => { if (e && e.options && e.options.name) { e.options.name = e.options.name.replace('[hash:8].', ''); } }); }); return config; } };
好了,所有的代码就这些了,是不是很简单了?我们koa2读取的静态资源是 build目录下面的。先执行npm run build打包项目,再执行node ./server 启动服务端项目。看下:3030页面的HTML代码检查下:
没有{{root}}了,服务器渲染成功!
总结
相信这篇文章是最简单的react服务器渲染案例了,这里交出github地址:https://github.com/mtsee/react-koa2-ssr