We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
原文地址
代码执行时机将决定着是否能够正常执行,当依赖文件没加载完成就开始执行、使用对应模块,那么将会导致执行异常。这在“存在资源加载失败时,加载重试影响原来文件的执行顺序”的场景下尤为常见。
webpack 构建除了进行模块依赖管理,实际上,也天然地管理了 entry 与 chunk 多文件的执行时机,但缺少了对 external 文件管理,当 external 文件加载失败或未完成时,执行、使用对应模块同样将导致异常。为此,wait-external-webpack-plugin 应运而生,以 webpack 插件的形式,补充 external 的执行管理。本文将进行简要说明。
将 webpack 打包后的代码进行简化,其实就是一个立即调用函数;传入“模块”,使用 webpack_require 进行调用。在单文件下,文件加载后将立即执行业务逻辑。
(function(modules) { // webpackBootstrap function __webpack_require__(moduleId) { // ... // 执行模块代码 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); } // 引用入口 return __webpack_require__(__webpack_require__.s = "./src/entryB.js"); })({ "./entryB.js": (function(module, __webpack_exports__, __webpack_require__) { // ... }) });
为了 “抽取公共模块进行单独打包避免重复加载” 或 “增加并发请求数减少总加载时间” 等原因,一般会将代码拆分成多文件,可使用如下形式:
拆分成多个文件后,为了避免业务逻辑执行时相关文件还没加载完成导致执行出错,需要等待相关文件都加载完成后再开始执行。
entry 与 其他 chunk 文件的 “等待-执行” 的逻辑,webpack 其实已经帮我们自动生成了。
// # entry.js // 声明依赖列表 deferredModules.push(["./src/entryA.js","commons"]); // 缓存已完成的加载 var installedChunks = { "entryA": 0 }; function webpackJsonpCallback(data) { // 加载后标记完成 installedChunks[chunkId] = 0; } // 检查是否都加载完成,如是,则开始执行业务逻辑 function checkDeferredModules() { // 判断 installedChunks 是否完整 // ... if(fulfilled) { // 所有都加载,开始执行 result = __webpack_require__(__webpack_require__.s = deferredModule[0]); } } // 提供给 chunk 的全局回调方法 var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; jsonpArray.push = webpackJsonpCallback;
chunk 文件加载后,正常情况下将调用 entry 提供的全局回调方法,标记加载完成。而当 chunk 文件先于 entry 加载完成,则会先缓存记录,等 entry 文件加载后读取缓存并将其标记完成。
// # chunk.js (window["webpackJsonp"] = window["webpackJsonp"] || []).push([["commons"],{ "./src/moduleA.js": (function(module, __webpack_exports__, __webpack_require__) { // ... }) }]);
基于以上分析,可以看出 entry 和 chunk 文件加载顺序不会影响执行时机,只有在都加载完成后,才会执行业务逻辑。如下图示
项目引用第三方库,一般会配置 external 让库单独加载。通过 webpack 生成的代码可以看出,配置 external 的模块在业务代码执行前将被当作已存在环境中,不做任何判断。所以当 external 文件未加载完成或加载失败时,使用对应模块将会导致执行出错。
"react": (function(module, exports) { eval("(function() { module.exports = window[\"React\"]; }());"); })
为了避免使用时出错,在执行前需先保证 external 文件已经加载完成。处理方式如下
示意代码:
(function () { var entryInit = function () { (function(modules) { // webpackBootstrap // ... })({}) }; if (window["React"]) { entryInit(); } else { var hasInit = false; var callback = function () { if(hasInit) return; if (window["React"]) { hasInit = true; document.removeEventListener('load', callback, true); entryInit(); } }; document.addEventListener('load', callback, true); } })();
等待 external 加载完成逻辑是统一的,差异在于依赖的 external 或有不同。为了避免手动添加出错,我们可以通过以 webpack 插件的形式自动分析依赖,并生成相关代码。
具体实现可见插件 wait-external-webpack-plugin
通过 wait-external-webpack-plugin 插件,能够自动生成等待依赖的 external 文件加载完成再执行逻辑,对开发者透明,保证文件对正常执行。
欢迎使用,欢迎任何意见或建议,谢谢。
查看更多文章 >> https://github.com/joeyguo/blog
The text was updated successfully, but these errors were encountered:
有两个问题
document.onload
window.onload
script
onload
Sorry, something went wrong.
@INCHMAN1900
No branches or pull requests
原文地址
代码执行时机将决定着是否能够正常执行,当依赖文件没加载完成就开始执行、使用对应模块,那么将会导致执行异常。这在“存在资源加载失败时,加载重试影响原来文件的执行顺序”的场景下尤为常见。
webpack 构建除了进行模块依赖管理,实际上,也天然地管理了 entry 与 chunk 多文件的执行时机,但缺少了对 external 文件管理,当 external 文件加载失败或未完成时,执行、使用对应模块同样将导致异常。为此,wait-external-webpack-plugin 应运而生,以 webpack 插件的形式,补充 external 的执行管理。本文将进行简要说明。
一、单文件
将 webpack 打包后的代码进行简化,其实就是一个立即调用函数;传入“模块”,使用 webpack_require 进行调用。在单文件下,文件加载后将立即执行业务逻辑。
二、多文件
为了 “抽取公共模块进行单独打包避免重复加载” 或 “增加并发请求数减少总加载时间” 等原因,一般会将代码拆分成多文件,可使用如下形式:
拆分成多个文件后,为了避免业务逻辑执行时相关文件还没加载完成导致执行出错,需要等待相关文件都加载完成后再开始执行。
2.1 等待 entry 与 chunk 文件都加载完成
entry 与 其他 chunk 文件的 “等待-执行” 的逻辑,webpack 其实已经帮我们自动生成了。
2.1.1 在生成的 entry 文件中
2.1.2 在生成的 chunk 文件中
chunk 文件加载后,正常情况下将调用 entry 提供的全局回调方法,标记加载完成。而当 chunk 文件先于 entry 加载完成,则会先缓存记录,等 entry 文件加载后读取缓存并将其标记完成。
2.1.3 小结
基于以上分析,可以看出 entry 和 chunk 文件加载顺序不会影响执行时机,只有在都加载完成后,才会执行业务逻辑。如下图示
2.2 等待 external 文件加载完成
项目引用第三方库,一般会配置 external 让库单独加载。通过 webpack 生成的代码可以看出,配置 external 的模块在业务代码执行前将被当作已存在环境中,不做任何判断。所以当 external 文件未加载完成或加载失败时,使用对应模块将会导致执行出错。
2.2.1 添加等待 external 文件加载完成再执行逻辑
为了避免使用时出错,在执行前需先保证 external 文件已经加载完成。处理方式如下
示意代码:
2.2.2 “自动”生成等待 external 文件加载完成再执行逻辑
等待 external 加载完成逻辑是统一的,差异在于依赖的 external 或有不同。为了避免手动添加出错,我们可以通过以 webpack 插件的形式自动分析依赖,并生成相关代码。
具体实现可见插件 wait-external-webpack-plugin
通过 wait-external-webpack-plugin 插件,能够自动生成等待依赖的 external 文件加载完成再执行逻辑,对开发者透明,保证文件对正常执行。
欢迎使用,欢迎任何意见或建议,谢谢。
查看更多文章 >>
https://github.com/joeyguo/blog
The text was updated successfully, but these errors were encountered: