记一次react HMR使用

639 阅读1分钟

在umi/react-script/vite中的react都启用了HMR

自己使用webpack构建react项目中如何接入呢

以前使用的插件是react-hot-loader,官方推荐将插件改为react-refresh + pmmmwh/react-refresh-webpack-plugin

其配置是在webpack中

rules: [
    {
        test: /.js(x)?$/,
        exclude: /node_modules/,
        use: [
            {
                loader: "babel-loader",
                options: {
                    presets: [
                        "@babel/preset-env",
                        [
                            "@babel/preset-react",
                            {
                                "runtime": "automatic"
                            }
                        ],
                    ],
                    plugins: [require("react-refresh/babel")], // 添加,也可以加到.babelrc
                }
            },
        ]
    },
]
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

plugins: [
    new ReactRefreshWebpackPlugin({ // 添加
        overlay: false,
    })
],

但是项目中如果使用ts,则该方法并不能凑效。

我们官方推荐使用社区维护的插件react-refresh-typescript,注意,需ts4.0及以上。

移除babel插件@babel/preset-typescript,直接使用ts插件

const ReactRefreshTypeScript = require('react-refresh-typescript');

{
    test: /.(jsx|js|ts|tsx)$/,
    exclude: /node_modules/,
    use: [
        {
            loader: "babel-loader",
            options: {
                presets: [
                    "@babel/preset-env",
                    [
                        "@babel/preset-react",
                        {
                            "runtime": "automatic"
                        }
                    ],
                ],
                plugins: [require("react-refresh/babel")],
            }
        },
    ]
},
{
    test: /.(ts|tsx)$/,
    exclude: /node_modules/,
    use: [
        {
            loader: "ts-loader",
            options: {
                getCustomTransformers: () => ({
                    before: [ReactRefreshTypeScript()],
                }),
                transpileOnly: true,
            },
        },
    ],
},

上面那种方式则可在.babelrc中使用,或

const ReactRefreshTypeScript = require('react-refresh-typescript');

{
    test: /.(jsx|js|ts|tsx)$/,
    exclude: /node_modules/,
    use: [
        {
            loader: "babel-loader",
            options: {
                presets: [
                    "@babel/preset-env",
                    [
                        "@babel/preset-react",
                        {
                            "runtime": "automatic"
                        }
                    ],
                ],
                plugins: [require("react-refresh/babel")],
            }
        },
        {
            loader: "ts-loader",
            options: {
                getCustomTransformers: () => ({
                    before: [ReactRefreshTypeScript()].filter(Boolean),
                }),
                transpileOnly: true,
            },
        },
    ]
},

坑,入口文件的tsx无法HMR,只有组件中会生效

注意:以上的HMR配置需要区分环境,不要在生产中使用