创建服务端渲染打包的入口文件
server-entry.js
import React from 'react';
import App from './App.jsx';
export default <App />;
创建服务端渲染的webpack配置文件
webpack.config.server.js
const path=require('path');
module.exports={
target: 'node', //表示运行在node
entry:{
app:path.join(__dirname,'../client/server-entry.js')
},
output:{
filename:'server-entry.js',
path:path.join(__dirname,'../dist'),
publicPath:'/public',
libraryTarget :'commonjs2' //打包出来的文件使用哪种规范,这里使用的是commonjs2的规范
},
mode:'development', //在webpack4当中,此配置是必需的.development为开发环境,production为生产环境
module:{
rules:[
{
test: /.jsx$/,
loader: 'babel-loader' //此loader将jsx文件转换为es5语法
},
{
test: /.js$/,
loader: 'babel-loader', //此loader将js文件转换为es5语法
exclude:[
path.join(__dirname,'../node_modules')
]
}
]
},
}
创建node服务端文件
server.js
const express = require('express')
const ReactSSR = require('react-dom/server')
const serverEntry = require('../dist/server-entry').default
const fs = require('fs')
const path = require('path')
const template = fs.readFileSync(path.join(__dirname,'../dist/index.html'),'utf8') //把打包生产的index.html读进来
const app = express()
app.use('/public',express.static(path.join(__dirname,'../dist'))); //使用中间件过滤静态资源的请求。
app.get('*',function(req,res){
const appString = ReactSSR.renderToString(serverEntry); //通过reactSSR,把打包的组件解析为html返回到浏览器
res.send(template.replace('<app></app>',appString)); //把app标签替换成生成的html节点
})
app.listen(3333,function(){
console.log('server is listening on 3333')
})
添加打包命令
package.json
"scripts": {
"bulid:client": "webpack --config build/webpack.config.client.js",
"bulid:server": "webpack --config build/webpack.config.server.js",
"clear": "rimraf dist",
"bulid": "npm run clear && npm run bulid:client && npm run bulid:server",
"start": "node server/server.js"
},