前端工程化之:webpack1-4(编译结果分析)

一、运行环境打包

 webpack 会假定项目的入口起点为 src/index.js ,然后会在 dist/main.js 输出结果,并且在生产环境开启压缩和优化。

我们要分析的就是 main.js 文件。

  1.  main.js 文件中的代码实际上就是一个自执行函数,将一个对象参数传入其中。
  2. 对象参数的 key 为所有模块的路径代码, value 为该路径下的代码统一放入一个函数中。
  3. 自执行函数中,需要引入项目的入口文件 src/index.js 
  4. 在自执行函数中定义一个 __webpack_require__ 函数,函数参数为自执行函数参数中的key 
  5. 根据参数中的路径,找到对应的函数代码,并执行,传入对应参数 module 、 module.exports 、 __webpack_require__
  6. 由于模块有缓存,所以需要定义一个变量 moduleExports ,将模块运行结果缓存起来。再次调用 __webpack_require__ 函数时判断是否存在缓存,如果已经加载过该模块,则直接返回缓存结果。

例: a.js 

console.log("module a");
module.exports = "a";

 index.js 

console.log("index module");
var a = require("./a");
console.log(a);

 my-main.js :手写一个 main.js 

(function (modules) {
  var moduleExports = {}; // 用于存放模块缓存
  // require函数相当于是运行一个模块,得到模块导出结果
  function __webpack_require__(moduleId) {
    // 如果已经加载过该模块,直接返回缓存结果
    if (moduleExports[moduleId]) {
      return moduleExports[moduleId];
    }
    // moduleId 表示模块的路径
    var func = modules[moduleId]; // 得到该模块路径对应的代码
    var module = {
      exports: {},
    };
    func(module, module.exports, __webpack_require__); // 执行该模块代码
    var result = module.exports; // 得到模块导出的结果
    moduleExports[moduleId] = result; // 将模块运行结果缓存起来
    return result;
  }

  // 执行入口模块
  __webpack_require__("./src/index.js"); // 执行入口模块,require函数相当于是运行一个模块,得到模块导出结果
})({
  // 该对象保存了所有的模块,以及模块对应的代码
  "./src/a.js": function (module, exports) {
    console.log("module a");
    module.exports = "a";
  },
  "./src/index.js": function (module, exports, __webpack_require__) {
    console.log("index module");
    var a = __webpack_require__("./src/a.js");
    console.log(a);
  },
});

需要注意的是: main.js 文件中,自执行函数的参数 value ,也就是路径所对应函数中的内容被 eval() 包裹起来,作用是为了在浏览器调试时更加方便,其中 "//# sourceURL=webpack://test/./src/index.js?" 代表了调试时候显示的路径。

二、生产环境打包

生产环境打包是将变量名简化减少打包体积,原理与运行环境打包一致!

生产环境中没有 eval() 函数。

你可能感兴趣的:(前端工程化,前端,javascript,webpack)