美文网首页
React-Hot-Loader v3

React-Hot-Loader v3

作者: 472abb2e4941 | 来源:发表于2017-06-23 17:36 被阅读4132次

    安装

    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']
          }
        ]
      }
    }
    

    已知的局限性

    组件不会被替换

    • React Hot Loader 不会替换任何的组件, 只是 register 了它。
      • 当使用 webpack loader - 仅仅只有export 的模块会被 register
      • 当使用 babel plugin - 仅仅顶层的变量才会被 register
      • 当 React Hot Loader 不能替换 Component, 将会显示错误信息

    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)

    相关文章

      网友评论

          本文标题:React-Hot-Loader v3

          本文链接:https://www.haomeiwen.com/subject/bzgccxtx.html