时间:2021-05-18
本文介绍了webpack编译vue项目生成的代码探索,分享给大家,具体如下:
前言
往 main.js 里写入最简单的 vue 项目结构如下
import Vue from 'vue'; import App from './App.vue';new Vue({ el: '#app', template: '<App/>', components: { App }})App.vue 如下
<template> <div id="app"> <h1>{{ msg }}</h1> <h2>Essential Links</h2> <ul> <li> <a href="https://vuejs.org" rel="external nofollow" target="_blank">Core Docs</a> </li> <li> <a href="https://forum.vuejs.org" rel="external nofollow" target="_blank">Forum</a> </li> <li> <a href="https://chat.vuejs.org" rel="external nofollow" target="_blank">Community Chat</a> </li> <li> <a href="https://twitter.com/vuejs" rel="external nofollow" target="_blank">Twitter</a> </li> </ul> <h2>Ecosystem</h2> <ul> <li> <a href="http://router.vuejs.org/" rel="external nofollow" target="_blank">vue-router</a> </li> <li> <a href="http://vuex.vuejs.org/" rel="external nofollow" target="_blank">vuex</a> </li> <li> <a href="http://vue-loader.vuejs.org/" rel="external nofollow" target="_blank">vue-loader</a> </li> <li> <a href="https://github.com/vuejs/awesome-vue" rel="external nofollow" target="_blank">awesome-vue</a> </li> </ul> </div></template><script> export default { name: 'app', data() { return { msg: 'Welcome to Your Vue.js App' } }}</script><style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px;}h1, h2 { font-weight: normal;}ul { list-style-type: none; padding: 0;}li { display: inline-block; margin: 0 10px;}a { color: #42b983;}</style>编译生成后得到一个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-modulesHash: 18d868a423b48dc263e9 Version: webpack 3.9.1 Time: 3693ms Asset Size Chunks Chunk Names build.js 316 kB 0 [emitted] [big] mainbuild.js.map 399 kB 0 [emitted] main代码分解
按顺序往下解读,本篇编译后的代码在这儿,如果只想看结论那么请拉到最后有一张结构梳理图。
webpack 模块机制
前面70行还是熟悉的 webpack 模块机制的基础代码,关于它的细致解读参见上一篇webpack模块机制,编译后的代码格式如下,并且我做了代码美化,并且插上了中文注释
/******/ (function(modules) { // webpackBootstrap/******/ // The module cache/******/ // 缓存模块,所有被加载过的模块都会成为installedModules对象的属性,靠函数__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)/******/ // 创造一个新模块并放入缓存中,i是模块标识,l意为是否加载此模块完毕,exports是此模块执行后的输出对象/******/ 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 标为true代表模块执行完成。/******/ module.l = true;/******//******/ // Return the exports of the module 返回此模块输出的对象/******/ return module.exports;/******/ }/******//******//******/ // expose the modules object (__webpack_modules__)/******/ // webpack 私有变量,保存传入的modules,即所有的模块组成的数组/******/ __webpack_require__.m = modules;/******//******/ // expose the module cache/******/ // 保存缓存中的模块数组/******/ __webpack_require__.c = installedModules;/******//******/ // define getter function for harmony exports/******/ // 为 es6 exports 定义 getter/******/ __webpack_require__.d = function(exports, name, getter) {/******/ // 如果 exports 输出的对象本身不包含 name 属性时,定义一个。/******/ 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 有关吧,webpack 的公共路径/******/ __webpack_require__.p = "/dist/";/******//******/ // Load entry module and return exports 执行第一个依赖模块并且返回它输出。/******/ return __webpack_require__(__webpack_require__.s = 0);/******/ })0号模块
导出一个全局变量,在web端就是指代window
1号模块
实际上做的事情很明显,就是导出了 main.js 的代码,一个vue实例对象
/***/ (function(module, __webpack_exports__, __webpack_require__) {"use strict";Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(2); var __WEBPACK_IMPORTED_MODULE_1__App_vue__ = __webpack_require__(6);// 从2号模块导出的一个叫a的变量,就是Vue对象本身new __WEBPACK_IMPORTED_MODULE_0_vue__["a" ]({ el: '#app', template: '<App/>', components: { App: __WEBPACK_IMPORTED_MODULE_1__App_vue__["a" ] }});/***/ })2号模块
即是 Vue 源码本身,从114行一直到了10818行,一共是10705行代码,啧啧啧
webpack 有所配置,所以导出的 Vue 实际上是 vue/dist/vue.esm.js 的完整编译版本。
/***/ (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,实际上就是window// __webpack_require__(3).setImmediate)作为setsetImmediate参数传入函数(function (global, setImmediate) { // 省略近1w行的代码,关于vue原本本身的解读以后再做...... // 最终 export 出来一个叫 Vue$3的对象 __webpack_exports__["a"] = (Vue$3); }.call(__webpack_exports__, __webpack_require__(0), __webpack_require__(3).setImmediate))}),3,4,5号模块
都和 node_modules/setimmediate 有关,由于 vue 的 DOM 异步更新机制使用到了它,所以被引入。
这里也不做详解,只给出结构。
/***/(function (module, exports, __webpack_require__) { // 省略代码... // setimmediate attaches itself to the global object __webpack_require__(4); exports.setImmediate = setImmediate; exports.clearImmediate = clearImmediate; /***/}),/***/(function (module, exports, __webpack_require__) { (function (global, process) { // 省略代码... }.call(exports, __webpack_require__(0), __webpack_require__(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号模块
和 App.vue 的解析有关,把 App.vue 中的 template 和 script 编译为一个 vue components,并把 style 标签内的样式插入到DOM中。
/***/(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 函数。 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函数 function injectStyle(ssrContext) { // 由此可知7号模块是编译并插入vue中的css到DOM上的 __webpack_require__(7) } // 12号模块用于输出components渲染函数 var normalizeComponent = __webpack_require__(12) var __vue_template_functional__ = false var __vue_styles__ = injectStyle var __vue_scopeId__ = null 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" ], __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" ], __vue_template_functional__, __vue_styles__, __vue_scopeId__, __vue_module_identifier__ ) __webpack_exports__["a"] = (Component.exports); /***/}),7、8、9、10、11
都和样式有关,简言之就是7号模块加载8号模块获取css代码作为参数,并作为参数传入10号模块进行插入
太长也只大意上列出结构
总结
结构梳理,一图胜千言
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
在使用vue-cli创建vue项目时,可以自动生成webpack文件。使用npmrunbuild即可打包发布生产文件,打包后的文件webpack配置可以看到使用
一款自动生成vue路由文件的webpack插件vue-route-webpack-plugin在项目中试点成功了,现在在项目中已经不需要再维护路由配置文件了,由
亲测,webpack打包vue项目之后生成的dist文件可以部署到express服务器上运行。我的vue项目结构如下:1.进入该vue项目目录,打开gitbas
以vue-cli生成的项目为例1.static文件夹下先放入ueditor文件2.index.html添加如下代码3.webpack.base.conf.js添
起源由Vue-Cli(2.X)生成的Vue项目中存在着首屏加载过慢,编译资源过大等问题,主要针对这些问题对项目进行相应的优化,提升项目响应速度,优化项目性能。操