webpack打包相互引用的模块
示例项目
( github )
遇到的问题
在有2个或2个以上的文件之间的相互依赖关系构成闭环的时候,有时会出现
Can't read Property 'xxx' of undefined
或者
(0,xxx) is not a function
这类的错误,比如:
示例项目中的src/index.js引用src/a.js,而src/a.js中也引用了src/index.js
为什么会出现这样的问题
这就跟webpack打包后的代码执行逻辑有关
webpack的头部启动代码中,通过闭包中的installedModules对象,将模块名或者id作为对象的key来缓存各个模块的export的值,通过判断installedModules上是否缓存了对应模块的key来判断是否已经加载了模块
// 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,
l: false,
exports: {}
};
// Execute the module function
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__)
但存在一个问题:当模块还处于第一次执行中的状态时,如果碰到相互引用的情况的话,webpack可能会认为一个没有完全加载完成的模块已经加载完了
就拿export function.js中的代码和export const _var.js中的代码为例:
export function.js
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports._console = _console;// <- 📢注意这里
var _a = __webpack_require__(2);
var _a2 = _interopRequireDefault(_a);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _console(