const path = require('path')
const HTMLPlugin = require('html-webpack-plugin')
module.exports = {
//应用入口
entry: {
app: path.join(__dirname, '../client/app.js')
},
//打包的文件路径
output: {
filename: '[name].[hash].js',
path: path.join(__dirname, '../dist'),
//静态资源输出路径
publicPath: ''
},
//用于识别jsx
module: {
rules: [
{
test: /.jsx$/,//正则表达式
loader: 'babel-loader'
},
{
test: /.js$/,//正则表达式
exclude: path.join(__dirname, '../node_modules'),
loader: 'babel-loader'
}
]
},
plugins: [
//生成一个html文件,同时注入entry
new HTMLPlugin()
]
}
{
//babel默认编译es6 es7 es8 不认识jsx 需要配置
"presets": [
["es2015", {"loose": true}],
"react"
]
}
还记得我们在client端是通过把
渲染到document.body
中,
//应用入口
import React from 'react'
import ReactDom from 'react-dom'//把react渲染成dom
import App from './App.jsx'
ReactDom.render(<App/>, document.getElementById('root'))
可是服务端是没有document.body
的,这里暂且放一下,我们先来配置一下服务端webpack
const path = require('path')
module.exports = {
target: 'node',//表示webpack打包出来的js是使用在哪个平台的
//应用入口
entry: {
app: path.join(__dirname, '../client/server-entry.js')
},
//打包的文件路径
output: {
filename: 'server-entry.js',
path: path.join(__dirname, '../dist'),
//静态资源输出路径
publicPath: '',
libraryTarget: 'commonjs2'
},
//用于识别jsx
module: {
rules: [
{
test: /.jsx$/,//正则表达式
loader: 'babel-loader'
},
{
test: /.js$/,//正则表达式
exclude: path.join(__dirname, '../node_modules'),
loader: 'babel-loader'
}
]
},
}
接着来写服务端代码,这里用到了node的express框架
const express = require('express')
const ReactSSR = require('react-dom/server')
const fs = require('fs')
const path = require('path')
const template = fs.readFileSync(path.join(__dirname, '../dist/index.html'), 'utf8')
const serverEntry = require('../dist/server-entry').default
const app = express()
app.get('*', function(req, res) {
const appString = ReactSSR.renderToString(serverEntry)
res.send(template.replace(' ', appString))
})
app.listen(3333, function() {
console.log('listening on 3333')
})
服务端渲染的内容会替换前端模板
html中的标签
<html>
<head>
<title>Document</title>
</head>
<body>
<div id="root"><app></app></div>
</body>
</html>
它可以帮我们通过webpack启动一个服务,它的文件是存在在内存中的,每次有文件变化,它都会自动执行编译,这样就不需手动执行了。
有了它,只要文件有变化,页面就会自动刷新
代码仓库在此。