详细解析Webpack是怎么运行的(4)

引用工具模块导出的变量后,入口模块再执行它剩余的部分。至此,Webpack 基本的模块执行过程就结束了。

好了,我们用流程图总结一下Webpack 模块的加载思路:

异步加载

有上面的打包我们发现将不同的打包进一个 main.js 文件。main.js 会集中消耗太多网络资源,导致用户需要等待很久才可以开始与网页交互。

一般的解决方式是:根据需求降低首次加载文件的体积,在需要时(如切换前端路由器,交互事件回调)异步加载其他文件并使用其中的模块。

Webpack 推荐用 ES import() 规范来异步加载模块,我们根据 ES 规范修改一下入口模块的 import 方式,让其能够异步加载模块:

src/index.js

console.log('Hello webpack!');
window.setTimeout(() => {
 import('./utils/math').then(mathUtil => {
 console.log('1 + 2: ' + mathUtil.plus(1, 2));
 });
}, 2000);

工具模块(src/utils/math.js)依然不变,在webpack 配置里,我们指定一下资源文件的公共资源路径(publicPath),后面的探索过程中会遇到。

const path = require('path');
const MyPlugin = require('./src/MyPlugin.js')
module.exports = {
 mode: 'development',
 devtool: 'source-map',
 entry: './src/index.js',
 output: {
 path: path.resolve(__dirname, 'dist'),
 publicPath: '/dist/'
 },
 plugins:[
 new MyPlugin()
 ]
};

接着执行一下打包,可以看到除了 dist/main.js 外,又多了一个 dist/0.js ./src/utils/math.js。模块从main chunk 迁移到了 0 chunk 中。而与 demo1 不同的是,main chunk 中添加了一些用于异步加载的代码,我们概览一下:

// webpackBootstrap
(function (modules) {
 // 加载其他 chunk 后的回调函数
 function webpackJsonpCallback(data) {
 // ...
 }
 // ...
 // 用于缓存 chunk 的加载状态,0 为已加载
 var installedChunks = {
 "main": 0
 };
 // 拼接 chunk 的请求地址
 function jsonpScriptSrc(chunkId) {
 // ...
 }
 // 同步 require 函数,内容不变
 function __webpack_require__(moduleId) {
 // ...
 }
 // 异步加载 chunk,返回封装加载过程的 promise
 __webpack_require__.e = function requireEnsure(chunkId) {
 // ...
 }
 // ...
 // defineProperty 的包装,内容不变
 __webpack_require__.d = function (exports, name, getter) {}
 // ...
 // 根据配置文件确定的 publicPath
 __webpack_require__.p = "/dist/";
 /**** JSONP 初始化 ****/
 var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
 var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
 jsonpArray.push = webpackJsonpCallback;
 jsonpArray = jsonpArray.slice();
 for (var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
 var parentJsonpFunction = oldJsonpFunction;
 /**** JSONP 初始化 ****/
 return __webpack_require__(__webpack_require__.s = "./src/index.js");
})({
 "./src/index.js": (function(module, exports, __webpack_require__) {
 document.write('Hello webpack!\n');
 window.setTimeout(() => {
  __webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./utils/math */ "./src/utils/math.js")).then(mathUtil => {
  console.log('1 + 2: ' + mathUtil.plus(1, 2));
  });
 }, 2000);
 })
})
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/1508.html