Skip to content

Commit

Permalink
Vue-loader输出分析
Browse files Browse the repository at this point in the history
  • Loading branch information
yzsunlei committed Oct 7, 2019
1 parent 677a801 commit 4bda6be
Showing 1 changed file with 97 additions and 0 deletions.
97 changes: 97 additions & 0 deletions 5.3.Vue-loader输出分析.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
layout: post
title: 4.3.Vue-loader输出分析
category: 写教程
tag: vue-loader
exception:
readtime: 12
---

## 如何获取输出文件
* 我们在 `vue-loader` 源码根目录先 `npm install` 安装项目依赖包, 然后 `npm run build` 就可以看到输出文件 `./example/dist/bundle.js`

## 输出文件示例
* 因为打包后的文件巨大,这里只抽出部分代码进行分析,如下:
```javascript
/***/ "./example/source.vue":
/*!****************************!*\
!*** ./example/source.vue ***!
\****************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./source.vue?vue&type=template&id=27e4e96e&lang=pug& */ \"./example/source.vue?vue&type=template&id=27e4e96e&lang=pug&\");\n/* harmony import */ var _source_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./source.vue?vue&type=script&lang=js& */ \"./example/source.vue?vue&type=script&lang=js&\");\n/* empty/unused harmony star reexport *//* harmony import */ var _source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./source.vue?vue&type=style&index=0&module=true&lang=css& */ \"./example/source.vue?vue&type=style&index=0&module=true&lang=css&\");\n/* harmony import */ var _lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../lib/runtime/componentNormalizer.js */ \"./lib/runtime/componentNormalizer.js\");\n/* harmony import */ var _source_vue_vue_type_custom_index_0_blockType_foo__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./source.vue?vue&type=custom&index=0&blockType=foo */ \"./example/source.vue?vue&type=custom&index=0&blockType=foo\");\n\n\n\n\n\nvar cssModules = {}\nvar disposed = false\n\nfunction injectStyles (context) {\n if (disposed) return\n \n cssModules[\"$style\"] = (_source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_2__[\"default\"].locals || _source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_2__[\"default\"])\n Object.defineProperty(this, \"$style\", {\n configurable: true,\n get: function () {\n return cssModules[\"$style\"]\n }\n })\n \n}\n\n\n module.hot && module.hot.dispose(function (data) {\n disposed = true\n })\n\n\n\n module.hot && module.hot.accept([/*! ./source.vue?vue&type=style&index=0&module=true&lang=css& */ \"./example/source.vue?vue&type=style&index=0&module=true&lang=css&\"], function(__WEBPACK_OUTDATED_DEPENDENCIES__) { /* harmony import */ _source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./source.vue?vue&type=style&index=0&module=true&lang=css& */ \"./example/source.vue?vue&type=style&index=0&module=true&lang=css&\");\n(function () {\n var oldLocals = cssModules[\"$style\"]\n if (oldLocals) {\n var newLocals = __webpack_require__(/*! ./source.vue?vue&type=style&index=0&module=true&lang=css& */ \"./example/source.vue?vue&type=style&index=0&module=true&lang=css&\")\n if (JSON.stringify(newLocals) !== JSON.stringify(oldLocals)) {\n cssModules[\"$style\"] = newLocals\n __webpack_require__(/*! ./node_modules/vue-hot-reload-api/dist/index.js */ \"./node_modules/vue-hot-reload-api/dist/index.js\").rerender(\"27e4e96e\")\n }\n }\n })(__WEBPACK_OUTDATED_DEPENDENCIES__); })\n\n/* normalize component */\n\nvar component = Object(_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(\n _source_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n _source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__[\"render\"],\n _source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"],\n false,\n injectStyles,\n null,\n null\n \n)\n\n/* custom blocks */\n\nif (typeof _source_vue_vue_type_custom_index_0_blockType_foo__WEBPACK_IMPORTED_MODULE_4__[\"default\"] === 'function') Object(_source_vue_vue_type_custom_index_0_blockType_foo__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(component)\n\n/* hot reload */\nif (true) {\n var api = __webpack_require__(/*! ./node_modules/vue-hot-reload-api/dist/index.js */ \"./node_modules/vue-hot-reload-api/dist/index.js\")\n api.install(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm.js\"))\n if (api.compatible) {\n module.hot.accept()\n if (!module.hot.data) {\n api.createRecord('27e4e96e', component.options)\n } else {\n api.reload('27e4e96e', component.options)\n }\n module.hot.accept(/*! ./source.vue?vue&type=template&id=27e4e96e&lang=pug& */ \"./example/source.vue?vue&type=template&id=27e4e96e&lang=pug&\", function(__WEBPACK_OUTDATED_DEPENDENCIES__) { /* harmony import */ _source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./source.vue?vue&type=template&id=27e4e96e&lang=pug& */ \"./example/source.vue?vue&type=template&id=27e4e96e&lang=pug&\");\n(function () {\n api.rerender('27e4e96e', {\n render: _source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__[\"render\"],\n staticRenderFns: _source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"]\n })\n })(__WEBPACK_OUTDATED_DEPENDENCIES__); })\n }\n}\ncomponent.options.__file = \"example/source.vue\"\n/* harmony default export */ __webpack_exports__[\"default\"] = (component.exports);\n\n//# sourceURL=webpack:///./example/source.vue?");

/***/ }),

/***/ "./example/source.vue?vue&type=custom&index=0&blockType=foo":
/*!******************************************************************!*\
!*** ./example/source.vue?vue&type=custom&index=0&blockType=foo ***!
\******************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_lib_index_js_vue_loader_options_source_vue_vue_type_custom_index_0_blockType_foo__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../node_modules/babel-loader/lib!../lib??vue-loader-options!./source.vue?vue&type=custom&index=0&blockType=foo */ \"./node_modules/babel-loader/lib/index.js!./lib/index.js?!./example/source.vue?vue&type=custom&index=0&blockType=foo\");\n/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__[\"default\"] = (_node_modules_babel_loader_lib_index_js_lib_index_js_vue_loader_options_source_vue_vue_type_custom_index_0_blockType_foo__WEBPACK_IMPORTED_MODULE_0__[\"default\"]); \n\n//# sourceURL=webpack:///./example/source.vue?");

/***/ }),

/***/ "./example/source.vue?vue&type=script&lang=js&":
/*!*****************************************************!*\
!*** ./example/source.vue?vue&type=script&lang=js& ***!
\*****************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _lib_index_js_vue_loader_options_source_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../lib??vue-loader-options!./source.vue?vue&type=script&lang=js& */ \"./lib/index.js?!./example/source.vue?vue&type=script&lang=js&\");\n/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__[\"default\"] = (_lib_index_js_vue_loader_options_source_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__[\"default\"]); \n\n//# sourceURL=webpack:///./example/source.vue?");

/***/ }),

/***/ "./example/source.vue?vue&type=style&index=0&module=true&lang=css&":
/*!*************************************************************************!*\
!*** ./example/source.vue?vue&type=style&index=0&module=true&lang=css& ***!
\*************************************************************************/
/*! no static exports found */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_vue_style_loader_index_js_node_modules_css_loader_index_js_ref_3_oneOf_0_1_lib_loaders_stylePostLoader_js_lib_index_js_vue_loader_options_source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../node_modules/vue-style-loader!../node_modules/css-loader??ref--3-oneOf-0-1!../lib/loaders/stylePostLoader.js!../lib??vue-loader-options!./source.vue?vue&type=style&index=0&module=true&lang=css& */ \"./node_modules/vue-style-loader/index.js!./node_modules/css-loader/index.js?!./lib/loaders/stylePostLoader.js!./lib/index.js?!./example/source.vue?vue&type=style&index=0&module=true&lang=css&\");\n/* harmony import */ var _node_modules_vue_style_loader_index_js_node_modules_css_loader_index_js_ref_3_oneOf_0_1_lib_loaders_stylePostLoader_js_lib_index_js_vue_loader_options_source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_node_modules_css_loader_index_js_ref_3_oneOf_0_1_lib_loaders_stylePostLoader_js_lib_index_js_vue_loader_options_source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_0__);\n/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _node_modules_vue_style_loader_index_js_node_modules_css_loader_index_js_ref_3_oneOf_0_1_lib_loaders_stylePostLoader_js_lib_index_js_vue_loader_options_source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_0__) if(__WEBPACK_IMPORT_KEY__ !== 'default') (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _node_modules_vue_style_loader_index_js_node_modules_css_loader_index_js_ref_3_oneOf_0_1_lib_loaders_stylePostLoader_js_lib_index_js_vue_loader_options_source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__));\n /* harmony default export */ __webpack_exports__[\"default\"] = (_node_modules_vue_style_loader_index_js_node_modules_css_loader_index_js_ref_3_oneOf_0_1_lib_loaders_stylePostLoader_js_lib_index_js_vue_loader_options_source_vue_vue_type_style_index_0_module_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a); \n\n//# sourceURL=webpack:///./example/source.vue?");

/***/ }),

/***/ "./example/source.vue?vue&type=template&id=27e4e96e&lang=pug&":
/*!********************************************************************!*\
!*** ./example/source.vue?vue&type=template&id=27e4e96e&lang=pug& ***!
\********************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _lib_loaders_templateLoader_js_vue_loader_options_node_modules_pug_plain_loader_index_js_lib_index_js_vue_loader_options_source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../lib/loaders/templateLoader.js??vue-loader-options!../node_modules/pug-plain-loader!../lib??vue-loader-options!./source.vue?vue&type=template&id=27e4e96e&lang=pug& */ \"./lib/loaders/templateLoader.js?!./node_modules/pug-plain-loader/index.js!./lib/index.js?!./example/source.vue?vue&type=template&id=27e4e96e&lang=pug&\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return _lib_loaders_templateLoader_js_vue_loader_options_node_modules_pug_plain_loader_index_js_lib_index_js_vue_loader_options_source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__[\"render\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return _lib_loaders_templateLoader_js_vue_loader_options_node_modules_pug_plain_loader_index_js_lib_index_js_vue_loader_options_source_vue_vue_type_template_id_27e4e96e_lang_pug___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"]; });\n\n\n\n//# sourceURL=webpack:///./example/source.vue?");

/***/ }),
```
* 以上的部分输出就是可以直接拿到浏览器上运行的 `JavaScript`

## 输出分析
* 很明显,`.vue` 文件中的 `template``script``style` 、自定义块 四大语言块被拆成了四个可执行的 `javascript` 字符串,并使用 `eval` 进行执行。
* 这些代码虽然很难看懂,我们可以大致猜一下。
- `Template` 部分
从左往右看,`./source.vue` 先后被 `../lib/loaders/templateLoader.js``../node_modules/pug-plain-loader`处理过了。
`../lib/loaders/templateLoader.js` 的处理结果其实是将 `./source.vue` 中的 `template` 语言块抽出来之后,交给第三方包 `pug-plain-loader` 处理, 最终输出浏览器可解析的html。
- `Script` 部分
从右往左看, `./source.vue` 直接被 `./lib/index.js` 进行处理。


- `Style` 部分
从右往左看, `./source.vue` 先后被 `./lib/loaders/stylePostLoader.js``../node_modules/css-loader``../node_modules/vue-style-loader`给处理。
`./lib/loaders/stylePostLoader.js` 处理结果其实是将 `./source.vue` 中的 `style` 语言块抽出来,然后再交给第三方包 `css-loader``vue-style-loader` 依次处理, 最终输出浏览器可解析的css。

- `Custom` 部分
从右往左看,`./source.vue` 先后被 `../lib/index.js``../node_modules/babel-loader`进行处理,`../lib/index.js` 将自定义语言块抽取出来交给第三方包 `babel-loader` 处理。

## 小结
* 以上只是 `vue-loader` 输出文件的一小部分,还有其余的代码我们可以再花些时间分析一下。下节将针对这部分输出代码来分析 `vue-loader` 具体的处理逻辑。

0 comments on commit 4bda6be

Please sign in to comment.