Как я могу заставить webpack-dev-server прекратить загрузку неверных фрагментов при изменении контента с помощью разделения кода React lazy/Suspense?

Вот моя установка:

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. Кроме того, я попробовал предложение здесь: все куски после каждого изменения и это совсем не помогло.


person thisissami    schedule 06.11.2019    source источник
comment
Зачем вам react-hot-loader/root вместо этого просто используйте webpack hot reloader. ?   -  person Sakhi Mansoor    schedule 11.11.2019
comment
@SakhiMansoor Я почти уверен, что реагирующие крючки также могут перезагружаться в горячем режиме. Давно не устанавливал, может что не так помню. Разделение кодов является новым - использование этой установки с горячей перезагрузкой - нет. Но да - если память не изменяет, без этого хуков горячей перезагрузки не обойтись.   -  person thisissami    schedule 12.11.2019


Ответы (2)


Я думаю, это связано с react-hot-loader

Согласно https://github.com/gaearon/react-hot-loader.

наши внутренние процессы повторного рендеринга дерева React, которые необходимы для согласования обновленного приложения, прежде чем React попытается его повторно отобразить.

Поэтому я думаю, что используемый вами горячий загрузчик, по замыслу, попытается отобразить все дерево, независимо от лени или текущего состояния, чтобы он мог согласовать изменения.

Вариант для изучения может быть вместо горячей перезагрузки всего приложения, как у вас, горячая перезагрузка <MobileApp /> и <DesktopApp /> отдельно с этими компонентами. Таким образом, вы можете сохранить ленивость приложения для разделения пакетов, которое работает при загрузке, но горячая перезагрузка меняется в зависимости от используемого пакета.

person Jake Luby    schedule 11.11.2019
comment
Учитывая, что react-hot-loader был сделан одним из основных людей, стоящих за Suspense/lazy, и учитывая, что в react-hot-loader github README есть раздел, посвященный code splitting, из которого ясно, что он поддерживает react.lazy - я сомневаюсь, что проблема в этом. (хотя это может быть) Предложение о горячей перезагрузке отдельных компонентов является хорошим, но у меня есть общая логика, которая работает над этим переключателем, которая затем больше не будет захватываться при горячей перезагрузке. - person thisissami; 12.11.2019
comment
В этом репо есть несколько человек, у которых есть проблемы с разделением кода. Некоторые вообще не могут заставить его работать, сомневаюсь, что они слишком заботятся о комплектации, если горячая перезагрузка вообще работает. И если вы используете крючки, это выглядит как дерьмо. Надеюсь, вы сможете прибить его, извините, больше ничем помочь не могу. - person Jake Luby; 12.11.2019
comment
Этот ответ не соответствует моим потребностям, но, вероятно, он находится на правильном пути и является информативным (и не совсем неосведомленным и неверным, как другой). Я бы предпочел, чтобы кто-то получил награду, чем чтобы срок ее действия истек, поэтому я отдал ее вам. Не буду проверять это как правильный ответ, хотя все, что вы мне дали, - это предположение. - person thisissami; 19.11.2019

Должно сработать:

    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>

    );
person Marty    schedule 18.11.2019