我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

到目前为止,React SSR的代码使用姿势问题,已经讲的很明确了,应该可以应付绝大多数使用场景了。本文的内容把目光集中在“注水函数hydrateRoot()所在的.js文件”上。在目前的一系列react相关文章中,一直基于create-react-appcra模版进行修改的,本文中所描述的代码,依然是基于这个cra模版的不断魔改版本。

苏南大叔:React SSR,如何利用webpack编译获得react注水js文件? - react-ssr-complie
React SSR,如何利用webpack编译获得react注水js文件?(图5-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程心得体会。本文测试环境:nodejs@20.18.0create-react-app@5.0.1react-router-dom@6.27.0react@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/>);

苏南大叔:React SSR,如何利用webpack编译获得react注水js文件? - 代码目的性区分
React SSR,如何利用webpack编译获得react注水js文件?(图5-2)

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

苏南大叔:React SSR,如何利用webpack编译获得react注水js文件? - npm run build
React SSR,如何利用webpack编译获得react注水js文件?(图5-3)

webpack + babelrc(自搭建环境)

如果不是标准的create-react-app项目,也可以利用webpackbabel生成目标js文件。参考文章:

.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/,
        }],
    },
};

苏南大叔:React SSR,如何利用webpack编译获得react注水js文件? - webpack-config
React SSR,如何利用webpack编译获得react注水js文件?(图5-4)

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:ssr
npm run build:ssr:prod

苏南大叔:React SSR,如何利用webpack编译获得react注水js文件? - 不同的构建结果对比
React SSR,如何利用webpack编译获得react注水js文件?(图5-5)

有关cross-env命令的安装和使用,可以参考文章:

webpack也可以根据需要开启watch参数,参考文章:

development 和 production

从上面的构建结果,可以看到:development的构建结果,文件是比较巨大的(高达1.5M左右)。而production的结果,则是比较的小巧,一百多K。所以,哪个文件适合于部署,是一目了然的。

NODE_ENVmodesourcemap文件
production开启main.9447f8ca.js(199kb)
developmentdevelopment开启ssr.js(1.5M)
productionproduction关闭ssr.prod.js(197kb)

顺便提一句,webpack.config.js里面的mode:production,也可以转移到webpack命令里面去。例如:

webpack --mode production

结语

更多react经典经验文章,请参考苏南大叔的博客:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   react