结合create-react-app和上一章静态页面babel进行配置。
目录结构
依赖配置
package.json
{
"name": "react_ssr",
"version": "0.1.0",
"private": "true",
"dependencies": {
"babel-node": "0.0.1-security",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"express": "^4.16.4",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1"
},
"devDependencies": {
"cross-env": "^5.2.0"
},
"scripts": {
"server": "cross-env NODE_ENV=test nodemon --exec babel-node src/server.js",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browsersList": [
">0.2%",
"not dead",
"not ie <=11",
"not op_mini all"
],
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
.babelrc
{
"presets": [
"env",
"react"
],
"plugins": [
"transform-decorators-legacy"
]
}
页面渲染
/src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
/src/App.js
import React, { Component } from 'react'
export default class App extends Component {
sayHello(){
alert('Hello!')
}
render() {
return (
<div>
<button onClick={this.sayHello}>hello</button>
</div>
)
}
}
/src/server.js
import express from 'express'
import App from './App'
import React from 'react'
import {renderToString} from 'react-dom/server'
import fs from 'fs'
var app=express()
app.get('/',function(req,res){
const html=fs.readFileSync('./build/index.html')
const content=renderToString(<App/>)
res.send(html.toString().replace(`<div id="root"></div>`,`<div id="root">${content}</div>`))
})
app.use('/',express.static('build'))
app.listen(3002,function(){
console.log('listening on 3002!')
})
最后npm run server启动服务器
如果对APP组件里有修改,需要重新build,再npm run server启动服务器。会对比之前一个版本增加script标签。
对于不同写法的state和函数表示方式,配置会有不同,以上试用于state写在constructor里的情况。
如果state写在外面,安装@babel/plugin-proposal-class-properties,修改.babelrc
{
"presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": ["@babel/plugin-proposal-class-properties"]
}
下面state写法属于ES7语法,目前浏览器还不支持,需要安装@babel/plugin-proposal-class-properties,并在.babelrc中plugins属性中配置。
import React from 'react'
export default class App extends React.Component {
state = {
count: 0
}
render() {
return <div>{this.state.count}</div>
}
}