Обработка отсутствующих динамических фрагментов после нового развертывания с помощью webpack

У меня есть AngularJs (1.7) SPA с Webpack (4.x).

Вот как мы создаем имена чанков:

  config.output = {
    path: PATHS.build,
    publicPath: '/dist/',
    filename:  `[name]${isDev ? '' : '.[contenthash:8]'}.bundle.js`,
    chunkFilename: `chunks/[name]${isDev ? '' : '.[contenthash:8]'}.chunk.js`
  };

Ленивая загрузка выполняется в определениях состояний в ui-router в основном следующим образом:

  $stateProvider
    .state('reports', {
      url: '/projects/:project_id/reports',
      lazyLoad: function($transition$) {
        const injector = $transition$.injector().get('$injector');
        return import(/* webpackChunkName: "admin.reports.module" */ './reports')
          .then(mod => {
            injector.loadNewModules([mod.default]);
          })
          .catch(err => {
            throw new Error('An error occured, ' + err);
          });
      }
    })

После развертывания из-за изменений модуля в «динамическом» фрагменте - имя файла изменится в этом фрагменте ([contenthash] изменился).

Когда вошедший в систему пользователь (где загружены все связанные активы до последнее развертывание) теперь пытается открыть маршрут с новым фрагментом - фрагмента нет (404), и он завершится ошибкой с:

Transition Rejection($id: 4 type: 6, message: The transition errored, detail: Error: An error occured, Error: Loading chunk 14 failed.
(error: admin.reports.module.8fc31757.chunk.js))

Есть ли общий способ обойти / справиться с этим?

Может быть, в целом: как можно обнаружить изменения в связанном веб-приложении? Есть ли обычный способ вызвать перезагрузку? Всегда ли требуется обновление вручную?

5
0
1 637
1

Ответы 1

Я думаю, что есть несколько способов обойти это, поскольку javascript в текущем контексте не знает нового хэша контента, созданного последней сборкой, которую вы могли бы попробовать:

1.) Вы можете попробовать настроить http-редирект для хешированных файлов: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections Браузер запросит старый файл, и сервер может указать на новый файл вместо того, чтобы возвращать 404. Если все ваши файлы следуют соглашению и сохраняют только один файл за раз, например: component.hash.js, тогда это должно быть довольно легко.

2.) Хакерский клиентский подход будет обрабатывать отклонение перехода в попытке поймать и перезагрузить страницу без кеша для получения новых ресурсов. https://developer.mozilla.org/en-US/docs/Web/API/Location/reload

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

Я согласен с тем, что существует несколько подходов, но я ищу общий подход, который уже доказал свою эффективность. Перенаправление к новому файлу затруднено, потому что в имени файла есть хэш из содержание файла. Это можно сделать с помощью манифеста из Webpack. Может, кто-то делал это раньше?

madflow 03.11.2018 14:05

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

madflow 03.11.2018 14:07

Другие вопросы по теме