webpack 打包之後的代碼學習

心血來潮,看看打包之後的文件是怎麼樣的,如下所示,是簡單的不能再簡單的代碼了

1、只有 簡單 js 的打包

// number.js
export default function count (a, b) {
    return a + b
}
// largeNumber.js
import number from './number'
export default function add (a, b) {
    return number(a, b);
}

打包之後的代碼如下所示

// 如下所示,這裏是一個自執行的代碼
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
  else if(typeof exports === 'object')
    // 把 打包的 文件名稱 作爲 變量 放到 exports 上面
		exports["largeNumber"] = factory();
  else
    // 在全局 掛載 當前的 打包文件
    root["largeNumber"] = factory();
    // 在上面 的函數傳入的兩個參數
})(window, function() {
                // 這裏的 modules 就是 模塊化了的 代碼,也就是說,對應的 依賴 都被裝在了這裏
return  (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: {}
 		};

    // 這裏就是很簡單的 執行了 對應 id 的 代碼
 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

 		module.l = true;

    // 最後 導出的 還是 掛載到 exports 上的 所有數據,這裏就是 default
 		return module.exports;
 	}


 	__webpack_require__.m = modules;

 	__webpack_require__.c = installedModules;

  // 這個函數的 作用 就是 把 對應的 參數 使用 defineProperty 的方式 掛載到 exports 上面
 	__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__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };

 	__webpack_require__.p = "";


  // 這裏的 __webpack_require__ 就是 前面定義的 執行函數,這裏 id = 0 傳入,也就是先執行 第一個 代碼
 	return __webpack_require__(__webpack_require__.s = 0);
 })
/************************************************************************/
            //這裏 傳入的 就是 文件中的 代碼 和對應的 依賴,變成了一個數組
 ([
/* 0 */   // 可以看到,這裏標記的 / 0 / 就是主入口
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return add; });
                        // 獲得 這個函數的依賴,也就是 count 函數
/* harmony import */ var _number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);

function add (a, b) {
    // 執行 對應 代碼 中 導出的 default 函數,也就是 count 函數
    return Object(_number__WEBPACK_IMPORTED_MODULE_0__["default"])(a, b);
}


/***/ }),
/* 1 */  // 第二個依賴,這裏就是 傳入的 number 文件夾中的默認導出 函數 ,也就是 對應 id === 1 的代碼所在
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
                           // 使用了 d 函數,也就是說 把  count 函數 使用 default 參數 掛載到 __webpack_exports__ 上面去
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return count; });
function count (a, b) {
    return a + b
}

/***/ })
 ])["default"];
});
  1. 這裏的入口函數 是一個 自執行的代碼,參數 就是 主入口函數 和對應的依賴函數

  2. 依賴函數的參數 是一個數組,按照被加載的順序 放置

  3. 然後再 利用 函數作用域,將對應的 依賴函數 放進 對應模塊的 export 上,默認是 default 參數,通過 defineProperty 設置

  4. 然後在需要的時候,執行這個 default 裏的 內容

2、加上 css 和 css-loader

在以下的代碼裏,可以發現 其實 單純的加上css 只是作爲字符串被編譯到了 js 文件當中,這個 css 是不會被執行的,只會 被放到對應模塊的 exports 裏面

/** index.css */
.body {
    color: red;
    background-color: blue;
}

import number from './number'
import './index.css'
export default function add (a, b) {
    return number(a, b);
}
// 去除了 大量的 這裏沒有用到的代碼
...
([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return add; });
/* harmony import */ var _number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
                            // 導入第二個模塊,也就是 css 模塊
/* harmony import */ var _index_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);

function add (a, b) {
    
    return Object(_number__WEBPACK_IMPORTED_MODULE_0__["default"])(a, b);
}
 ...

// /***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {

// Imports
  // 導入 處理 css 的模塊 3,我們直接去看 第三個 模塊做了什麼
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(3);
// 直接在這裏傳入了 false,也就是說,沒有 對應的 sourceMap
// 然後這裏的返回值,就是 下文中的 list 數組
exports = ___CSS_LOADER_API_IMPORT___(false);
// Module  這裏的 css 都是 以字符串的 形式 出現在了 js 代碼之中
           // 這裏的 i 也就是 對應的 moduleId ,這裏就是 2  
exports.push([module.i, ".body {\n    color: red;\n    background-color: blue;\n}", ""]);
// Exports  把 list 數組導出
module.exports = exports;


/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// eslint-disable-next-line func-names
// 在執行 __webpack_require__ 的時候,其實導出的就是這個 exports ,所以 最後 執行的結果就是這個 function
// 再看上文中的 ___CSS_LOADER_API_IMPORT___ ,這裏的 useSourceMap 被傳入了 false
module.exports = function (useSourceMap) {
  var list = []; // return the list of modules as css string
  // 重新定義了 list 數組的 toString 方法
  list.toString = function toString() {
    return this.map(function (item) {
      // 這裏的 content 直接就是 上文中的 css 字符串
      var content = cssWithMappingToString(item, useSourceMap);
      // 當前的 item[2] 就是一個 ''
      if (item[2]) {
        return "@media ".concat(item[2], " {").concat(content, "}");
      }
      // 這裏返回的 依舊是 上文中的字符串
      return content;
    }).join('');
  }; // import a list of modules into the list
   ....

  return list;
};

function cssWithMappingToString(item, useSourceMap) {
  var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring

  var cssMapping = item[3];

  if (!cssMapping) {
    return content;
  }

  if (useSourceMap && typeof btoa === 'function') {
    var sourceMapping = toComment(cssMapping);
    var sourceURLs = cssMapping.sources.map(function (source) {
      return "/*# sourceURL=".concat(cssMapping.sourceRoot || '').concat(source, " */");
    });
    return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
  }

  return [content].join('\n');
} // Adapted from convert-source-map (MIT)


function toComment(sourceMap) {
  // eslint-disable-next-line no-undef
  var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
  var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
  return "/*# ".concat(data, " */");
}

/***/ })
/******/ ])["default"];
});

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章