加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

浅谈webpack编译vue项目生成的代码探索

发布时间:2020-12-17 02:41:08 所属栏目:百科 来源:网络整理
导读:本文介绍了webpack编译vue项目生成的代码探索,分享给大家,具体如下: 前言 往 main.js 里写入最简单的 vue 项目结构如下 new Vue({ el: '#app',template: '',components: { App } }) App.vue 如下 {{ msg }} Essential Links Ecosystem 编译生成后得到一个

本文介绍了webpack编译vue项目生成的代码探索,分享给大家,具体如下:

前言

往 main.js 里写入最简单的 vue 项目结构如下

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

App.vue 如下

{{ msg }}

Essential Links

Ecosystem

编译生成后得到一个316kb的文件,而在316Kb中包含着什么,我很好奇想探索一番。

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

代码分解

按顺序往下解读,本篇编译后的代码在这儿,如果只想看结论那么请拉到最后有一张结构梳理图。

webpack 模块机制

前面70行还是熟悉的 webpack 模块机制的基础代码,关于它的细致解读参见上一篇webpack模块机制,编译后的代码格式如下,并且我做了代码美化,并且插上了中文注释

0号模块

导出一个全局变量,在web端就是指代window

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号模块

实际上做的事情很明显,就是导出了 main.js 的代码,一个vue实例对象

"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号模块导出的一个叫a的变量,就是Vue对象本身
new WEBPACK_IMPORTED_MODULE_0_vue["a" / default /]({
el: '#app',components: {
App: WEBPACK_IMPORTED_MODULE_1__App_vue["a" / default /]
}
});

/***/ })

2号模块

即是 Vue 源码本身,从114行一直到了10818行,一共是10705行代码,啧啧啧

webpack 有所配置,所以导出的 Vue 实际上是 vue/dist/vue.esm.js 的完整编译版本。

"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的对象
/ harmony default export /
__webpack_exports__["a"] = (Vue$3);

/ WEBPACK VAR INJECTION /
}.call(webpack_exports,webpack_require(0),__webpack_require__(3).setImmediate))

}),

3,4,5号模块

都和 node_modules/setimmediate 有关,由于 vue 的 DOM 异步更新机制使用到了它,所以被引入。

这里也不做详解,只给出结构。

// 省略代码...

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

//
}),/
4 /
/
/
(function (module,__webpack_require__) {

/ WEBPACK VAR INJECTION /
(function (global,process) {
// 省略代码...
}.call(exports,__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号模块

和 App.vue 的解析有关,把 App.vue 中的 template 和 script 编译为一个 vue components,并把 style 标签内的样式插入到DOM中。

"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)
/ 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

都和样式有关,简言之就是7号模块加载8号模块获取css代码作为参数,并作为参数传入10号模块进行插入

太长也只大意上列出结构

  1. 7号模块由 style-loader 带入,把所有的css插入到 style 标签里
  2. 8号模块加载具体的css代码,
  3. 9号模块由css-loader代入,用于做css的sourceMap
  4. 10号模块返回具体插入动作函数,供7号模块调用
  5. 11号模块把所有的样式组成的数组转为字符串,给10号模块做插入。
/***/
(function (module,__webpack_require__) {

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