真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

淺談webpack編譯vue項(xiàng)目生成的代碼探索

本文介紹了webpack編譯vue項(xiàng)目生成的代碼探索,分享給大家,具體如下:

憑祥網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)成立與2013年到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。

前言

往 main.js 里寫入最簡(jiǎn)單的 vue 項(xiàng)目結(jié)構(gòu)如下

import Vue from 'vue'; 
import App from './App.vue';

new Vue({ 
  el: '#app',
  template: '',
  components: {
    App
  }
})

App.vue 如下





 

編譯生成后得到一個(gè)316kb的文件,而在316Kb中包含著什么,我很好奇想探索一番。

npm run build

> learning-in-vue@1.0.0 build /Users/everlose/workspace/github/learningInVue
> cross-env NODE_ENV=production webpack --progress --hide-modules

Hash: 18d868a423b48dc263e9 
Version: webpack 3.9.1 
Time: 3693ms 
    Asset  Size Chunks          Chunk Names
  build.js 316 kB    0 [emitted] [big] main
build.js.map 399 kB    0 [emitted]     main 

代碼分解

按順序往下解讀,本篇編譯后的代碼在這兒,如果只想看結(jié)論那么請(qǐng)拉到最后有一張結(jié)構(gòu)梳理圖。

webpack 模塊機(jī)制

前面70行還是熟悉的 webpack 模塊機(jī)制的基礎(chǔ)代碼,關(guān)于它的細(xì)致解讀參見(jiàn)上一篇webpack模塊機(jī)制,編譯后的代碼格式如下,并且我做了代碼美化,并且插上了中文注釋

/******/ (function(modules) { // webpackBootstrap
/******/   // The module cache
/******/   // 緩存模塊,所有被加載過(guò)的模塊都會(huì)成為installedModules對(duì)象的屬性,靠函數(shù)__webpack_require__做到。
/******/   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)
/******/     // 創(chuàng)造一個(gè)新模塊并放入緩存中,i是模塊標(biāo)識(shí),l意為是否加載此模塊完畢,exports是此模塊執(zhí)行后的輸出對(duì)象
/******/     var module = installedModules[moduleId] = {
/******/       i: moduleId,
/******/       l: false,
/******/       exports: {}
/******/     };
/******/
/******/     // Execute the module function
/******/     // 傳入?yún)?shù)并執(zhí)行模塊函數(shù)
/******/     modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/     // Flag the module as loaded 標(biāo)為true代表模塊執(zhí)行完成。
/******/     module.l = true;
/******/
/******/     // Return the exports of the module 返回此模塊輸出的對(duì)象
/******/     return module.exports;
/******/   }
/******/
/******/
/******/   // expose the modules object (__webpack_modules__)
/******/   // webpack 私有變量,保存?zhèn)魅氲膍odules,即所有的模塊組成的數(shù)組
/******/   __webpack_require__.m = modules;
/******/
/******/   // expose the module cache
/******/   // 保存緩存中的模塊數(shù)組
/******/   __webpack_require__.c = installedModules;
/******/
/******/   // define getter function for harmony exports
/******/   // 為 es6 exports 定義 getter
/******/   __webpack_require__.d = function(exports, name, getter) {
/******/     // 如果 exports 輸出的對(duì)象本身不包含 name 屬性時(shí),定義一個(gè)。
/******/     if(!__webpack_require__.o(exports, name)) {
/******/       Object.defineProperty(exports, name, {
/******/         configurable: false,
/******/         enumerable: true,
/******/         get: getter
/******/       });
/******/     }
/******/   };
/******/
/******/   // getDefaultExport function for compatibility with non-harmony modules
/******/   // 解決 ES module 和 Common js module 的沖突,ES 則返回 module['default']
/******/   __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
/******/   // 工具方法,判斷是否object有property屬性。
/******/   __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/   // __webpack_public_path__
/******/   // 大概和 webpack.config.js 的 output 有關(guān)吧,webpack 的公共路徑
/******/   __webpack_require__.p = "/dist/";
/******/
/******/   // Load entry module and return exports 執(zhí)行第一個(gè)依賴模塊并且返回它輸出。
/******/   return __webpack_require__(__webpack_require__.s = 0);
/******/ })

0號(hào)模塊

導(dǎo)出一個(gè)全局變量,在web端就是指代window

/* 0 */
(function (module, exports) {

  var g;

  // This works in non-strict mode
  g = (function () {
    return this;
  })();

  try {
    // This works if eval is allowed (see CSP)
    g = g || Function("return this")() || (1, eval)("this");
  } catch (e) {
    // This works if the window reference is available
    if (typeof window === "object")
      g = window;
  }

  // g can still be undefined, but nothing to do about it...
  // We return undefined, instead of nothing here, so it's
  // easier to handle this case. if(!global) { ...}

  module.exports = g;


  /***/
}),

1號(hào)模塊

實(shí)際上做的事情很明顯,就是導(dǎo)出了 main.js 的代碼,一個(gè)vue實(shí)例對(duì)象

/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__App_vue__ = __webpack_require__(6);

// 從2號(hào)模塊導(dǎo)出的一個(gè)叫a的變量,就是Vue對(duì)象本身
new __WEBPACK_IMPORTED_MODULE_0_vue__["a" /* default */]({ 
  el: '#app',
  template: '',
  components: {
    App: __WEBPACK_IMPORTED_MODULE_1__App_vue__["a" /* default */]
  }
});

/***/ })

2號(hào)模塊

即是 Vue 源碼本身,從114行一直到了10818行,一共是10705行代碼,嘖嘖嘖

webpack 有所配置,所以導(dǎo)出的 Vue 實(shí)際上是 vue/dist/vue.esm.js 的完整編譯版本。

/* 2 */
/***/ (function (module, __webpack_exports__, __webpack_require__) {

"use strict";
/*!
 * Vue.js v2.5.9
 * (c) 2014-2017 Evan You
 * Released under the MIT License.
 */

// 作用域指向__webpack_exports__,并把__webpack_require__(0)作為global,實(shí)際上就是window
// __webpack_require__(3).setImmediate)作為setsetImmediate參數(shù)傳入函數(shù)
(function (global, setImmediate) {

  // 省略近1w行的代碼,關(guān)于vue原本本身的解讀以后再做......

  // 最終 export 出來(lái)一個(gè)叫 Vue$3的對(duì)象
  /* harmony default export */
  __webpack_exports__["a"] = (Vue$3);

  /* WEBPACK VAR INJECTION */
}.call(__webpack_exports__, __webpack_require__(0), __webpack_require__(3).setImmediate))

}),

3,4,5號(hào)模塊

都和 node_modules/setimmediate 有關(guān),由于 vue 的 DOM 異步更新機(jī)制使用到了它,所以被引入。

這里也不做詳解,只給出結(jié)構(gòu)。

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

  // 省略代碼...

  // setimmediate attaches itself to the global object
  __webpack_require__(4);
  exports.setImmediate = setImmediate;
  exports.clearImmediate = clearImmediate;

  /***/
}),

/* 4 */
/***/
(function (module, exports, __webpack_require__) {

  /* WEBPACK VAR INJECTION */
  (function (global, process) {
    // 省略代碼...
  }.call(exports, __webpack_require__(0), __webpack_require__(5)))

  /***/
}),

/* 5 */
/***/
(function (module, exports) {

  // shim for using process in browser
  var process = module.exports = {};

  // 省略代碼...

  process.cwd = function () {
    return '/'
  };
  process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
  };
  process.umask = function () {
    return 0;
  };
  /***/
}),

6號(hào)模塊

和 App.vue 的解析有關(guān),把 App.vue 中的 template 和 script 編譯為一個(gè) vue components,并把 style 標(biāo)簽內(nèi)的樣式插入到DOM中。

/* 6 */
/***/
(function (module, __webpack_exports__, __webpack_require__) {

  "use strict";

  // 返回具體 App.vue 中 的script 中的代碼
  var __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_App_vue__ = __webpack_require__(13);

  // 把App.vue 的 template 解析為一堆 vue render 函數(shù)。
  var __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_66ce2159_hasScoped_false_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_App_vue__ = __webpack_require__(14);

  // 注入vue文件里寫入的css函數(shù)
  function injectStyle(ssrContext) {
    // 由此可知7號(hào)模塊是編譯并插入vue中的css到DOM上的
    __webpack_require__(7)
  }
  // 12號(hào)模塊用于輸出components渲染函數(shù)
  var normalizeComponent = __webpack_require__(12)
  /* script */

  /* template */

  /* template functional */
  var __vue_template_functional__ = false
  /* styles */
  var __vue_styles__ = injectStyle
  /* scopeId */
  var __vue_scopeId__ = null
  /* moduleIdentifier (server only) */
  var __vue_module_identifier__ = null

  // 編譯模塊,混雜template和script。
  var Component = normalizeComponent(
    __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_App_vue__["a" /* default */ ],
    __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_66ce2159_hasScoped_false_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_App_vue__["a" /* default */ ],
    __vue_template_functional__,
    __vue_styles__,
    __vue_scopeId__,
    __vue_module_identifier__
  )

  /* harmony default export */
  __webpack_exports__["a"] = (Component.exports);


  /***/
}),

7、8、9、10、11

都和樣式有關(guān),簡(jiǎn)言之就是7號(hào)模塊加載8號(hào)模塊獲取css代碼作為參數(shù),并作為參數(shù)傳入10號(hào)模塊進(jìn)行插入

太長(zhǎng)也只大意上列出結(jié)構(gòu)

  1. 7號(hào)模塊由 style-loader 帶入,把所有的css插入到 style 標(biāo)簽里
  2. 8號(hào)模塊加載具體的css代碼,
  3. 9號(hào)模塊由css-loader代入,用于做css的sourceMap
  4. 10號(hào)模塊返回具體插入動(dòng)作函數(shù),供7號(hào)模塊調(diào)用
  5. 11號(hào)模塊把所有的樣式組成的數(shù)組轉(zhuǎn)為字符串,給10號(hào)模塊做插入。
/* 7 */

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

  // style-loader: Adds some css to the DOM by adding a