1. 服务端渲染的好处
SEO和首屏时间
2. 热替换
react-hot-reload(react-hot-reload不用刷新浏览器), (webpack-dev-server还是需要刷新浏览器)
3. 速成的代码
1). 分成client端, 借用webpack打包到dist下面。 将用于生成string的html加入替换的标记<!--app-->
2). 服务端node, 借助webpack(target:node), 生成压缩版的组件,读取导出的客户端组件; 然后读取index.html, 替换<!--app-->
3).。 调用renderToString(App), 返回string.
server.js
const express = require("express");
const path = require("path");
const React = require("react");
const { renderToString } = require("react-dom/server");
const { readFile: rf } = require("fs");
const { promisify } = require("util");
// const App = require("../client/app").default;
const App = require('../../dist/serverapp.js').default
const app = express();
const readFile = promisify(rf);
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const text = renderToString(App);
console.log(text);
app.get("/",async (req,res) => {
const content = renderToString(App);
// 读取打包出来的 HTML 文件
const str = await readFile(path.join(__dirname, "../../dist/index.html"));
// 把内容替换掉
const html = str.toString().replace("<!--app-->",content);
// 将页面发到前端
res.send(html);
});
// 打包生成的文件夹作为静态服务路径,这样静态文件就可以请求到了
app.use("/test",express.static(path.join(__dirname, "../../dist")));
app.listen(8001,() => {
console.log("Server is running: http://localhost:8001");
});
server->webpack.js
1 const path = require("path"); 2 3 module.exports = { 4 target:"node", 5 entry: path.join(__dirname, "./src/client/server-app.js"), 6 output: { 7 path: path.join(__dirname, "./dist"), 8 filename: "serverapp.js", 9 libraryTarget: "commonjs2" 10 }, 11 mode: "development", //production慢 12 module: { 13 rules: [ 14 { 15 test: /\.jsx?$/, 16 exclude: /node_modules/, 17 use: { 18 loader: "babel-loader", 19 }, 20 }, 21 ], 22 }, 23 resolve: { 24 extensions: [".js", ".jsx", ".mjs"], 25 }, 26 plugins: [] 27 };
client: webpackl
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: path.join(__dirname, "./src/client/index.js"),
output: {
path: path.join(__dirname, "./dist"),
filename: "bundle.js",
},
mode: "development", //production慢
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
],
},
resolve: {
extensions: [".js", ".jsx", ".mjs"],
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, "./src/client/index.html"),
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ["./dist"],
dry: false,
dangerouslyAllowCleanPatternsOutsideProject: true,
}),
],
devServer: {
hot:true,
host: 'localhost',
compress: true,
port: 8080
}
};
浙公网安备 33010602011771号