React + Redux 开启 HMR/Hot Loader

1,494 阅读2分钟
原文链接: szhshp.org

React + Redux 开启 HMR/Hot Loader

2018-09-01

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

1. Create-React-App 开启热替换

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

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

2. 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
    <appcontainer>
      <app>
    </app></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 吧。

3. 参考文献