引用工具模块导出的变量后,入口模块再执行它剩余的部分。至此,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); }) })
内容版权声明:除非注明,否则皆为本站原创文章。