Асинхронные чанки в веб-пакете могут быть созданы с помощью динамического импорта (например, import('./ModuleA.js');
). Теперь, если динамические чанки не загружаются, я хочу повторить попытку загрузки их из другого места.Подумав много об этой проблеме и изучив babel и webpack, я написал плагин babel, который присоединяет предложение catch к каждому динамическому импорту, а внутри предложение catch - я пытаюсь загрузить чанк из другого места (например, если первый чанк не загружается)из CDN, затем я попытаюсь загрузить его с сервера в пункте catch).
Чтобы загрузить чанк с сервера, я изменяю __webpack_public_path__
на домен сервера и затем вызываю __webpack_chunk_load__(chunkId);
chunkId доступен в объекте ошибки всякий раз, когда динамический импорт отклоняется.
Теперь возникает проблема с динамическим импортом маршрутов, если я использую
React.lazy(() => import(/* webpackChunkName: "ModuleA" */ './ModuleA'));
React.lazy()
, ожидаемый по умолчаниюПри экспорте компонента React, который должен быть возвращен, __webpack_chunk_load__(chunkId)
, загружает блок путем динамического внедрения тега сценария, но он не загружает модуль и возвращает module.exports
, что необходимо для React.lazy()
.
Внутренне,
React.lazy(() => import(/* webpackChunkName: "ModuleA" */ './ModuleA'));
будет преобразован в следующий код через веб-пакет:
react__WEBPACK_IMPORTED_MODULE_5___default.a.lazy(function () {
return Promise.resolve(__webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./ModuleA */ "./src/ModuleA.js")))
});
Теперь, как вы можете видеть, __webpack_require__.bind(null, /*! ./ModuleA */ "./src/ModuleA.js")
, возвращаетмодуль.экспорт.
Я могу выполнить загрузку асинхронного блока веб-пакета с использованием __webpack_chunk_load__(chunkId);
, но не могу вызвать __webpack_require__.bind(null, /*! ./ModuleA */ "./src/ModuleA.js")
, поскольку __webpack_require__
требует moduleId, который здесь недоступен.
IsЕсть ли способ вручную загрузить динамический чанк в веб-пакет?или как я могу получить moduleId
, чтобы позвонить __webpack_require__.bind(null, /*! ./ModuleA */ "./src/ModuleA.js")
Кроме того, это правильный путь для достижения этого, буду рад видеть любой другой подход.
Я использую следующий кодоговорка об улове,
filePath = error.request;
var chunkId = error.message.substring(error.message.indexOf('chunk') + 6 , error.message.indexOf('failed.') - 1);
return Promise.resolve(window.chunkLoad(chunkId)).then(window.webpackRequire.bind(null, window.dynamicModule));