React-Hot-Loader v3

2017-06-23  本文已影响4132人  472abb2e4941

安装

npm install --save react-hot-loader

注意: 你可以 install react-hot-loader 作为一个常规的 dependency,而不是 dev dependency,因为它会自动的确保不会在生产环境执行,并且它留下的痕迹是非常小的。

开始使用

  1. .babelrc 里面增加 react-hot-loader/babel
// .babelrc
{
  "plugins": ["react-hot-loader/babel"]
}
  1. Enable Hot Module Replacement in Webpack

  2. 在Webpack config 的 entry 最顶部(除开polyfills)添加 react-hot-loader/patch:

// webpack.config.js
module.exports = {
  entry: [
    'babel-polyfill',
    'react-hot-loader/patch',
    './main.js'
  ]
}

注意:保证把 output.publicPath 属性设置成 "/"。以保证 hot reloading 会在嵌套的路由有效。

  1. 把你的应用包裹在 <AppContainer>,当发生更新所有 <AppContainer> 的 children 会 reloaded。
// main.js
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from './containers/App'

const render = Component => {
  ReactDOM.render(
    <AppContainer>
      <Component />
    </AppContainer>,
    document.getElementById('root'),
  )
}

render(App)

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

为了使上面有效,你需要不使用 Babel 编译 ES2015 的模块,通过把 Babel ES2015 的 preset 改为 ["es2015", { "modules": false }]

使用 Webpack loader 取代 Babel plugin

也许你没有在你的工程里面使用 Babel, React Hot Loader 提供了一个 Webpack loader 可以提供一些限制性的功能,如果你想用它,你可以添加到你 Webpack config里面。如果你不使用babel,你不需要增加这个loader

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: ['react-hot-loader/webpack']
      }
    ]
  }
}

已知的局限性

组件不会被替换

Code Splitting

如果你想使用 Webpack 通过 require.ensure 切割代码,你必须在 require.ensure 代码块增加额外的 module.hot.accept 回调, 就像这样:

require.ensure([], (require) => {
  if (module.hot) {
    module.hot.accept('../components/App', () => {
      loadComponent(require('../components/App').default);
    })
  }
  loadComponent(require('../components/App').default);
});

注意如果你使用 React Router (4.0版本之前), 这个只会对 getChildRoutes 有效, 但对 getComponent 无效, 因为 getComponent's 的回调只会加载 component 一次。

同样, 如果你使用 Webpack 2 beta, 你可以使用 System.import 而不需要额外的 module.hot.accept 调用, 当然这里现在有一些 issues .

检查 Element 的 type

因为 React Hot Loader 为你的组件创建了一个 proxy 的版本,比较 element 的type引用是没有用的:

const element = <Component />;
console.log(element.type === Component); // false

有一种变通的方法,创建一个 element (它会有被 proxy 组件的 type属性 ):

const ComponentType = (<Component />).type;
const element = <Component />;
console.log(element.type === ComponentType); // true

你同样可以在 component 的 class 上设置一个属性:

const Widget = () => <div>hi</div>;
Widget.isWidgetType = true;
console.log(<Widget />.type.isWidgetType); // true

重新对 Component 赋值

React Hot Loader 将会 reload 原来组件引用,所以当你把另外一个变量重新赋值给该组件时,就像下面一样:

let App = () => (<div>hello</div>);
App = connect()(App);
export default App;

React Hot Loader 将不会重新 reload, 你必须重新定义一次:

const App = () => (<div>hello</div>);
export default connect()(App);

Decorators

Components 如果被 decorated 过(比如用 @autobind),现在这种情况当 hot-reloaded 不会保留 state。(参看#279)

上一篇下一篇

猜你喜欢

热点阅读