可以使用动态导入(例如import('./ModuleA.js');
)在webpack中创建异步块,现在,如果动态块无法加载,那么我想重试从其他位置加载它们。在对问题进行了很多思考并探索了babel和webpack之后,我编写了一个babel插件,将catch子句附加到每个动态import和内部catchs子句中,然后尝试从其他位置加载块(例如,如果第一个块无法加载从CDN,然后尝试在catch子句中从服务器加载它。
要从服务器加载块,我将__webpack_public_path__
更改为服务器域,然后调用
__webpack_chunk_load__(chunkId);
,只要动态导入拒绝,chunkId就会在错误对象中可用。
现在,如果我使用
,动态导入路径就会出现问题 React.lazy(() => import(/* webpackChunkName: "ModuleA" */ './ModuleA'));
React.lazy()
期望返回默认的React Component导出,__webpack_chunk_load__(chunkId)
,通过动态注入脚本标签来加载块,但不会加载模块并返回module.exports
由React.lazy()
。
内部
React.lazy(() => import(/* webpackChunkName: "ModuleA" */ './ModuleA'));
将通过webpack转换为以下代码,
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")
将返回module.exports。
我能够使用__webpack_chunk_load__(chunkId);
来实现webpack异步块的加载,但无法调用__webpack_require__.bind(null, /*! ./ModuleA */ "./src/ModuleA.js")
,因为__webpack_require__
需要的moduleId在此不可用。
有什么方法可以在Webpack中手动加载动态块吗?或如何让moduleId
呼叫__webpack_require__.bind(null, /*! ./ModuleA */ "./src/ModuleA.js")
此外,这是否是实现它的正确方法,也很乐意看到其他方法。
我在catch子句中使用以下代码,
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));
答案 0 :(得分:3)
您可以编辑默认的5次重试,直到它最终失败。
function retry(fn, retriesLeft = 5, interval = 1000) {
return new Promise((resolve, reject) => {
fn()
.then(resolve)
.catch((error) => {
setTimeout(() => {
if (retriesLeft === 1) {
// reject('maximum retries exceeded');
reject(error);
return;
}
// Passing on "reject" is the important part
retry(fn, retriesLeft - 1, interval).then(resolve, reject);
}, interval);
});
});
}
现在按如下所示使用此功能:
// Code split without retry
React.lazy(() => import("./ModuleA"));
// Code split with retry
React.lazy(() => retry(() => import("./ModuleA")));
此插件的唯一警告是将重试次数限制为1。但是,它节省了开发人员在每次动态导入时进行更改的时间。
希望这会有所帮助。