解析webpackv5.68.0编译后的main文件
webpack根据entry入口文件,生成一个main.js的主文件,此文件运用闭包立即调用的机制
main文件的四块逻辑
- 初始化全局的module内容,仅包含同步文件的代码
- 模块的缓存以及加载模块函数
- webpack各种运行时的函数方法
- 加载入口文件代码
关于更多的weboack运行时函数,可看webpack/lib/RuntimeGlobals.js文件
// 闭包形式(() => {// 第一个逻辑: 初始化全局的module内容,仅包含同步文件的代码var webpack = ({'xxx.js': ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {// 文件内容...}),// ....等});/************************************************************************/// 第二个逻辑: 模块的加载存储对象和存储函数var __webpack_module_cache__ = {};// 获取模块对象的函数function __webpack_require__(moduleId) {};__webpack_require__.m = __webpack_modules__;/************************************************************************/// 第三个逻辑: webpack各种运行时的函数方法,全都已闭包自执行的方式运行/* webpack/runtime/define property getters */(() => {__webpack_require__.d = (exports, definition) => {}})();(() => {__webpack_require__.r = (exports) => {}})();// ...等运行时函数/************************************************************************/// 第四个逻辑: 加载入口文件代码var __webpack_exports__ = {};(() => {__webpack_require__.r(__webpack_exports__);__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__, {"testField": () => (/* binding */ 'testField')});__webpack_require__(/*! ./remote */ "xxx.js");})();})();
script load function
// js 文件的加载方法// __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);// url: js路径// loadingEnded: js 文件加载失败时的回调方法// "chunk-" + chunkId: js + chunk合并的js路径名称// chunkId: 编译后的文件对应的chunkId名称/* webpack/runtime/load script */(() => {var inProgress = {};var dataWebpackPrefix = "webpack-app:";__webpack_require__.l = (url, done, key, chunkId) => {// 如果正在加载js文件,就等待if(inProgress[url]) { inProgress[url].push(done); return; }var script, needAttach;if(key !== undefined) {// 遍历查找,查看js文件是否已经加载完成var scripts = document.getElementsByTagName("script");for(var i = 0; i < scripts.length; i++) {var s = scripts[i];if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; }}}// 资源未加载的情况下,创建资源加载if(!script) {needAttach = true;script = document.createElement('script');script.charset = 'utf-8';script.timeout = 120;if (__webpack_require__.nc) {script.setAttribute("nonce", __webpack_require__.nc);}script.setAttribute("data-webpack", dataWebpackPrefix + key);script.src = url;}inProgress[url] = [done];// script资源完成的情况var onScriptComplete = (prev, event) => {script.onerror = script.onload = null;clearTimeout(timeout);var doneFns = inProgress[url];delete inProgress[url];script.parentNode && script.parentNode.removeChild(script);doneFns && doneFns.forEach((fn) => (fn(event)));if(prev) return prev(event);}// script资源加载超时var timeout = setTimeout(onScriptComplete.bind(null,undefined,{ type: 'timeout', target: script }),120000);// script资源的事件监听script.onerror = onScriptComplete.bind(null, script.onerror);script.onload = onScriptComplete.bind(null, script.onload);needAttach && document.head.appendChild(script);};})();
