webpack打包文件解析

214 阅读2分钟

1,新建项目文件夹,然后在文件夹下运行npm init -y初始化项目。

2,然后在项目目录下安装对应打包工具

npm i webpack webpack-cli -D

3,在项目目录下面新建一个webpack.config.js配置文件,文件内容如下:

{
  "name": "webpacktEST",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "webpack-cli": "^3.3.12",
    "webpack": "^4.43.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

4,项目下新建src目录,目录下新建两个js文件,a.js和index.js文件

index.js:

module.exports={
    mode:"development",
    entry:'./src/index.js',
    output: {
        filename: "bundle.js"
    }
}

a.js:

console.log("这是a.js输出的内容");
module.exports="这是a.js导出的内容";

5,运行npx webpack命令

可以在dist目录下找到一个打包好的budle.js文件

bundle.js:

(function (modules) { // webpackBootstrap
    var installedModules = {};

    function __webpack_require__(moduleId) {
        if (installedModules[moduleId]) {
            return installedModules[moduleId].exports;
        }
        var module = installedModules[moduleId] = {
            i: moduleId,
            l: false,
            exports: {}
        };
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
        module.l = true;
        return module.exports;
    }

    __webpack_require__.m = modules;
    __webpack_require__.c = installedModules;
    __webpack_require__.d = function (exports, name, getter) {
        if (!__webpack_require__.o(exports, name)) {
            Object.defineProperty(exports, name, {enumerable: true, get: getter});
        }
    };

    __webpack_require__.r = function (exports) {
        if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
            Object.defineProperty(exports, Symbol.toStringTag, {value: 'Module'});
        }
        Object.defineProperty(exports, '__esModule', {value: true});
    };

    __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;
    };

    __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__.o = function (object, property) {
        return Object.prototype.hasOwnProperty.call(object, property);
    };
    __webpack_require__.p = "";

    return __webpack_require__(__webpack_require__.s = "./src/index.js");
})
({
    "./src/a.js":
        (function (module, exports) {
            eval("console.log(\"这是a.js输出的内容\");\r\nmodule.exports=\"这是a.js导出的内容\";\n\n//# sourceURL=webpack:///./src/a.js?");
        }),
    "./src/index.js":
        (function (module, exports, __webpack_require__) {
            eval("let res=__webpack_require__(/*! ./a */ \"./src/a.js\");\r\nconsole.log(\"这是index输出的内容\");\r\nconsole.log(res);\r\nmodule.exports=\"这是index导出的文件\"\n\n//# sourceURL=webpack:///./src/index.js?");
        })

});

解析:

(1),这个解析文件整体是一个立即执行函数:

函数参数为一个对象:对象的key值即模块的路径,value为模块的执行内容。

{
    "./src/a.js":
        (function (module, exports) {
            eval("console.log(\"这是a.js输出的内容\");\r\nmodule.exports=\"这是a.js导出的内容\";\n\n//# sourceURL=webpack:///./src/a.js?");
        }),
    "./src/index.js":
        (function (module, exports, __webpack_require__) {
            eval("let res=__webpack_require__(/*! ./a */ \"./src/a.js\");\r\nconsole.log(\"这是index输出的内容\");\r\nconsole.log(res);\r\nmodule.exports=\"这是index导出的文件\"\n\n//# sourceURL=webpack:///./src/index.js?");
        })

}

(2),这个函数其实其实最重要的调用是__webpack_require__函数·的调用,这个函数根据一个模块的传入路径,然后会执行模块的内容,然后返回模块导出的内容,这个方法最开始传入index.js入口文件,

return __webpack_require__(__webpack_require__.s = "./src/index.js");

(3),想要拿到这个文件的exports内容,首先会查找缓存种是否已经存在,如果存在就从缓存中拿:

 if (installedModules[moduleId]) {
            return installedModules[moduleId].exports;
        }

如果缓存中不存在模块的信息,就重定义一个模块信息

var module = installedModules[moduleId] = {
            i: moduleId,
            l: false,
            exports: {}
      };

接着会调用模块对应的方法,也就是执行模块:

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

最后返回模块的导出:

 return module.exports;

6,把打包后的bundle.js放在html然后在浏览器运行,查看结果:

这是a.js输出的内容
index.js:2 这是index输出的内容
index.js:3 这是a.js导出的内容