Резервный вариант объединения модулей Webpack5 для неудачного сетевого вызова

#javascript #node-modules #federation #webpack-5

#javascript #узлы-модули #объединение #webpack-5

Вопрос:

Недавно я создал узел объединенного модуля, который объединяет верхний и нижний колонтитулы сайта. Все работает, как ожидалось, но я пытаюсь встроить несколько резервных вариантов, если запрос к объединенному хосту завершается неудачно.

 new ModuleFederationPlugin({
      name: 'app',
      remotes: {
        app2: 'app2@https:/example.com/remoteEntry.js',
        
      },
      shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true } },
    }),
  

Если я заблокирую запрос на https:/example.com/remoteEntry.js Я получаю сообщение об ошибке webpack ниже. В идеале я хотел бы загрузить базовый резервный заголовок или просто без заголовка, чем страница полностью умирает

 (error: https://example.com/remoteEntry.js1)
while loading "./Footer" from webpack/container/reference/app2
  

Комментарии:

1. Вы нашли какое-либо решение?

2. В этом руководстве Джека Херрингтона рассказывается о резервном варианте для npm-версии того же объединенного модуля. Вероятно, то, что вам нужно m.youtube.com/watch?v=K-yQB9YGmgE

Ответ №1:

Я знаю, что уже немного поздно, но я разработал это решение, и, возможно, оно может помочь кому-то еще с Webpack @ 5 и объединением модулей. Он также основан на динамических пультах дистанционного управления.

https://webpack.js.org/concepts/module-federation/#promise-based-dynamic-remotes

 new ModuleFederationPlugin({
      name: "app",
      remotes: {
        app2: `promise new Promise(resolve => {
          // This part depends on how you plan on hosting and versioning your federated modules
          const remoteUrlWithVersion = 'https:/example.com/remoteEntry.js'
          const script = document.createElement('script')
          script.src = remoteUrlWithVersion

          script.onload = () => {
            // the injected script has loaded and is available on window
            // we can now resolve this Promise
            const proxy = {
              get: (request) => {
                // Note the name of the module
                return window.app2.get(request);
              },
              init: (arg) => {
                try {
                  // Note the name of the module
                  return window.app2.init(arg)
                } catch(e) {
                  console.log('remote container already initialized')
                }
              }
            }
            resolve(proxy)
          }
          script.onerror = (error) => {
            console.error('error loading remote container')
            const proxy = {
              get: (request) => {
                // If the service is down it will render this content
                return Promise.resolve(() => () => "I'm dead");
              },
              init: (arg) => {
                return;
              }
            }
            resolve(proxy)
          }
          // inject this script with the src set to the versioned remoteEntry.js
          document.head.appendChild(script);
        })
        `
      },
      exposes: {},
      shared: {
        ...deps,
        react: {
          singleton: true,
          eager: true,
          requiredVersion: deps.react,
        },
        "react-dom": {
          singleton: true,
          eager: true,
          requiredVersion: deps["react-dom"],
        },
      },
    }),
  

Комментарии:

1. Как мы можем динамически изменять remoteUrlWithVersion, используя переменные среды?

Ответ №2:

Я нашел решение.

Проверьте эту статью https://habr.com/ru/post/554682 / — статья на русском языке, но вы можете воспользоваться переводчиком.

Обратите внимание на перехват — useDynamicScript и обработчики onload и onerror

Суть в том, чтобы независимо проверить, доступен ли он remoteEntry.js с удаленного хоста. Если remoteEntry.js недоступен, не загружайте удаленный компонент, в противном случае попробуйте загрузить. Вероятность того, что компонент загрузится в этом случае, очень высока.

Но если при загрузке remoteEntry.js возникнет ошибка, мы ее обработаем, и ошибка не будет выброшена на консоль.