如今Webpack已经是一个不可或缺的前端构建工具,借助这个构建工具,我们可以使用比较新的技术(浏览器不能直接支持)来开发。

你是否好奇你写的代码经过Webpack构建之后会生成什么东西?是否有时调试遇到莫名其妙的问题?

本文不讲如何进行配置,只是基于几个基础的例子,简要分析一下 webpack@4.20.2 构建后的代码结构,当然了,并不全面,时间问题能力问题还不能理解到位。

代码比较长,生成的代码也比较晦涩比较绕,也可能条理不顺,客官坐好咧~

一、Webpack的运行机制

Webpack的运行过程实际上可以归纳为这个步骤

读取配置参数 -> 相关事件绑定(插件参与) ->  识别各入口Entry模块 -> 编译文件(loader参与)-> 生成文件

首先读取我们的配置文件如 webpack.config.js,然后事件流就参与进来绑定相关的事件,Webpack中的事件使用 Tapable 来管理,在这一阶段,除了绑定webpack内置的一大堆事件之外,还支持自定义的一些事件处理。

配置中的 plugins部分,实际上也可以看作是一些自定义的事件处理,因为插件将在定义的”相关时刻“插入到编译过程中处理资源,这里的”相关时刻“指的就是 订阅-发布 模式中的发布环节

Webpack编译结果浅析-LMLPHP

webpack支持多个入口模块,所以还需要进行各入口模块的分析(这里的入口模块只能为JS模块),比如以下两个入口模块

Webpack编译结果浅析-LMLPHP

分析完入口模块,接下来分析该模块的依赖,并使用相关loader进行编译(如果需要loader的话),真正的编译环节是在这里。

期间会使用AST抽象语法树来分析语法,直到编译完成,输出到相应的文件中

可以来看看这篇文章 Webpack运行机制

二、Webpack编译结果

由最简单的例子开始

2.1 无依赖的单个模块

./main.js

console.log('main');

./webpack.config.js

module.exports = {
    // entry: './main',
    entry: {
        main: './main'
    },

    mode: 'none',

    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    }
};

注意,在webpack4中默认的mode对 development和production进行了一些特殊配置,为了简化,这里就设置成none

编译一个文件,将在dist目录中生成

Webpack编译结果浅析-LMLPHP

./dist/main.js

 1 /******/ (function(modules) { // webpackBootstrap
 2 /******/     // The module cache
 3 /******/     var installedModules = {};
 4 /******/
 5 /******/     // The require function
 6 /******/     function __webpack_require__(moduleId) {
 7 /******/
 8 /******/         // Check if module is in cache
 9 /******/         if(installedModules[moduleId]) {
10 /******/             return installedModules[moduleId].exports;
11 /******/         }
12 /******/         // Create a new module (and put it into the cache)
13 /******/         var module = installedModules[moduleId] = {
14 /******/             i: moduleId,
15 /******/             l: false,
16 /******/             exports: {}
17 /******/         };
18 /******/
19 /******/         // Execute the module function
20 /******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 /******/
22 /******/         // Flag the module as loaded
23 /******/         module.l = true;
24 /******/
25 /******/         // Return the exports of the module
26 /******/         return module.exports;
27 /******/     }
28 /******/
29 /******/
30 /******/     // expose the modules object (__webpack_modules__)
31 /******/     __webpack_require__.m = modules;
32 /******/
33 /******/     // expose the module cache
34 /******/     __webpack_require__.c = installedModules;
35 /******/
36 /******/     // define getter function for harmony exports
37 /******/     __webpack_require__.d = function(exports, name, getter) {
38 /******/         if(!__webpack_require__.o(exports, name)) {
39 /******/             Object.defineProperty(exports, name, { enumerable: true, get: getter });
40 /******/         }
41 /******/     };
42 /******/
43 /******/     // define __esModule on exports
44 /******/     __webpack_require__.r = function(exports) {
45 /******/         if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
46 /******/             Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
47 /******/         }
48 /******/         Object.defineProperty(exports, '__esModule', { value: true });
49 /******/     };
50 /******/
51 /******/     // create a fake namespace object
52 /******/     // mode & 1: value is a module id, require it
53 /******/     // mode & 2: merge all properties of value into the ns
54 /******/     // mode & 4: return value when already ns object
55 /******/     // mode & 8|1: behave like require
56 /******/     __webpack_require__.t = function(value, mode) {
57 /******/         if(mode & 1) value = __webpack_require__(value);
58 /******/         if(mode & 8) return value;
59 /******/         if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
60 /******/         var ns = Object.create(null);
61 /******/         __webpack_require__.r(ns);
62 /******/         Object.defineProperty(ns, 'default', { enumerable: true, value: value });
63 /******/         if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
64 /******/         return ns;
65 /******/     };
66 /******/
67 /******/     // getDefaultExport function for compatibility with non-harmony modules
68 /******/     __webpack_require__.n = function(module) {
69 /******/         var getter = module && module.__esModule ?
70 /******/             function getDefault() { return module['default']; } :
71 /******/             function getModuleExports() { return module; };
72 /******/         __webpack_require__.d(getter, 'a', getter);
73 /******/         return getter;
74 /******/     };
75 /******/
76 /******/     // Object.prototype.hasOwnProperty.call
77 /******/     __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
78 /******/
79 /******/     // __webpack_public_path__
80 /******/     __webpack_require__.p = "";
81 /******/
82 /******/
83 /******/     // Load entry module and return exports
84 /******/     return __webpack_require__(__webpack_require__.s = 0);
85 /******/ })
86 /************************************************************************/
87 /******/ ([
88 /* 0 */
89 /***/ (function(module, exports) {
90
91
92 console.log('main');
93
94
95 /***/ })
96 /******/ ]);

可以看到首先是一个匿名函数,在87行时自执行传入

[
/* 0 */
/***/ (function(module, exports) {


console.log('main');


/***/ })
/******/ ]

这个是modules,表示有一个模块需要加载

第3行使用 installedModules 来缓存已经加载的模块

webpack由最初支持 commonjs模块规范,到后来要支持es6的模块等,为了兼容不同的模块机制,定义了一个 __webpack_require__ 函数作为webpack内部的require

/******/     // The require function
/******/     function __webpack_require__(moduleId) {
/******/
/******/         // Check if module is in cache
                // 如果模块已经加载则直接使用
/******/         if(installedModules[moduleId]) {
/******/             return installedModules[moduleId].exports;
/******/         }
/******/         // Create a new module (and put it into the cache)
/******/         var module = installedModules[moduleId] = {
/******/             i: moduleId, // 模块ID
/******/             l: false, // 模块是否已加载
/******/             exports: {} // 模块的导出项
/******/         };
/******/
/******/         // Execute the module function
/******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/         // Flag the module as loaded
/******/         module.l = true; // 标记已经加载
/******/
/******/         // Return the exports of the module
/******/         return module.exports; // 返回模块的导出项目
/******/     }

其中,这个调用非常重要

modules[moduleId].call(module.exports, module, module.exports, __webpack_require__)

结合匿名函数传入的参数来看,modules[moduleId] 其实就是这个

(function(module, exports) {


console.log('main');


/***/ })

第一个参数 module.exports 实际上就是上面模块的导出项,是为了保证this能正确地指向module,第二第三个参数按着顺序来,第四个参数一般用于依赖

因为这里 main.js没有依赖其他模块,所以没有传进来

最后 return module.exports; 实际上就是返回了模块的导出项,在上面的84行中,入口模块被引入 。从而自动地加载第一个模块并执行

return __webpack_require__(__webpack_require__.s = 0); // __webpack_require__.s为入口文件,此处引用模块ID

另外再看其它代码,

/******/     // expose the modules object (__webpack_modules__)
/******/     __webpack_require__.m = modules; // 将模块存起来
/******/
/******/     // expose the module cache
/******/     __webpack_require__.c = installedModules; // 将已经加载的模块存起来

/******/     // __webpack_public_path__
/******/     __webpack_require__.p = ""; // 设置的 publicPath

这里没什么可说的,这里的publicPath对应于 output中的配置,如

output: {
        publicPath: './dist/',
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    },

另外

/******/     // define getter function for harmony exports
/******/     __webpack_require__.d = function(exports, name, getter) {
/******/         if(!__webpack_require__.o(exports, name)) {
/******/             Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/         }
/******/     };
/******/
/******/     // define __esModule on exports
/******/     __webpack_require__.r = function(exports) {
/******/         if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/             Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/         }
/******/         Object.defineProperty(exports, '__esModule', { value: true });
/******/     };

/******/     // Object.prototype.hasOwnProperty.call
/******/     __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };

这里 __webpack_require__.o 这里只是hasOwnProperty的包装

__webpack_require__.d 这里是对exports定义一个属性(当前模块未用到,暂且如此,理解不到位)

__webpack_require__.r 这里是对es6模块中的export的支持(当前模块未用到,暂且如此,理解不到位)

还有这个,这个就更难理解了

/******/     // create a fake namespace object
/******/     // mode & 1: value is a module id, require it
/******/     // mode & 2: merge all properties of value into the ns
/******/     // mode & 4: return value when already ns object
/******/     // mode & 8|1: behave like require
/******/     __webpack_require__.t = function(value, mode) {
/******/         if(mode & 1) value = __webpack_require__(value);
/******/         if(mode & 8) return value;
/******/         if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/         var ns = Object.create(null);
/******/         __webpack_require__.r(ns);
/******/         Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/         if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/         return ns;
/******/     };
/******/
/******/     // getDefaultExport function for compatibility with non-harmony modules
/******/     __webpack_require__.n = function(module) {
/******/         var getter = module && module.__esModule ?
/******/             function getDefault() { return module['default']; } :
/******/             function getModuleExports() { return module; };
/******/         __webpack_require__.d(getter, 'a', getter);
/******/         return getter;
/******/     };

__webpack_require__.t 暂时不说明了,还看不懂怎么调用的..

__webpack_require__.n 这个主要也是为 es6模块服务的,也没能理解好,知道的可以在评论区留言哈~

2. 有依赖的单个模块

先使用最基础的commonjs模块规范  require, exports ,module.exports 有助于理解上面那个模块的导出项目

./main.js

let number = require('./number');

console.log('main', number);

./number.js

let n = 10;

exports.n = n;

编译后,生成的文件变化的只是匿名函数传入的部分

Webpack编译结果浅析-LMLPHP

./dist/main.js

// 省略

/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {


let number = __webpack_require__(1);

console.log('main', number);


/***/ }),
/* 1 */
/***/ (function(module, exports) {


let n = 10;

exports.n = n;


/***/ })
/******/ ]);

注意到前面的数字即是模块的ID,也可图中的一致

这里__webpack_require__参数被传进来,main.js中引入number这个模块 __webpack_require__(1);

number模块中 exports.n = n,注意这里的 exports即是调用时的第二个参数

modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

所以此时 n属性被存入module的export导出项中,从而__webpack_require__(1) 就能获取这个导出项

换种方式,使用es6的模块导出

更改 ./number.js

let n = 10;

export {
    n
};

编译后 ./dist/main.js

/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {


let number = __webpack_require__(1);

console.log('main', number);


/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "n", function() { return n; });

let n = 10;




/***/ })
/******/ ]);

可以看到模块1变了,为了兼容 export ,使用 __webpack_require__.r 定义了它为es6模块,再使用__webpack_require__.d 将 n保存到模块的导出项中

Webpack编译结果浅析-LMLPHP

__webpack_require__.d 函数中的 getter即为 这里的 function() { return n; },通过设置为对象的get属性,可以获取到 n这个返回值

var o = {};

Object.defineProperty(o, 'abc', {
    get: function() {
        return 123;
    }
});

console.log(o.abc); // 123

所以将 let n = 10 定义在后面也是没问题的,因为getter是在number模块被调用返回之后才使用的

接着,我们把引入依赖文件改为import

./main.js

import {n} from './number';

console.log('main', n);

编译后 ./dist/main.js

/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);



console.log('main', _number__WEBPACK_IMPORTED_MODULE_0__["n"]);


/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "n", function() { return n; });

let n = 10;




/***/ })
/******/ ]);

同样的,这时main模块用到了es6的模块引入方式,所以 __webpack_require__.r(__webpack_exports__);

var _number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);

这个 __webpack_require__(1) 实际上就是 number模块的模块导出项,自然就能取到属性 n 了

接下来,着眼那个 default字眼,继续更换模块的导入导出方式

./main.js

import n from './number';

console.log('main', n);

./number.js

let n = 10;

export default n;

./dist/main.js

/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);



console.log('main', _number__WEBPACK_IMPORTED_MODULE_0__["default"]);


/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);

let n = 10;

/* harmony default export */ __webpack_exports__["default"] = (n);


/***/ })
/******/ ]);

可以看到,变化只是属性变成了default

再来一种 es6的方式

./main.js

import n from './number';

console.log('main', n);

./number.js

import {str as n} from './str';

export default n;

./str.js

export var str = 10;

编译后

Webpack编译结果浅析-LMLPHP

./dist/main.js

/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);



console.log('main', _number__WEBPACK_IMPORTED_MODULE_0__["default"]);


/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _str__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);



/* harmony default export */ __webpack_exports__["default"] = (_str__WEBPACK_IMPORTED_MODULE_0__["str"]);


/***/ }),
/* 2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "str", function() { return str; });
var str = 10;


/***/ })
/******/ ]);

可以看到 {str as n} 也是没什么影响的,通过上面的例子应该基本能理解模块的依赖了

3. 多个入口模块

如果不提取多模块之间的公共部分,多个入口模块和单个的不同之处就是多了一个文件而已,它们是独立的。

所以这里就不多说了

4. 异步加载模块

webpack支持使用require.ensure来异步加载模块

./main.js

console.log('main');

setTimeout(() => {
    require([], (require) => {
        let number = require('./number');

        console.log(number.n);
    });
}, 1000);

./number.js

let n = 10;

export {
    n
};

webpack.config.js中要加上 publicPath,防止异步模块加载路径出错

output: {
        publicPath: './dist/',
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    }

编译后,生成的 1.js即为异步的模块number

Webpack编译结果浅析-LMLPHP

./dist/1.js

(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],[
/* 0 */,
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "n", function() { return n; });


let n = 10;




/***/ })
]]);

可以看到,这里首先获取 (window["webpackJsonp"] = window["webpackJsonp"] || []), 再调用 push 传入模块及其依赖

jsonp类似我们跨域中的动态插入脚本,这里也是一样,动态插入一个script标签,把src设置好就加载这个异步模块了

push参数中第一个为当前异步模块

看看 ./dist/main.js

  1 /******/ (function(modules) { // webpackBootstrap  2 /******/     // install a JSONP callback for chunk loading  3 /******/     function webpackJsonpCallback(data) {  4 /******/         var chunkIds = data[0];  5 /******/         var moreModules = data[1];  6 /******/  7 /******/  8 /******/         // add "moreModules" to the modules object,  9 /******/         // then flag all "chunkIds" as loaded and fire callback 10 /******/         var moduleId, chunkId, i = 0, resolves = []; 11 /******/         for(;i < chunkIds.length; i++) { 12 /******/             chunkId = chunkIds[i]; 13 /******/             if(installedChunks[chunkId]) { 14 /******/                 resolves.push(installedChunks[chunkId][0]); 15 /******/             } 16 /******/             installedChunks[chunkId] = 0; 17 /******/         } 18 /******/         for(moduleId in moreModules) { 19 /******/             if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 20 /******/                 modules[moduleId] = moreModules[moduleId]; 21 /******/             } 22 /******/         } 23 /******/         if(parentJsonpFunction) parentJsonpFunction(data); 24 /******/ 25 /******/         while(resolves.length) { 26 /******/             resolves.shift()(); 27 /******/         } 28 /******/ 29 /******/     }; 30 /******/ 31 /******/ 32 /******/     // The module cache 33 /******/     var installedModules = {}; 34 /******/ 35 /******/     // object to store loaded and loading chunks 36 /******/     // undefined = chunk not loaded, null = chunk preloaded/prefetched 37 /******/     // Promise = chunk loading, 0 = chunk loaded 38 /******/     var installedChunks = { 39 /******/         0: 0 40 /******/     }; 41 /******/ 42 /******/ 43 /******/ 44 /******/     // script path function 45 /******/     function jsonpScriptSrc(chunkId) { 46 /******/         return __webpack_require__.p + "" + ({}[chunkId]||chunkId) + ".js" 47 /******/     } 48 /******/ 49 /******/     // The require function 50 /******/     function __webpack_require__(moduleId) { 51 /******/ 52 /******/         // Check if module is in cache 53 /******/         if(installedModules[moduleId]) { 54 /******/             return installedModules[moduleId].exports; 55 /******/         } 56 /******/         // Create a new module (and put it into the cache) 57 /******/         var module = installedModules[moduleId] = { 58 /******/             i: moduleId, 59 /******/             l: false, 60 /******/             exports: {} 61 /******/         }; 62 /******/ 63 /******/         // Execute the module function 64 /******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 65 /******/ 66 /******/         // Flag the module as loaded 67 /******/         module.l = true; 68 /******/ 69 /******/         // Return the exports of the module 70 /******/         return module.exports; 71 /******/     } 72 /******/ 73 /******/     // This file contains only the entry chunk. 74 /******/     // The chunk loading function for additional chunks 75 /******/     __webpack_require__.e = function requireEnsure(chunkId) { 76 /******/         var promises = []; 77 /******/ 78 /******/ 79 /******/         // JSONP chunk loading for javascript 80 /******/ 81 /******/         var installedChunkData = installedChunks[chunkId]; 82 /******/         if(installedChunkData !== 0) { // 0 means "already installed". 83 /******/ 84 /******/             // a Promise means "currently loading". 85 /******/             if(installedChunkData) { 86 /******/                 promises.push(installedChunkData[2]); 87 /******/             } else { 88 /******/                 // setup Promise in chunk cache 89 /******/                 var promise = new Promise(function(resolve, reject) { 90 /******/                     installedChunkData = installedChunks[chunkId] = [resolve, reject]; 91 /******/                 }); 92 /******/                 promises.push(installedChunkData[2] = promise); 93 /******/ 94 /******/                 // start chunk loading 95 /******/                 var head = document.getElementsByTagName('head')[0]; 96 /******/                 var script = document.createElement('script'); 97 /******/                 var onScriptComplete; 98 /******/ 99 /******/                 script.charset = 'utf-8';100 /******/                 script.timeout = 120;101 /******/                 if (__webpack_require__.nc) {102 /******/                     script.setAttribute("nonce", __webpack_require__.nc);103 /******/                 }104 /******/                 script.src = jsonpScriptSrc(chunkId);105 /******/106 /******/                 onScriptComplete = function (event) {107 /******/                     // avoid mem leaks in IE.108 /******/                     script.onerror = script.onload = null;109 /******/                     clearTimeout(timeout);110 /******/                     var chunk = installedChunks[chunkId];111 /******/                     if(chunk !== 0) {112 /******/                         if(chunk) {113 /******/                             var errorType = event && (event.type === 'load' ? 'missing' : event.type);114 /******/                             var realSrc = event && event.target && event.target.src;115 /******/                             var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')');116 /******/                             error.type = errorType;117 /******/                             error.request = realSrc;118 /******/                             chunk[1](error);119 /******/                         }120 /******/                         installedChunks[chunkId] = undefined;121 /******/                     }122 /******/                 };123 /******/                 var timeout = setTimeout(function(){124 /******/                     onScriptComplete({ type: 'timeout', target: script });125 /******/                 }, 120000);126 /******/                 script.onerror = script.onload = onScriptComplete;127 /******/                 head.appendChild(script);128 /******/             }129 /******/         }130 /******/         return Promise.all(promises);131 /******/     };132 /******/133 /******/     // expose the modules object (__webpack_modules__)134 /******/     __webpack_require__.m = modules;135 /******/136 /******/     // expose the module cache137 /******/     __webpack_require__.c = installedModules;138 /******/139 /******/     // define getter function for harmony exports140 /******/     __webpack_require__.d = function(exports, name, getter) {141 /******/         if(!__webpack_require__.o(exports, name)) {142 /******/             Object.defineProperty(exports, name, { enumerable: true, get: getter });143 /******/         }144 /******/     };145 /******/146 /******/     // define __esModule on exports147 /******/     __webpack_require__.r = function(exports) {148 /******/         if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {149 /******/             Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });150 /******/         }151 /******/         Object.defineProperty(exports, '__esModule', { value: true });152 /******/     };153 /******/154 /******/     // create a fake namespace object155 /******/     // mode & 1: value is a module id, require it156 /******/     // mode & 2: merge all properties of value into the ns157 /******/     // mode & 4: return value when already ns object158 /******/     // mode & 8|1: behave like require159 /******/     __webpack_require__.t = function(value, mode) {160 /******/         if(mode & 1) value = __webpack_require__(value);161 /******/         if(mode & 8) return value;162 /******/         if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;163 /******/         var ns = Object.create(null);164 /******/         __webpack_require__.r(ns);165 /******/         Object.defineProperty(ns, 'default', { enumerable: true, value: value });166 /******/         if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));167 /******/         return ns;168 /******/     };169 /******/170 /******/     // getDefaultExport function for compatibility with non-harmony modules171 /******/     __webpack_require__.n = function(module) {172 /******/         var getter = module && module.__esModule ?173 /******/             function getDefault() { return module['default']; } :174 /******/             function getModuleExports() { return module; };175 /******/         __webpack_require__.d(getter, 'a', getter);176 /******/         return getter;177 /******/     };178 /******/179 /******/     // Object.prototype.hasOwnProperty.call180 /******/     __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };181 /******/182 /******/     // __webpack_public_path__183 /******/     __webpack_require__.p = "./dist/";184 /******/185 /******/     // on error function for async loading186 /******/     __webpack_require__.oe = function(err) { console.error(err); throw err; };187 /******/188 /******/     var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];189 /******/     var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);190 /******/     jsonpArray.push = webpackJsonpCallback;191 /******/     jsonpArray = jsonpArray.slice();192 /******/     for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);193 /******/     var parentJsonpFunction = oldJsonpFunction;194 /******/195 /******/196 /******/     // Load entry module and return exports197 /******/     return __webpack_require__(__webpack_require__.s = 0);198 /******/ })199 /************************************************************************/200 /******/ ([201 /* 0 */202 /***/ (function(module, exports, __webpack_require__) {203204205206 console.log('main');207208 setTimeout(() => {209     __webpack_requi
10-11 01:05