【问题标题】:How can I get webpack-dev-server to stop downloading incorrect chunks on content change with React lazy/Suspense code splitting?如何让 webpack-dev-server 停止使用 React 延迟/Suspense 代码拆分在内容更改时下载不正确的块?
【发布时间】:2020-03-02 11:30:38
【问题描述】:

这是我的设置:

const DesktopApp = lazy(() => import(/* webpackChunkName: "DesktopApp" */'./DesktopApp'));
const MobileApp = lazy(() => import(/* webpackChunkName: "MobileApp" */'./MobileApp'));

type Props = { shouldServeMobile: boolean };

export const App = ({ shouldServeMobile }: Props): JSX.Element => (
  shouldServeMobile
    ? (
      <Suspense fallback={<AppLoading />}>
        <MobileApp />
      </Suspense>
    ) : (
      <Suspense fallback={<AppLoading />}>
        {/* GlobalDesktopStyle is injected in multiple places due to a bug where the
          theme gets reset when lazy loading via React.Lazy + webpack */}
        <GlobalDesktopStyle />
        <DesktopApp />
      </Suspense>
    )
);

这是由具有以下配置的webpack-dev-server 加载的:

  devServer: {
    contentBase: paths.output.path,
    // this host value allows devices on a LAN to connect to the dev server
    host: '0.0.0.0',
    https: true,
    port: 9001,
    hotOnly: true,
    // lets any URL work
    historyApiFallback: true,
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ]

现在,假设我们正在渲染

import { hot } from 'react-hot-loader/root';
// some imports omitted

const HotApp = hot(App);

ReactDOM.render(
  <HotApp shouldServeMobile={true} />,
  document.getElementById('root')
);

在初始加载时,这可以正常工作。 MobileApp 块下载,DesktopApp 不下载。但是,只要我更改了组件中的任何数据并且HMR 启动 - 重新加载就会下载DesktopApp 块。

这显然违背了代码拆分的目的。有谁知道如何阻止这种情况发生?

要明确:我输出了console.log(shouldServeMobile),它始终是true。另外,我在这里尝试了这个建议:Webpack-dev-server emits all chunks after every change,但它根本没有帮助。

【问题讨论】:

  • 为什么你需要react-hot-loader/root 而只是使用webpack hot reloader。 ?
  • @SakhiMansoor 我很确定这样反应钩子也可以热重载。设置好久了,可能记错了。代码分割是新的 - 使用这种热重载设置不是。但是是的 - 如果内存服务正确,没有它你就不能热重载钩子。

标签: reactjs webpack webpack-dev-server react-hot-loader react-suspense


【解决方案1】:

我认为这与react-hot-loader有关

https://github.com/gaearon/react-hot-loader

我们重新渲染 React 树的内部流程,这是在 React 尝试重新渲染之前协调更新的应用程序所必需的

所以我认为您使用的热加载器在设计上会尝试渲染整个树,而不管惰性或当前状态如何,以便协调更改。

要研究的选项可能不是像您那样热重新加载整个应用程序,而是在这些组件中分别热重新加载 &lt;MobileApp /&gt;&lt;DesktopApp /&gt;。这样,您可以保持应用程序对捆绑拆分的惰性,这在加载时有效,但热重载会根据正在使用的捆绑而变化。

【讨论】:

  • 考虑到react-hot-loader 是由Suspense/lazy 背后的主要人物之一制作的,并且考虑到react-hot-loader github README 有一个专门用于code splitting 的部分,它明确表示它支持@ 987654329@ - 我怀疑这就是问题所在。 (虽然它可能是)关于热重新加载单独组件的建议是一个很好的建议 - 但我已经共享了在该开关之上运行的逻辑,然后将不再在热重新加载中捕获。
  • 该仓库中有一些人在代码拆分方面存在问题。有些人根本无法让它工作,怀疑如果热重载通常工作,他们是否过于关心捆绑。如果你使用钩子,它看起来就像是一个废话。希望你能把它确定下来,对不起,不能提供更多帮助。
  • 这个答案不符合我的需求,但它可能在正确的轨道上并且信息丰富(并且不像另一个那样显然完全不知情和不正确)。我宁愿有人得到赏金也不愿让它过期,所以我把它给了你。虽然你给我的只是猜想,但不会将其作为正确答案来检查。
【解决方案2】:

应该有效:

    const DesktopApp = lazy(() => import(/* webpackChunkName: "DesktopApp" */'./DesktopApp'));
    const MobileApp = lazy(() => import(/* webpackChunkName: "MobileApp" */'./MobileApp'));

    type Props = { shouldServeMobile: boolean };

    export const App = ({ shouldServeMobile }: Props): JSX.Element => (
        <Suspense fallback={<AppLoading />}>
            shouldServeMobile
            ?
              <MobileApp />
            : <GlobalDesktopStyle />
              <DesktopApp />
         </Suspense>

    );

【讨论】:

    猜你喜欢
    • 2016-04-27
    • 2018-01-06
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2020-12-16
    • 2011-08-09
    • 2017-08-07
    相关资源
    最近更新 更多