如何让react-hot-loader使用动态导入?

时间:2018-02-23 19:48:54

标签: reactjs webpack react-hot-loader

我看到this answer显示了如何让react-hot-loader使用import()语法,但在我的情况下,直到运行时我才知道文件名。

这就是我所拥有的:

export default function(component, props, mountPoint) {

    function render() {
        import(`./containers/${component}`).then(({default: Component}) => {
            ReactDOM.render(
                <AppContainer>
                    <ErrorBoundary>
                        <Component {...props}/>
                    </ErrorBoundary>
                </AppContainer>, document.getElementById(mountPoint || 'react-root'));
        });
    }

    render();

    if(module.hot) {
        module.hot.accept('./containers', () => {
            render();
        });
    }

}

第一次加载工作正常,只是module.hot块不起作用。 Chrome告诉我:

  

未捕获(承诺)错误:找不到模块“./containers”

我的终端告诉我同样的事情:

  

警告在./node_modules/babel-loader/lib?{"cacheDirectory":"/usr/local/myproject/cache/babel","forceEnv":"development"}!./assets/scripts/app/ react_loader.js   找不到模块:错误:无法解析'/ usr / local / myproject / assets / scripts / app'中的'./containers'

如果我尝试接受./containers/${component},那么我会收到运行时错误:

  

忽略对未接受模块的更新./assets/scripts/lib/components/bpm/MyClientProcessMenu.jsx - &gt; ./assets/scripts/lib/components/bpm/MyClientProcessMenuLoader.jsx - &gt; ./assets/scripts/app/containers/MyClientProcessMenuContainer.jsx - &gt; ./assets/scripts/app/containers lazy recursive ^。/。 $ - &gt; ./node_modules/babel-loader/lib/index.js?{"cacheDirectory":"/usr/local/myproject/cache/babel","forceEnv":"development"}!./assets/scripts/app/react_loader .js - &gt; ./node_modules/bundle-loader/index.js!./assets/scripts/app/react_loader.js - &gt; ./assets/scripts/app recursive ./node_modules/bundle-loader/index.js!。/ ^。/。 $ - &gt; ./assets/scripts/lib/webpack.js - &gt; ./assets/main.js - &gt; 0

没有更新。

我如何“接受”动态组件?

1 个答案:

答案 0 :(得分:1)

我认为不复制代码当前不支持此功能。解决方法是,您可以创建两个文件,一个用于动态导入的生产文件,第二个不用于动态导入的开发文件。

具有动态导入的文件必须仅包含在生产中。这就是将环境逻辑移到其他文件(index.js)中的原因

index.js

// Neded because HMR doesn't work with dynamic import for languages
let app;
if (process.env.NODE_ENV === 'development') {
  app = require('./development').default;
} else {
  app = require('./production').default;
}
app(component);

client.js

export default function(Component) {

    function render() {
       ReactDOM.render(
         <AppContainer>
           <Component />
         </AppContainer>, document.getElementById('react-root'));
    }

    render();

    if(module.hot) {
        module.hot.accept('./containers', () => {
            render();
        });
    }
}

production.js

import client from './client';


export default function (component) {
  import(`./containers/${component}`).then(Component => {
    client(Component)
  });
}

development.js

import client from './client';

export default function (component) {
  const Component = require(`./containers/${component}`);

  client(Component);
}