webpack打包结果的分析

本文详细解释了Webpack如何实现模块化管理,包括模块的导入导出转换、IIFE、模块缓存、__webpack_require__函数的作用以及操作案例。通过创建简单的项目结构展示Webpack如何处理依赖和导出,最终生成可执行的main.js文件。

webpack支持多种模块化

webpack实际上是实现了一套属于自己的模块化。无论你是用CommonJS规范还是ES6模块化规范,他都将你的模块导入导出方式转换为自己的一套模块化。

打包结果总结

Webpack在打包过程中首先定义了一个立即执行函数(iife),在这个函数中创建了一个名为__webpack_modules__的对象,用于存储所有模块的定义。每个模块的代码都被整合在一起,并以模块路径作为key,对应的模块函数作为value。

随后,Webpack定义了模块缓存对象__webpack_module_cache__和模块加载函数__webpack_require__。模块加载函数的作用是加载模块,首先会检查缓存中是否已经存在该模块,如果存在则直接返回该模块的exports对象。如果缓存中没有该模块,则根据传入的模块路径从__webpack_modules__中获取模块定义,并执行该模块的代码。在执行模块函数时,会将__webpack_module_cache__、空的exports对象以及模块函数本身作为参数传入,执行该模块代码时会先调用__webpack_require__.d和__webpack_require.r这两个函数,将exports对象写入缓存内容。最终,模块加载函数会返回执行后的exports对象。

此外,Webpack还定义了一些运行时函数,如__webpack_require__.d用于定义模块的导出,__webpack_require.o用于判断对象是否具有某个属性,__webpack_require.r用于将模块标记为ES模块。这些运行时函数在整个应用程序的执行过程中发挥重要作用,帮助实现模块之间的依赖管理和导出导入功能。

最后,在入口文件中引入其他模块时,利用模块加载和缓存机制,调用__webpack_require__函数加载模块。如果模块尚未缓存,则会设置一个新的空的exports对象,并执行对应模块的函数。同时,会调用.d和.r函数来处理模块的导出和标记,最终返回包含模块导出内容的exports对象。整个过程有效地管理了模块间的依赖关系,实现了模块化管理的功能和可靠性。

以上是我简单的一个总结。

操作案例

1、首先创建进入一个目录并初始化 npm并安装webpack

mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev

     这时我们的目录里生成了 package.json文件和用于存放依赖。

2、现在创建以下目录结构、文件和内容:

       src/main.js

        

import num from './js'
console.log(num);

       src/js/index.js

import count from "./count";
import sum from "./sum";
console.log(count(2, 1));
console.log(sum(1, 2, 3, 4));
const num = count(2, 1) + sum(1, 2, 3, 4)
export default num

       src/js/count.js

export default function count(x, y) {
    return x - y;
  }

        src/js/sum.js

export default function sum(...args) {
    return args.reduce((p, c) => p + c, 0);
  }

        public/index.html

        需要引入打包后的js文件

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>起步</title>
  </head>
  <body>
   <script src="../dist/main.js"></script>
  </body>
</html>

3、接下来我们开始打包,在终端运行:

      

npx webpack ./src/main.js --mode=development --devtool=false

        npx是运行可执行文件的,./src/main.js是入口文件,--mode=development是打包方式为开发环境,--devtool=false是为了去除Source Map。

也可以将这行命令配置到package.json文件中,就可以直接运行npm run build

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "clean":"powershell -Command \"Remove-Item -Recurse -Force dist\"",
    "build":"npm run clean && webpack ./src/main.js --mode=development --devtool=false"
  },

npm run clean是为了每次打包时删除上次的dist文件

4、会生成dist文件,文件中的main.js就是打包后的代码

你可以根据你自己代码打包结果进行总结分析

打包后main.js文件里的代码

dist/main.js

(() => { // webpackBootstrap
  "use strict";
  var __webpack_modules__ = ({
    /*!*************************!*\
          !*** ./src/js/count.js ***!
          \*************************/
    "./src/js/count.js": ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
      __webpack_require__.r(__webpack_exports__);
      __webpack_require__.d(__webpack_exports__, {
        "default": () => (/* binding */ count)
      });
      function count(x, y) {
        return x - y;
      }
    }),
    /*!*************************!*\
      !*** ./src/js/index.js ***!
      \*************************/
    "./src/js/index.js": ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
      __webpack_require__.r(__webpack_exports__);
      __webpack_require__.d(__webpack_exports__, {
        "default": () => (__WEBPACK_DEFAULT_EXPORT__)
      });
      var _count__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./count */ "./src/js/count.js");
      var _sum__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./sum */ "./src/js/sum.js");
      console.log((0, _count__WEBPACK_IMPORTED_MODULE_0__["default"])(2, 1));
      console.log((0, _sum__WEBPACK_IMPORTED_MODULE_1__["default"])(1, 2, 3, 4));
      const num = (0, _count__WEBPACK_IMPORTED_MODULE_0__["default"])(2, 1) + (0, _sum__WEBPACK_IMPORTED_MODULE_1__["default"])(1, 2, 3, 4)
      const __WEBPACK_DEFAULT_EXPORT__ = (num);


    }),
    /*!***********************!*\
      !*** ./src/js/sum.js ***!
      \***********************/
    "./src/js/sum.js": ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

      __webpack_require__.r(__webpack_exports__);
      __webpack_require__.d(__webpack_exports__, {
        "default": () => (/* binding */ sum)
      });
      function sum(...args) {
        return args.reduce((p, c) => p + c, 0);
      }
    })

  });
  /************************************************************************/
  // The module cache
  var __webpack_module_cache__ = {};

  // The require function
  function __webpack_require__(moduleId) {
    // Check if module is in cache
    var cachedModule = __webpack_module_cache__[moduleId];
    if (cachedModule !== undefined) {
      return cachedModule.exports;
    }
    // Create a new module (and put it into the cache)
    var module = __webpack_module_cache__[moduleId] = {
      // no module.id needed
      // no module.loaded needed
      exports: {}
    };

    // Execute the module function
    __webpack_modules__[moduleId](module, module.exports, __webpack_require__);

    // Return the exports of the module
    return module.exports;
  }

  /************************************************************************/
  /* webpack/runtime/define property getters */
  (() => {
    // define getter functions for harmony exports
    __webpack_require__.d = (exports, definition) => {
      for (var key in definition) {
        if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
          Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
        }
      }
      console.log(exports);
    };

  })();

  /* webpack/runtime/hasOwnProperty shorthand */
  (() => {
    __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
  })();

  /* webpack/runtime/make namespace object */
  (() => {
    // define __esModule on exports
    __webpack_require__.r = (exports) => {
      if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
        Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
      }
      Object.defineProperty(exports, '__esModule', { value: true });
    };
  })();

  /************************************************************************/
  var __webpack_exports__ = {};
  // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
  (() => {
    /*!*********************!*\
      !*** ./src/main.js ***!
      \*********************/
    __webpack_require__.r(__webpack_exports__);
    var _js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./js */ "./src/js/index.js");

    console.log(_js__WEBPACK_IMPORTED_MODULE_0__["default"]);
  })();

})()
  ;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值