本文介紹了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 如下
{{ msg }}
Essential Links
Ecosystem
編譯生成后得到一個(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)
/* 7 */ /***/ (function (module, exports, __webpack_require__) { // style-loader: Adds some css to the DOM by adding a