React + Redux 开启 HMR/Hot Loader

首发于 http://szhshp.org/tech/2018/09/01/hmrwithreactandredux.html , 转载请注明

最近在用 React 以及 Redux 写几个项目, 使用的是官方 Create-React-App 的脚手架, 默认没有开启 HMR, 每次都要等他自动刷新也是挺烦的, 可以用这些方法实现热替换:

Create-React-App 开启热替换

如果没有使用 Redux, 单纯使用官方脚手架的话其实很简单, index.js 里面加上这句就可以:

  if (module.hot) {
    module.hot.accept();
  }

Create-React-App + Redux 开启热替换

如果按照上方的方法,直接开启热替换的话, 可能出现 state 被重置的问题。 比如我 toggle 了某个控件, 修改代码热替换完毕之后, 需要重新 toggle 一次, 因为 toggle 之后的状态被重置了,这个很可能是因为所有的状态都被 reduxProvider 接管了。

不过其实也有办法。

首先要安装三个重要的库:

npm install react-app-rewired react-app-rewire-hot-loader react-hot-loader

根目录创建一个 config-overrides.js 文件, 注意是在根目录,而不是在 src 文件夹下面:

  const rewireReactHotLoader = require('react-app-rewire-hot-loader');

  module.exports = function override(config, env) {
    config = rewireReactHotLoader(config, env);
    return config;
  }

如果使用的是普通的 Create-React-App 脚手架, 那么就直接修改 index.js:

  import React from 'react';
  import ReactDOM from 'react-dom';
  import './index.css';
  import App from './App';
  import registerServiceWorker from './registerServiceWorker';

  // Add this import:
  import { AppContainer } from 'react-hot-loader';

  // Wrap the rendering in a function:
  const render = Component => {
    ReactDOM.render(
      // Wrap App inside AppContainer
      
        
      ,
      document.getElementById('root')
    );
  };

  // Do this once
  registerServiceWorker();

  // Render once
  render(App);

  // Webpack Hot Module Replacement API
  if (module.hot) {
    module.hot.accept('./App', () => {
      render(App);
    });
  }

另外需要修改一下 package.json:

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test":  "react-scripts test --env=jsdom"
  }

修改成:

  "scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test":  "react-app-rewired test --env=jsdom"
}

启动的时候会自动寻找根目录下面的 config-overrides.js 文件, 然后所有的设置都全部完成, npm start 体验一下 HMR 吧。

参考文献

  • https://www.javascriptstuff.com/webpack-hmr-tutorial/

你可能感兴趣的:(NodeJS,Web)