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 动态import的实现需要先搞懂webpack打包后产生的代码
从以上代码可以看出,webpack替换了import 和 index中依赖的模块Hello。
简化以后的代码如下:
所以这个自执行函数会运行__webpack_require__(0)(第0项内容就是去加载 src/index.js 中的代码)
__webpack_require__接受一个moduleId,就是modules参数的key。__webpack_require__内执行的模块的代码就是key对应的value。
这里多了执行__webpack_require__.r 和 webpack_require.e。可以看到打包后的hello.js中有这样有个promise链:
__webpack_require__.e(/*! import() */ 0) .then(__webpack_require__.bind(null, /*! ./async */ "./src/async.js"))
先去加载了bundle 0 也就是0.bundle.js, 也就是webpack code splitting 出的async.js。然后(then)执行async.js的代码。
webpack_require.r
webpack_require.e 先来看一下__webpack_require__.e内部的代码:
大致概括一下__webpack_require__.e的代码: 根据传入的chunkId,先检查是否已经加载过了,再检查是否正在加载, 否则的话创建加载script的promise,然后去加载chunk script。如果script加载失败(超时也算),那么执行chunk promise的reject。
从这步可以看到动态import的实现已经初露端倪。要完整的理解,还需要思考一个问题:上面script加载成功的chunk promise的resolve在什么时候执行?下面来看一下项目async.js打包出来的代码(去掉了一些注释):
这里重点要看window[“webpackJsonp”]。window[“webpackJsonp”] 在之前的自执行函数的匿名函数中有定义。并且window[“webpackJsonp”] 的push方法已经被重写为webpackJsonpCallback。下面就来看一下webpackJsonpCallback这个函数。
webpackJsonpCallback大致就是在做:将传入的chunkid(个人以为叫bundleid更合理)标记为已加载,并将传入的模块挂在到installedChunks对象上(缓存),最终执行 webpack_require.e 函数返回的promise的resolve,注意resolve也是从__webpack_require__.e 函数处理过的installedChunks上取的(installedChunks[chunkId] = [resolve, reject])
实现动态import的主要代码:
async () => { const res = await import("./async"); console.log(res.default()); }
对应打包后的代码:
async () => { const res = await __webpack_require__.e(/*! import() */ 0) .then(__webpack_require__.bind(null, /*! ./async */ "./src/ async.js")); console.log(res.default()); }
先执行__webpack_require__.e(0),把动态import的promise挂载到installedChunks上, 创建script 加载0.bundle.js, 返回promise
如果加载(超时也是)失败,在onScriptComplete中reject;如果加载成功,则执行加载过来的js:执行 window[webpackJsonp] 上的push方法(已经被重写为webpackJsonpCallback),将动态加载的模块(0.bundle.j)标记为已加载,并将模块(async.js)对应的代码挂载到modules参数上,最后resolve异步加载的模块。
在then后执行(webpack_require)挂载到modules参数上对应的模块(async.js)的代码
通过分析 webpack打包后的模板代码,可以看到webpack用IIFE的形式将所有模块作为modules参数传入,从entry模块开始依次执行modules,巧妙的处理了动态加载的模块。用 webpack_require 抹平了import和require之间的差异。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
要搞懂webpack 动态import的实现需要先搞懂webpack打包后产生的代码
webpack输出代码分析
从以上代码可以看出,webpack替换了import 和 index中依赖的模块Hello。
简化以后的代码如下:
所以这个自执行函数会运行__webpack_require__(0)(第0项内容就是去加载 src/index.js 中的代码)
__webpack_require__接受一个moduleId,就是modules参数的key。__webpack_require__内执行的模块的代码就是key对应的value。
这里多了执行__webpack_require__.r 和 webpack_require.e。可以看到打包后的hello.js中有这样有个promise链:
先去加载了bundle 0 也就是0.bundle.js, 也就是webpack code splitting 出的async.js。然后(then)执行async.js的代码。
webpack_require.r
webpack_require.e
先来看一下__webpack_require__.e内部的代码:
大致概括一下__webpack_require__.e的代码: 根据传入的chunkId,先检查是否已经加载过了,再检查是否正在加载, 否则的话创建加载script的promise,然后去加载chunk script。如果script加载失败(超时也算),那么执行chunk promise的reject。
从这步可以看到动态import的实现已经初露端倪。要完整的理解,还需要思考一个问题:上面script加载成功的chunk promise的resolve在什么时候执行?下面来看一下项目async.js打包出来的代码(去掉了一些注释):
这里重点要看window[“webpackJsonp”]。window[“webpackJsonp”]
在之前的自执行函数的匿名函数中有定义。并且window[“webpackJsonp”]
的push方法已经被重写为webpackJsonpCallback。下面就来看一下webpackJsonpCallback这个函数。
webpackJsonpCallback大致就是在做:将传入的chunkid(个人以为叫bundleid更合理)标记为已加载,并将传入的模块挂在到installedChunks对象上(缓存),最终执行 webpack_require.e 函数返回的promise的resolve,注意resolve也是从__webpack_require__.e 函数处理过的installedChunks上取的(installedChunks[chunkId] = [resolve, reject])
总结
实现动态import的主要代码:
对应打包后的代码:
先执行__webpack_require__.e(0),把动态import的promise挂载到installedChunks上, 创建script 加载0.bundle.js, 返回promise
如果加载(超时也是)失败,在onScriptComplete中reject;如果加载成功,则执行加载过来的js:执行 window[webpackJsonp] 上的push方法(已经被重写为webpackJsonpCallback),将动态加载的模块(0.bundle.j)标记为已加载,并将模块(async.js)对应的代码挂载到modules参数上,最后resolve异步加载的模块。
在then后执行(webpack_require)挂载到modules参数上对应的模块(async.js)的代码
通过分析 webpack打包后的模板代码,可以看到webpack用IIFE的形式将所有模块作为modules参数传入,从entry模块开始依次执行modules,巧妙的处理了动态加载的模块。用 webpack_require 抹平了import和require之间的差异。
The text was updated successfully, but these errors were encountered: