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

Posted

技术标签:

【中文标题】如何让 react-hot-loader 使用动态导入?【英文标题】:How to get react-hot-loader working with dynamic imports? 【发布时间】:2018-08-03 22:43:28 【问题描述】:

我看到了 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 -> ./assets/scripts/lib/components/bpm/MyClientProcessMenuLoader.jsx -> ./assets/scripts/app /containers/MyClientProcessMenuContainer.jsx -> ./assets/scripts/app/containers 惰性递归 ^./.$ -> ./node_modules/babel-loader/lib/index.js?"cacheDirectory":"/ usr/local/myproject/cache/babel","forceEnv":"development"!./assets/scripts/app/react_loader.js -> ./node_modules/bundle-loader/index.js!./assets/scripts /app/react_loader.js -> ./assets/scripts/app 递归 ./node_modules/bundle-loader/index.js!./ ^​​./.$ -> ./assets/scripts/lib/webpack .js -> ./assets/main.js -> 0

并且没有更新发生。

如何“接受”动态组件?

【问题讨论】:

你能分享你的.babelrcwebpack.config.js吗? @Aaqib 当然,这里:gist.github.com/mnpenner/298208c1a3e6151fc36858d306c1dda6 尝试安装babel-plugin-syntax-dynamic-import 并提供给.babelrc npmjs.com/package/babel-plugin-syntax-dynamic-import 中的plugins 数组 @Aaqib 我已经有了:gist.github.com/mnpenner/… 请在.babelrc插件数组github.com/gaearon/react-hot-loader中添加react-hot-loader/babel 【参考方案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();
        );
    

生产.js

import client from './client';


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

开发.js

import client from './client';

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

  client(Component);

【讨论】:

我认为我不能接受'./containers' -- 我收到一个错误:“无法解析'./containers'” @mpen 你的容器路径正确吗?看起来只有路径有问题。 是的,没错。 The docs 不要提及能够接受目录。 是的,你必须为我指定主文件,它是带有路由 if (module.hot) module.hot.accept('modules/layout', () =&gt; const newLayout = require('modules/layout').default; renderApp(newLayout); ); 布局的布局文件:``` routes.map(route => ( /> )) ```加上一些布局 我不认为这与动态导入有关。在您将动态导入引入代码之前,这真的有效吗?

以上是关于如何让 react-hot-loader 使用动态导入?的主要内容,如果未能解决你的问题,请参考以下文章

无法让多应用 webpack 配置与 react-hot-loader 一起使用

使用 react-hot-loader 包时如何自动删除 *.hot-update.json 文件?

无法解析 react-hot-loader/patch

获取“由于 0 不被接受而中止”并使用 react-hot-loader 重新加载整页

react-hot-loader 与外部 configureStore 使用 redux-saga 抛出“regeneratorRuntime 未定义”

react-hot-loader 3.0于1.3的区别