国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

webpack初探——js打包

dack / 573人閱讀

摘要:已經(jīng)成為編譯構(gòu)建前端項(xiàng)目的必備工具。今天就來(lái)了解一下的打包機(jī)制,先從最簡(jiǎn)單的編譯打包開(kāi)始。打包后的文件先來(lái)看下打包之后的文件是什么樣,然后再反推它的打包機(jī)制。補(bǔ)充說(shuō)明本文使用的是的版本。

webpack已經(jīng)成為編譯構(gòu)建前端項(xiàng)目的必備工具。今天就來(lái)了解一下webpack的打包機(jī)制,先從最簡(jiǎn)單的js編譯打包開(kāi)始。
webpack打包后的文件

先來(lái)看下webpack打包之后的文件是什么樣,然后再反推它的打包機(jī)制。補(bǔ)充說(shuō)明:本文使用的是webpack 4.x的版本。

代碼示例:

入口文件index.js,依賴(lài)a.js和b.js,而a.js和b.js都依賴(lài)c.js

代碼如下:

// index.js
import {getDate} from "./a";
import {getDay} from "./b";
console.log(getDate() + " " + getDay());


// a.js
import now from "./c";
export function getDate() {
  var date = now();
  var year = date.getFullYear();
  var month = date.getMonth() + 1;
  month = month > 9 ? month : `0${month}`;
  var day = date.getDate();
  day = day > 9 ? day : `0${day}`;
  return `${year}-${month}-${day}`;
}

// b.js
import now from "./c";
export function getDay() {
  var date = now();
  var arr = ["日", "一", "二", "三", "四", "五", "六"];
  return `周${arr[date.getDay()]}`;
}

// c.js
export default function now() {
  var date = new Date();
  return date;
}

webpack打包后的bundle.js如下:

/******/ (function(modules) { // webpackBootstrap
/******/     // The module cache
/******/     var installedModules = {};
/******/
/******/     // The require function
/******/     function __webpack_require__(moduleId) {
/******/
/******/         // Check if module is in cache
/******/         if(installedModules[moduleId]) {
/******/             return installedModules[moduleId].exports;
/******/         }
/******/         // Create a new module (and put it into the cache)
/******/         var module = installedModules[moduleId] = {
/******/             i: moduleId,
/******/             l: false,
/******/             exports: {}
/******/         };
/******/
/******/         // Execute the module function
/******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/         // Flag the module as loaded
/******/         module.l = true;
/******/
/******/         // Return the exports of the module
/******/         return module.exports;
/******/     }
/******/
/******/
/******/     // expose the modules object (__webpack_modules__)
/******/     __webpack_require__.m = modules;
/******/
/******/     // expose the module cache
/******/     __webpack_require__.c = installedModules;
/******/
/******/     // define getter function for harmony exports
/******/     __webpack_require__.d = function(exports, name, getter) {
/******/         if(!__webpack_require__.o(exports, name)) {
/******/             Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/         }
/******/     };
/******/
/******/     // define __esModule on exports
/******/     __webpack_require__.r = function(exports) {
/******/         if(typeof Symbol !== "undefined" && Symbol.toStringTag) {
/******/             Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
/******/         }
/******/         Object.defineProperty(exports, "__esModule", { value: true });
/******/     };
/******/
/******/     // create a fake namespace object
/******/     // mode & 1: value is a module id, require it
/******/     // mode & 2: merge all properties of value into the ns
/******/     // mode & 4: return value when already ns object
/******/     // mode & 8|1: behave like require
/******/     __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;
/******/     };
/******/
/******/     // getDefaultExport function for compatibility with non-harmony modules
/******/     __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;
/******/     };
/******/
/******/     // Object.prototype.hasOwnProperty.call
/******/     __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/     // __webpack_public_path__
/******/     __webpack_require__.p = "";
/******/
/******/
/******/     // Load entry module and return exports
/******/     return __webpack_require__(__webpack_require__.s = "./example/src/index.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./example/src/a.js":
/*!**************************!*
  !*** ./example/src/a.js ***!
  **************************/
/*! exports provided: getDate */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDate", function() { return getDate; });
/* harmony import */ var _c__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./c */ "./example/src/c.js");

function getDate() {
  var date = Object(_c__WEBPACK_IMPORTED_MODULE_0__["default"])();
  var year = date.getFullYear();
  var month = date.getMonth() + 1;
  month = month > 9 ? month : `0${month}`;
  var day = date.getDate();
  day = day > 9 ? day : `0${day}`;
  return `${year}-${month}-${day}`;
}


//# sourceURL=webpack:///./example/src/a.js?");

/***/ }),

/***/ "./example/src/b.js":
/*!**************************!*
  !*** ./example/src/b.js ***!
  **************************/
/*! exports provided: getDay */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDay", function() { return getDay; });
/* harmony import */ var _c__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./c */ "./example/src/c.js");

function getDay() {
  var date = Object(_c__WEBPACK_IMPORTED_MODULE_0__["default"])();
  var arr = ["日", "一", "二", "三", "四", "五", "六"];
  return `周${arr[date.getDay()]}`;
}


//# sourceURL=webpack:///./example/src/b.js?");

/***/ }),

/***/ "./example/src/c.js":
/*!**************************!*
  !*** ./example/src/c.js ***!
  **************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return now; });
function now() {
  var date = new Date();
  return date;
}


//# sourceURL=webpack:///./example/src/c.js?");

/***/ }),

/***/ "./example/src/index.js":
/*!******************************!*
  !*** ./example/src/index.js ***!
  ******************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a */ "./example/src/a.js");
/* harmony import */ var _b__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./b */ "./example/src/b.js");


console.log(Object(_a__WEBPACK_IMPORTED_MODULE_0__["getDate"])() + " " + Object(_b__WEBPACK_IMPORTED_MODULE_1__["getDay"])());


//# sourceURL=webpack:///./example/src/index.js?");

/***/ })

/******/ });

簡(jiǎn)單點(diǎn),打包后的形式是這樣的:

(function(modules) {
  // ...
})({
  // ...
})

其實(shí)就是自執(zhí)行函數(shù),傳入的moduels對(duì)象是下面的形式:

{
  "./example/src/a.js": (function(module, __webpack_exports__, __webpack_require__) {
    // 模塊代碼
  }),
  "./example/src/b.js": (function(module, __webpack_exports__, __webpack_require__) {
    // 模塊代碼
  }),
  "./example/src/c.js": (function(module, __webpack_exports__, __webpack_require__) {
    // 模塊代碼
  }),
  "./example/src/index.js": (function(module, __webpack_exports__, __webpack_require__) {
    // 模塊代碼
  })
}

模塊代碼被編譯成es5格式的代碼,在執(zhí)行時(shí),自執(zhí)行函數(shù)從入口文件開(kāi)始執(zhí)行

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

再來(lái)看看__webpack_require__函數(shù)的定義:

function __webpack_require__(moduleId) {
/******/
/******/         // Check if module is in cache
/******/         if(installedModules[moduleId]) {
/******/             return installedModules[moduleId].exports;
/******/         }
/******/         // Create a new module (and put it into the cache)
/******/         var module = installedModules[moduleId] = {
/******/             i: moduleId,
/******/             l: false,
/******/             exports: {}
/******/         };
/******/
/******/         // Execute the module function
/******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/         // Flag the module as loaded
/******/         module.l = true;
/******/
/******/         // Return the exports of the module
/******/         return module.exports;
/******/     }

函數(shù)返回的是module.exports,對(duì)于已經(jīng)存在于installedModules中的模塊,再次require時(shí),直接返回module.exports,而不會(huì)執(zhí)行。

根據(jù)webpack打包后的文件,可以得出打包的思路:

定義require函數(shù)

分析入口文件的依賴(lài),打包成moduels形式的代碼

生成自執(zhí)行的bundle.js,從入口文件開(kāi)始執(zhí)行

開(kāi)發(fā)簡(jiǎn)單的打包程序 將es6語(yǔ)法轉(zhuǎn)換成es5

這一步通過(guò)babel來(lái)轉(zhuǎn)換

通過(guò)babylon生成AST

通過(guò)babel-core將AST重新生成源碼

/**
 * 獲取文件,生成AST
 * @param filename
 */
function getAst(filename) {
  const content = fs.readFileSync(filename, "utf-8");
  return babylon.parse(content, {
    sourceType: "module"
  });
}

/**
 * 編譯
 * @param ast
 */
function getTranslateCode(ast) {
  const { code } = babel.transformFromAst(ast, null, {
    presets: ["env"]
  });
  return code;
}
處理模塊的依賴(lài)關(guān)系

通過(guò)babel-traverse遍歷AST,找到模塊的依賴(lài)

function getDependencies(ast) {
  let dependencies = [];
  traverse(ast, {
    ImportDeclaration: ({node}) => {
      dependencies.push(node.source.value);
    }
  });
  return dependencies;
}
解析模塊
function parse(filename, entry) {
  let absolutePath = path.join(entry, filename + ".js");
  const ast = getAst(absolutePath);
  return {
    filename,
    dependence: getDependencies(ast), // 解析依賴(lài)
    code: getTranslateCode(ast) // 編譯成es5
  };
}
解析深度依賴(lài)

此時(shí)的getDependencies還只是解析一個(gè)模塊的依賴(lài),但依賴(lài)的依賴(lài)沒(méi)有解析,所以需要深度遍歷

const modules = {};
/**
 * 深度隊(duì)列依賴(lài)
 * @param main
 */
function getQueue(main) {
  if (modules[main.filename]) {
    return;
  }
  modules[main.filename] = main;
  main.dependence.forEach(dep => {
    let child = parse(dep, "example/src");
    getQueue(child);
  });
}
bundle函數(shù)
function bundle(queue) {
  let modules = "";
  queue.forEach(mod => {

    modules += `"${mod.filename}": function(require, module, exports) {${mod.code}},`
  });
  const result = `
  (function(modules){
    var installedModules = {};
    function require(moduleId){
      if (installedModules[moduleId]) {
        return installedModules[moduleId].exports;
      }
      var fn = modules[moduleId];
      var module = installedModules[moduleId] = {exports: {}};
      fn(require, module, module.exports);
      return module.exports;
    }
    require("index");
  })({${modules}})
  `;
  return result;
}
執(zhí)行bundle后的輸出
(function (modules) {
  var installedModules = {};

  function require(moduleId) {
    if (installedModules[moduleId]) {
      return installedModules[moduleId].exports;
    }
    var fn = modules[moduleId];
    var module = installedModules[moduleId] = {exports: {}};
    fn(require, module, module.exports);
    return module.exports;
  }

  require("index");
})({
  "index": function (require, module, exports) {
    "use strict";

    var _a = require("./a");

    var _b = require("./b");

    console.log((0, _a.getDate)() + " " + (0, _b.getDay)());
  }, "./a": function (require, module, exports) {
    "use strict";

    Object.defineProperty(exports, "__esModule", {
      value: true
    });
    exports.getDate = getDate;

    var _c = require("./c");

    var _c2 = _interopRequireDefault(_c);

    function _interopRequireDefault(obj) {
      return obj && obj.__esModule ? obj : {default: obj};
    }

    function getDate() {
      var date = (0, _c2.default)();
      var year = date.getFullYear();
      var month = date.getMonth() + 1;
      month = month > 9 ? month : "0" + month;
      var day = date.getDate();
      day = day > 9 ? day : "0" + day;
      return year + "-" + month + "-" + day;
    }
  }, "./c": function (require, module, exports) {
    "use strict";

    Object.defineProperty(exports, "__esModule", {
      value: true
    });
    exports.default = now;

    function now() {
      var date = new Date();
      return date;
    }
  }, "./b": function (require, module, exports) {
    "use strict";

    Object.defineProperty(exports, "__esModule", {
      value: true
    });
    exports.getDay = getDay;

    var _c = require("./c");

    var _c2 = _interopRequireDefault(_c);

    function _interopRequireDefault(obj) {
      return obj && obj.__esModule ? obj : {default: obj};
    }

    function getDay() {
      var date = (0, _c2.default)();
      var arr = ["日", "一", "二", "三", "四", "五", "六"];
      return "u5468" + arr[date.getDay()];
    }
  }
})
  
總結(jié)

這樣,基本上處理js依賴(lài)和編譯的工作算是完成了

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/95469.html

相關(guān)文章

  • gulp和webpack初探

    摘要:首先聲明一下,和兩者關(guān)系不大,主要是團(tuán)隊(duì)之前一直用構(gòu)建工具,這幾天業(yè)務(wù)上比較清閑,老大讓我學(xué)學(xué)新的和這些潮流工具,于是草草研究了一天,記一些筆記。最后使用將各個(gè)組件打包在一起。 首先聲明一下,gulp和webpack兩者關(guān)系不大,主要是團(tuán)隊(duì)之前一直用grunt構(gòu)建工具,這幾天業(yè)務(wù)上比較清閑,老大讓我學(xué)學(xué)新的gulp和webpack這些潮流工具,于是草草研究了一天,記一些筆記。 gulp...

    jhhfft 評(píng)論0 收藏0
  • webpack初探

    摘要:我們還想要的顏色我們通過(guò)下面命令行可以做到觀(guān)察模式我們不想每一次項(xiàng)目變化都要手動(dòng)編譯可以緩存兩次編譯之間沒(méi)有變化的模塊和輸出文件。開(kāi)發(fā)服務(wù)器使用開(kāi)發(fā)服務(wù)器開(kāi)發(fā)體驗(yàn)會(huì)更好這將在本地啟動(dòng)一個(gè)端口的服務(wù),指向靜態(tài)文件以及自動(dòng)編譯。 原文英文版來(lái)自webpack官網(wǎng) demo代碼 本文地址 歡迎瀏覽 這是一篇通過(guò)一個(gè)小例子給你介紹webpack的文章 你可以通過(guò)這篇文章了解到: 如...

    soasme 評(píng)論0 收藏0
  • webpack初探

    摘要:我們還想要的顏色我們通過(guò)下面命令行可以做到觀(guān)察模式我們不想每一次項(xiàng)目變化都要手動(dòng)編譯可以緩存兩次編譯之間沒(méi)有變化的模塊和輸出文件。開(kāi)發(fā)服務(wù)器使用開(kāi)發(fā)服務(wù)器開(kāi)發(fā)體驗(yàn)會(huì)更好這將在本地啟動(dòng)一個(gè)端口的服務(wù),指向靜態(tài)文件以及自動(dòng)編譯。 原文英文版來(lái)自webpack官網(wǎng) demo代碼 本文地址 歡迎瀏覽 這是一篇通過(guò)一個(gè)小例子給你介紹webpack的文章 你可以通過(guò)這篇文章了解到: 如...

    Lavender 評(píng)論0 收藏0
  • webpack初探

    摘要:我們還想要的顏色我們通過(guò)下面命令行可以做到觀(guān)察模式我們不想每一次項(xiàng)目變化都要手動(dòng)編譯可以緩存兩次編譯之間沒(méi)有變化的模塊和輸出文件。開(kāi)發(fā)服務(wù)器使用開(kāi)發(fā)服務(wù)器開(kāi)發(fā)體驗(yàn)會(huì)更好這將在本地啟動(dòng)一個(gè)端口的服務(wù),指向靜態(tài)文件以及自動(dòng)編譯。 原文英文版來(lái)自webpack官網(wǎng) demo代碼 本文地址 歡迎瀏覽 這是一篇通過(guò)一個(gè)小例子給你介紹webpack的文章 你可以通過(guò)這篇文章了解到: 如...

    geekzhou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<