React SSR,如何利用webpack编译获得react注水js文件?
发布于 作者:苏南大叔 来源:程序如此灵动~
到目前为止,React SSR的代码使用姿势问题,已经讲的很明确了,应该可以应付绝大多数使用场景了。本文的内容把目光集中在“注水函数hydrateRoot()所在的.js文件”上。在目前的一系列react相关文章中,一直基于create-react-app的cra模版进行修改的,本文中所描述的代码,依然是基于这个cra模版的不断魔改版本。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程心得体会。本文测试环境:nodejs@20.18.0,create-react-app@5.0.1,react-router-dom@6.27.0,react@18.3.1。本文所叙述的内容,其实和SSR关联并不大。更多的关乎的是React程序的编译和运行。
区分目的性
实际上,对于普通的React程序渲染createRoot(),还是以注水为目的的hydrateRoot()。仅仅有一小部分代码不一致。那么,体现在index.js文件里面,代码参考:
普通版:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);| 关键函数 | 目的性 |
|---|---|
| createRoot() | react普通渲染 |
| hydrateRoot() | react注水 |
注水版:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.hydrateRoot(document.getElementById('root'),<App/>);
npm run build(create-react-app)
正常来说,react项目里面那么多的自定义的文件,以及node_modules里面的关联代码。因为使用了目前尚未被支持的语法,所以,需要使用babel进行编译成目前能理解的代码,然后合并处理成一个.js文件。
对于create-react-app构建的项目来说,把createRoot()替换成hydrateRoot()之后,执行npm run build命令。就可以在build/static/js/文件夹里面获得目标js文件了。改成需要的名字,放在合适的位置就行了。
npm run build实际执行的命令是:
react-scripts build
webpack + babelrc(自搭建环境)
如果不是标准的create-react-app项目,也可以利用webpack和babel生成目标js文件。参考文章:
- 自己搭建
webpack+react环境:https://newsn.net/say/webpack-react-diy.html
.babelrc文件如下:
{
"presets": [
"react-app",
"@babel/preset-env"
]
}webpack.config.js:
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/ssr.jsx',
output: {
filename: 'ssr.js',
path: path.resolve('dist'),
},
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
},
module: {
rules: [{
test: /\.jsx?$/,
use: 'babel-loader',
exclude: /node_modules/,
}],
},
};webpack.config.prod.js:
const path = require('path')
module.exports = {
mode: 'production',
entry: './src/ssr.jsx',
output: {
filename: 'ssr.prod.js',
path: path.resolve('dist'),
},
// devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
},
module: {
rules: [{
test: /\.jsx?$/,
use: 'babel-loader',
exclude: /node_modules/,
}],
},
};
src/ssr.jsx:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.hydrateRoot(document.getElementById('root'),<App/>);执行命令
package.json,新增两条命令:
{
"scripts": {
"build:ssr": "cross-env NODE_ENV=development webpack",
"build:ssr:prod": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
}
}执行命令:
npm run build:ssrnpm run build:ssr:prod
有关cross-env命令的安装和使用,可以参考文章:
webpack也可以根据需要开启watch参数,参考文章:
development 和 production
从上面的构建结果,可以看到:development的构建结果,文件是比较巨大的(高达1.5M左右)。而production的结果,则是比较的小巧,一百多K。所以,哪个文件适合于部署,是一目了然的。
| NODE_ENV | mode | sourcemap | 文件 |
|---|---|---|---|
| 无 | production | 开启 | main.9447f8ca.js(199kb) |
| development | development | 开启 | ssr.js(1.5M) |
| production | production | 关闭 | ssr.prod.js(197kb) |
顺便提一句,webpack.config.js里面的mode:production,也可以转移到webpack命令里面去。例如:
webpack --mode production结语
更多react经典经验文章,请参考苏南大叔的博客: