{"resource":{"author":{"id":"h2so9H8jPMmgUKGghoNl","name":"Yomesh Gupta","username":"yomeshgupta"},"content":{"link":"https://devtools.tech/understanding-webpack-require/","difficulty":2,"domain":1,"type":1,"isInternal":true,"body":"In this blog post, we are going to talk about webpack's require function, how it manages our modules and explore a use-case where such knowledge might help debug.\n\n### What is Webpack?\n\nJavaScript, in the current modern era, is a different beast altogether than in previous years. Way too many libraries, frameworks, tooling and information are available. There are dozens of scripts, each might be created by different persons/teams. There are third party libraries, which are known as `dependencies`. These dependencies need to be loaded and the order of loading also matters. On top of that, lack of language features support makes things worse.\n\nTo solve these problems, we need to keep track of each script, transpile code, add them to the webpage, maintain the loading order and take care of asynchronous behaviour.\n\nWebpack helps us to solve these problems in a much more hassle free-way. Sure, the learning curve can be daunting at times however latest release `Webpack 4` comes with zero configuration out of the box.\n\nWebpack is a `module bundler`. It runs at the time of development/deployment and the final output runs on your webpage. It takes a `configuration file` which provides instructions like what is the entry point of the codebase, where should it write the final bundle, how to handle different encountered resources and what all optimizations to perform. It starts traversing the codebase starting from the entry point and handles each imported resource as per the provided loader configuration. You need to describe to Webpack how to load and manipulate files such as `*.js`. After processing, it creates a final bundle and writes it to the output destination on the disk.\n\n### Webpack Runtime\n\nWebpack Runtime often called \"Webpack Bootstrap\", is the boilerplate code added to the final bundle which is responsible for functionalities like managing all the imported modules, cross-browser support, defining the public path and much more. Following is the `webpackBootstrap` code.\n\n```js\n/******/ (function(modules) { // webpackBootstrap\n/******/  // The module cache\n/******/  var installedModules = {};\n/******/\n/******/  // The require function\n/******/  function __webpack_require__(moduleId) {\n/******/\n/******/    // Check if module is in cache\n/******/    if(installedModules[moduleId]) {\n/******/      return installedModules[moduleId].exports;\n/******/    }\n/******/    // Create a new module (and put it into the cache)\n/******/    var module = installedModules[moduleId] = {\n/******/      i: moduleId,\n/******/      l: false,\n/******/      exports: {}\n/******/    };\n/******/\n/******/    // Execute the module function\n/******/    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/    // Flag the module as loaded\n/******/    module.l = true;\n/******/\n/******/    // Return the exports of the module\n/******/    return module.exports;\n/******/  }\n/******/\n/******/\n/******/  // expose the modules object (__webpack_modules__)\n/******/  __webpack_require__.m = modules;\n/******/\n/******/  // expose the module cache\n/******/  __webpack_require__.c = installedModules;\n/******/\n/******/  // define getter function for harmony exports\n/******/  __webpack_require__.d = function(exports, name, getter) {\n/******/    if(!__webpack_require__.o(exports, name)) {\n/******/      Object.defineProperty(exports, name, {\n/******/        configurable: false,\n/******/        enumerable: true,\n/******/        get: getter\n/******/      });\n/******/    }\n/******/  };\n/******/\n/******/  // define __esModule on exports\n/******/  __webpack_require__.r = function(exports) {\n/******/    Object.defineProperty(exports, '__esModule', { value: true });\n/******/  };\n/******/\n/******/  // getDefaultExport function for compatibility with non-harmony modules\n/******/  __webpack_require__.n = function(module) {\n/******/    var getter = module && module.__esModule ?\n/******/      function getDefault() { return module['default']; } :\n/******/      function getModuleExports() { return module; };\n/******/    __webpack_require__.d(getter, 'a', getter);\n/******/    return getter;\n/******/  };\n/******/\n/******/  // Object.prototype.hasOwnProperty.call\n/******/  __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/  // __webpack_public_path__\n/******/  __webpack_require__.p = \"\";\n/******/\n/******/\n/******/  // Load entry module and return exports\n/******/  return __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n....\n/***/ ])\n```\n\nYes, this seems like a lot of code and kind of overwhelming. Folks at Webpack are kind enough to leave comments for us, mere mortals, to understand this code.\n\n### Let's break it up\n\nIn this blog post, we are going to look at the `__webpack_require__` functionality. We are going to take this code apart into tiny snippets and then talk about it.\n\nRemember, first comes the code snippet than the explanation.\n\n```js\n/******/ (function(modules) { // webpackBootstrap\n/******/ ...\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n....\n/***/ ])\n```\n\nIf we take a look at the larger picture then the above code is an [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) which takes an array of IIFE(s) as the argument. Every array element represents a module in our code that is assigned a `moduleId` like first is\n`0` which is also the entry module.\n\n```js\n/******/ // The module cache\n/******/ var installedModules = {};\n```\n\nIt is a cache that would store all the modules as the code executes.\n\n```js\n/******/  // The require function\n/******/  function __webpack_require__(moduleId) {\n/******/\n/******/    // Check if module is in cache\n/******/    if(installedModules[moduleId]) {\n/******/      return installedModules[moduleId].exports;\n/******/    }\n/******/  ...\n```\n\nHere, starts the function declaration of `__webpack_require__`. It takes `moduleId` as a parameter and whenever this function is invoked when the cache is being checked if the module is already loaded or not. If yes then the module is returned from the cache else we load the module.\n\n`.exports` is not native `module export`. It is a custom property defined by `webpack runtime`.\n\n```js\n/******/    // Create a new module (and put it into the cache)\n/******/    var module = installedModules[moduleId] = {\n/******/      i: moduleId,\n/******/      l: false,\n/******/      exports: {}\n/******/    };\n/******/    ...\n```\n\nIf the module is not found in the cache then we load it. A variable called `module` is defined which is an `object` and has three properties on it.\n\n1. `i` refers to the `module`.\n2. `l` is a boolean flag that signifies if the module is already loaded or not.\n3. `exports` is an `object`.\n\nAt the same time, we put this `module` in the cache via `installedModules[moduleId]`.\n\n```js\n/******/    // Execute the module function\n/******/    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/    ...\n```\n\nNow, we call the module which we just placed in the cache.\n\n1. We look it up via `moduleId`.\n2. Every module is an IIFE. We invoke it using the `.call` method with the calling context `module.exports`.\n3. We provide it with the necessary arguments required by the module.\n4. We pass the existing `__webpack_require__` function so that the current module can require other modules if needed.\n\n```js\n/******/    // Flag the module as loaded\n/******/    module.l = true;\n/******/\n/******/    // Return the exports of the module\n/******/    return module.exports;\n/******/    ...\n```\n\nWe set the `l` flag to `true` which means the module is now loaded then return the `module.exports`.\n\nThis completes the `__webpack_require__` function. The rest of the code takes care of exposing certain properties, support for non-harmony modules and others.\n\n```js\n/******/ // Load entry module and return exports\n/******/ return __webpack_require__((__webpack_require__.s = 0));\n```\n\nWe end the IIFE by calling `__webpack_require__` with the first module a.k.a the entry module as the parameter. It initiates the above cycle we discussed of finding it in the cache or loading it in the cache and returning the `module.exports`.\n\n### Problem Usecase\n\nThis entire blog post is more good to know. You might not need it ever in your day job. However, at times it helps. I will tell you one small use case where knowing this code helped me track and solve a bug.\n\nRecently, I was assigned to optimize a JS bundle. Consider, a very large bundle that consists of many modules spanning different parts of a repo. Now, we realized that the bundle is being shipped with duplicate copies of `jQuery` which lead to an unnecessary increase in payload size.\n\nI am going to dumb down the complete problem case as the issue was much more complex and I cannot share all the details. I will focus on just how webpack require knowledge helped us.\n\nNow, this duplication shouldn't have happened because one module imported the `jQuery` and bound it to `window scoped variable`. All other modules used it from there rather than importing it. The task was to identify how the two copies are being imported and shipped.\n\nWhile going through the bundle, I came across the following code snippets.\n\n```js\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * jQuery JavaScript Library v1.11.2\n  ...\n```\n\n```js\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * jQuery JavaScript Library v1.11.2\n  ...\n```\n\n1. This meant the same library is being imported twice in different modules rather than using the window scoped jQuery.\n2. `moduleId(s)` for different copies of jQuery are `0` and `6`.\n3. Knowing that these `moduleIds` are assigned by webpack, what they mean and how they are used by `__webpack_require__` to load the modules helped in finding the part of the bundle where these modules are being required.\n\nInstance One\n\n```js{2}\nvar config = __webpack_require__(1),\n    jQuery = __webpack_require__(0),\n    consts = __webpack_require__(4),\n    yetAnotherModule = __webpack_require__(5),\n```\n\nInstance Two\n\n```js{1}\nvar jQuery = __webpack_require__(6),\n    renderModule = __webpack_require__(7),\n    logicModule = __webpack_require__(8),\n    someOtherModule = __webpack_require__(9),\n```\n\nThe above code snippet demonstrates that two modules required the `jQuery` whereas in the ideal case, the first module should require it and bind it. The second module should use the window scoped variable rather than importing it.\n\nWe were able to find the part of the codebase which provided us with context that second jQuery is being imported in the module which also requires `renderModule`, `logicModule`.\n\nSo now, the only thing left was to run a simple search in IDE and change the code accordingly in the second module to make it use the `window scoped jQuery` rather than importing it.\n\n**Boom, with that change 247 KB disappeared from the bundle! :P**\n\nI know, this might not seem like much or a magic wand but having such knowledge drastically reduced the debugging time and efforts.\n","languages":[],"editorConfig":{}},"stats":{"views":35033,"used":0,"likes":0},"description":"","published":true,"isActive":true,"tags":["node.js","javascript","frontend","frontend fundamentals","js fundamentals","interview questions","backend","backend fundamentals","webpack","inside webpack","advanced webpack"],"slug":"understanding-webpacks-require---rid---7VvMusDzMPVh17YyHdyL","isPremium":false,"categories":[],"requires":[],"_id":"5f1dd793cbec5f7ffc0c2fad","title":"Understanding Webpack's Require","resourceId":"7VvMusDzMPVh17YyHdyL","createdAt":1595791251201,"modifiedAt":1643098923812},"currentUser":null,"isOwner":false,"recommendations":{"questions":[{"_id":"60aa3947e541233080dcd5b1","content":{"difficulty":4,"languages":"javascript"},"tags":["javascript","frontend","promises","asynchronous programming","javascript fundamentals"],"slug":"what-would-the-output-of-the-following-code-snippet-promises-in-javascript---qid---bZEq6flSA5fB61P2ylHN","title":"What would the output of the following code snippet? [Promises in JavaScript]","questionId":"bZEq6flSA5fB61P2ylHN"},{"_id":"5eb7d8943f4a621665113a3d","content":{"difficulty":1,"languages":"javascript"},"tags":["node.js","javascript","delete operator","frontend fundamentals","javascript fundamentals","web development"],"title":"Output question based on the delete operator in JavaScript","questionId":"TO3XSXEbx9FW3cbnrfvK","slug":"output-question-based-on-the-delete-operator-in-javascript---qid---TO3XSXEbx9FW3cbnrfvK"},{"_id":"62fb6d1477f9961d5b7c7df6","content":{"languages":["html","react"],"difficulty":1},"tags":["","javascript","html calculator","html css","begineer","frontend begineer","frontend coding challenges","ui","ux","javascript interview questions","devtools tech","frontend masters","learn javascript","practice frontend"],"slug":"build-a-simple-html-calculator-or-frontend-coding-challenge-or-vanilla-javascript-or-machine-coding-round---qid---95l5mqyP6FmG3hVbnj9P","title":"Build a Simple HTML Calculator | Frontend Coding Challenge | Vanilla JavaScript | Machine Coding Round ","questionId":"95l5mqyP6FmG3hVbnj9P"},{"_id":"6259736b1195627fe9f0be26","content":{"languages":["javascript","typescript"],"difficulty":2},"tags":["javascript","frontend","node.js","event emitter","facebook","advanced frontend","interview question","devtools tech","frontend masters","egghead"],"slug":"how-to-implement-event-emitter-in-javascript-or-facebook-interview-question---qid---J4fNqXImp6QIdGMc7SPF","title":"How to implement Event Emitter in JavaScript? | Facebook Interview Question","questionId":"J4fNqXImp6QIdGMc7SPF"},{"_id":"67e5a04f347ebdb1a74bb40e","content":{"languages":["javascript","typescript"],"difficulty":2},"tags":["javascript","frontend","ui","ux","airbnb","store data","store claass","airbnb frontend interview question"],"slug":"implement-event-driven-key-value-store---qid---yySc0O8S4w3YIeA3pBFY","title":"Implement Event-Driven Key-Value Store","questionId":"yySc0O8S4w3YIeA3pBFY"}],"resources":[{"_id":"5fc7215a6d3cda64e470c415","content":{"difficulty":4,"domain":1,"type":5},"tags":["linkedin","jobs","skills","career","indemand","devtools"],"slug":"move-close-to-your-dream-job-find-out-top-skills-in-the-market---rid---layhD7GHUKsulhIM25yM","title":"Move close to your dream job. Find out top skills in the market.","resourceId":"layhD7GHUKsulhIM25yM"},{"_id":"62056636e12bce537863f36a","content":{"difficulty":1,"domain":1,"type":1,"isInternal":true},"tags":["javascript","remix run","social login","login with google","session","encryption","js fundamentals","remix server"],"slug":"add-social-authentication-to-remix-run-project-or-remix-server---rid---GEN4IbgWorJNeQL7Gkm8","title":"Add Social Authentication to Remix Run Project | Remix Server","resourceId":"GEN4IbgWorJNeQL7Gkm8"},{"_id":"69a7c7b992f33c7d8aa04c41","content":{"difficulty":1,"domain":1,"type":2,"isInternal":false,"languages":[]},"tags":["javascript","ui","ux","devtools tech","coding","frontend","polyfill"],"slug":"implementing-javascript-promise-polyfill---rid---9ExnAPiGr8eioZLa9IeV","title":"Implementing JavaScript Promise Polyfill","resourceId":"9ExnAPiGr8eioZLa9IeV"},{"_id":"61f505741238c849f9e159e5","content":{"difficulty":4,"domain":2,"type":1,"isInternal":true},"tags":["javascript","pagination","remix run","frontend","tutorial","query params","navigation","js framework"],"slug":"add-pagination-to-remix-run---rid---A9jJkhqXgojvhovKZACe","title":"Add Pagination to Remix Run","resourceId":"A9jJkhqXgojvhovKZACe"},{"_id":"639222ff937c6f54916670ee","content":{"difficulty":3,"domain":2,"type":2,"isInternal":false},"tags":["frontend","javascript","react","interview question","coding","programming","custom hooks","react hooks","ui","ux","blog","tech"],"slug":"how-to-create-useprevious-react-custom-hook-or-advanced-react-js-or-javascript-interview-question---rid---Dwblxb3EWYYxTG2vmwEp","title":"How to create usePrevious React Custom Hook? | Advanced React.js | JavaScript Interview Question","resourceId":"Dwblxb3EWYYxTG2vmwEp"}]}}