About this repo

This repo: https://github.com/patricksevat/circ-deps showcases a couple different ways how circular dependencies are being handled by Webpack

Got to know before continuing!

The main thing you need to know about Webpack in the context of circular dependencies is how it resolves module dependencies.

Given these files (use tabs to switch files):

entry.js
moduleA.js
moduleC.js
moduleB.js

_10
import foo from './moduleA';
_10
_10
console.log(foo);

Webpack generates this dist/main.js, click on the tabs to go through it:

Full file

The __webpack_modules__ variable

This variable is an array or object which contains the source code for a particular file, but transpiled in a couple ways:

  1. It is transformed into a function
  2. Certain elements are transpiled, such as require(), import and export

moduleA.js before and after transpilation

The __webpack_require__ and __webpack_module_cache__ variables

As you can see in the example above,

import c from './moduleC''

is transformed to

__webpack_require__("./src/regular/c.js").

So what is __webpack_require__()?

Whenever __webpack_require__ is called:

  • it takes the moduleId ("./src/regular/c.js")
  • it checks if there is already an entry for this moduleId in __webpack_module_cache__ and return a cache hit or resolve the module, save it to cache and return the result

__webpack_module_cache__ cache hit

In case there is an entry in __webpack_module_cache__ for the requested moduleId Webpack will return the cached result:

__webpack_module_cache__ cache miss

In case there is no entry in __webpack_module_cache__ for the requested moduleId Webpack will:

  1. look up the module function in __webpack_modules__
  2. execute module function
  3. store the result in the cache
  4. return the result to the parent module which is importing the requested module
dist/main.js

_58
(function () {
_58
"use strict";
_58
var __webpack_modules__ = ({
_58
"./src/regular/moduleA.js":
_58
(function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
_58
__webpack_require__.r(__webpack_exports__);
_58
var _moduleC__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/regular/moduleC.js");
_58
const foo = _moduleC__WEBPACK_IMPORTED_MODULE_0__["default"] + 'bar';
_58
__webpack_exports__["default"] = (foo);
_58
}),
_58
"./src/regular/moduleB.js":
_58
(function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
_58
__webpack_require__.r(__webpack_exports__);
_58
var _moduleA__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/regular/moduleA.js");
_58
const bar = _moduleA__WEBPACK_IMPORTED_MODULE_0__["default"] + 'bar';
_58
__webpack_exports__["default"] = (bar);
_58
}),
_58
"./src/regular/moduleC.js":
_58
(function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
_58
__webpack_require__.r(__webpack_exports__);
_58
var _moduleB__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/regular/moduleB.js");
_58
const baz = _moduleB__WEBPACK_IMPORTED_MODULE_0__["default"] + 'baz';
_58
__webpack_exports__["default"] = (baz);
_58
})
_58
});
_58
_58
var __webpack_module_cache__ = {};
_58
_58
function __webpack_require__(moduleId) {
_58
var cachedModule = __webpack_module_cache__[moduleId];
_58
if (cachedModule !== undefined) {
_58
return cachedModule.exports;
_58
}
_58
var module = __webpack_module_cache__[moduleId] = {
_58
exports: {}
_58
};
_58
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
_58
return module.exports;
_58
}
_58
_58
!function () {
_58
__webpack_require__.r = function (exports) {
_58
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
_58
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
_58
}
_58
Object.defineProperty(exports, '__esModule', { value: true });
_58
};
_58
}();
_58
_58
var __webpack_exports__ = {};
_58
_58
!function () {
_58
__webpack_require__.r(__webpack_exports__);
_58
var _moduleA__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/regular/moduleA.js");
_58
console.log(_moduleA__WEBPACK_IMPORTED_MODULE_0__["default"]);
_58
}();
_58
})()
_58
;

Next: our first circular dependency

Now that you understand the basics of module resolution in Webpack, it's time to move to a circular dependency. click here