快如闪电的 react-refresh

10,915 阅读1分钟

最近被安利了最新的 react 热更新插件, 今天安利给大家 react-refresh-webpack-plugin,目前 github 上已经有 1.4k star

介绍

  1. 热更新的意思是不用刷新页面,简单的讲,就是使用 react 编写代码时,能让修改的部分自动刷新。但这和自动刷新网页是不同的,因为 hot-loader 并不会刷新网页,而仅仅是替换你修改的部分,也就是 without losing state
  2. 这个插件官网也说了,也不是百分百稳定,不过我用了发现啥大问题

兼容性

依赖 最低 最佳
react 16.9.0 16.13.0+
react-dom 16.9.0 16.13.0+
react-reconciler 0.22.0 0.25.0+
webpack 4.0.0(对于0.3.x)4.43.0(对于0.4.x+ 4.43.0+

可以看出目前版本要求很高,不过还处在第一版,希望以后能够用到老项目

安装

npm install -D type-fest
yarn add -D type-fest
pnpm add -D type-fest

使用

下面放一些常用的三种配置

webpack-dev-server

// package.json  "start": "webpack-dev-server --hot",
const path = require('path');
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const isDevelopment = process.env.NODE_ENV !== 'production';

module.exports = {
  mode: isDevelopment ? 'development' : 'production',
  entry: {
    main: './src/index.js',
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        include: path.join(__dirname, 'src'),
        use: 'babel-loader',
      },
    ],
  },
  plugins: [
    isDevelopment && new ReactRefreshPlugin(),
    new HtmlWebpackPlugin({
      filename: './index.html',
      template: './public/index.html',
    }),
  ].filter(Boolean),
  resolve: {
    extensions: ['.js', '.jsx'],
  },
};

webpack-hot-middleware

webpack.dev.js

const devMode = process.env.NODE_ENV !== 'production';
// ...
    {
        test: /\.(jsx|js)$/,
        exclude: /node_modules/,
        use: [
            {
                loader: require.resolve('babel-loader'),
                options: {
                    plugins: devMode ? [require.resolve('react-refresh/babel')] : [],
                },
            },
        ],
    },

webpack.prod.js

const devMode = process.env.NODE_ENV !== 'production';
// ...
    plugins: [
        // ...,
        new webpack.HotModuleReplacementPlugin(),
        devMode && new ReactRefreshWebpackPlugin(),
    ],

ts

module.exports = {
  mode: isDevelopment ? 'development' : 'production',
  entry: {
    main: './src/index.tsx',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        include: path.join(__dirname, 'src'),
        use: [
          isDevelopment && {
            loader: 'babel-loader',
            options: { plugins: ['react-refresh/babel'] },
          },
          {
            loader: 'ts-loader',
            options: { transpileOnly: true },
          },
        ]
      },
    ],
  },
  plugins: [
    isDevelopment && new ReactRefreshPlugin(),
  ]
};

测试

从结果可以看出快如闪电,目前已经用上了暂时没发现什么大问题,希望下一步能够支持17,毕竟17是个超融合版本,老项目可以无痛升级17

本文使用 mdnice 排版