平常遇到喜欢的页面总喜欢拿来欣赏一番,今天就以webpack+vue的项目为例分析一下打包后的源码。
环境:
webpack4.16
vue2.5.16

为了方便理解,先使用webpack打一个最简单的包(未使用vue),下面是混淆压缩前的伪代码

(function (modules) {
  var installedModules = {} // 缓存模块

   // 处理AMD commonjs  ESModule
  function __webpack_require__(moduleId)() {  ...  return module.exports}
  __webpack_require__.m
  __webpack_require__.c
  __webpack_require__.d
  __webpack_require__.r
  __webpack_require__.n
  __webpack_require__.o
  __webpack_require__.p

  return __webpack_require__(__webpack_require__.s = "./src/index.js")
})(obj)

var obj = {

  // 入口js处理
  './src/index.js': (function(module, __webpack_exports__, __webpack_require__) {"use strict";
    eval(`__webpack_require__.r(__webpack_exports__);\n/* harmony import */
    var _js_home__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./js/home */ \"./src/js/home.js\");\n/* harmony import */
    var _js_home__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_js_home__WEBPACK_IMPORTED_MODULE_0__);\n\r\n\r\n
    console.log('index.js')\n\n//# sourceURL=webpack:///./src/index.js?`);
  }),

  // 其他js处理
  './src/js/home.js': {
    (function (module, exports,__webpack_require__) {
      eval("console.log('home') \n\n//# sourceURL=webpack:///./src/js/home.js?")
    })
  }
}

从结果来看,文件由一个立即执行函数(IIFE)组成,IIFE内部是webpack用于模块处理的逻辑,不需要关心,真正的业务逻辑以参数的形式传入,也就是obj,这个是我们需要重点关注的。
接下来是webpack+vue混淆压缩后的伪代码

!function(e){}([function(e, t, n){},function(e, t, n){},...])

通过和上一段代码对比,可以知道各个参数的含义

e: module  t:export  n:__webpack_require__

那么一个vue文件压缩后的是怎么样的,下面我从压缩文件中提取组成的代码片段



//-------------------template压缩前------------------
<div class="home">
  <img class="logo" src="../images/logo.png"/>
  <h1>hello VueDemo</h1>
</div>
//-------------------template压缩后------------------
function (e, t, n) { 
  "use strict";
  var r = function () {
      var e = this.$createElement;
      this._self._c;
      return this._m(0)
    },
    a = [function () {
      var e = this.$createElement,
        t = this._self._c || e;
      return t("div", {
        staticClass: "home"
      }, [t("img", {
        staticClass: "logo",
        attrs: {
          src: n(68)
        }
      }), this._v(" "), t("h1", [this._v("hello VueDemo")])])
    }];
  r._withStripped = !0, n.d(t, "a", function () {
    return r
  }), n.d(t, "b", function () {
    return a
  })
}
//n(68): images/logo.82b9c7.png
//function (e, t, n) {
//e.exports = n.p + "images/logo.82b9c7.png"
//}
//n(0): window    n(2): vue

// -------------------script压缩前------------------
export default {
  data() {
    return {
      name: 'home'
    }
  },
  mounted() {},
  methods: {},
  components: {}
}
// -------------------script压缩后------------------
function (e, t, n) {
  "use strict";
  Object.defineProperty(t, "__esModule", {
    value: !0
  });
  n(45);
  t.default = {
    data: function () {
      return {
        name: "home"
      }
    },
    mounted: function () {},
    methods: {},
    components: {}
  }
}

// -------------------style压缩前------------------
.home{font-size: 16px;text-align: center;}
.logo{width: 100px;margin: 50px;}
// -------------------style压缩后------------------
function (e, t, n) {
  var r = n(66);
  "string" == typeof r && (r = [
    [e.i, r, ""]
  ]), r.locals && (e.exports = r.locals);
  (0, n(10).default)("d1dbaf94", r, !1, {})
}
//n(66):
//.home[data-v-324fb87d] {font-size: 0.21333333rem;text-align: center;}
//.logo[data-v-324fb87d] {width: 1.33333333rem; margin: 0.66666667rem;}
//function (e, t, n) {
//(e.exports = n(11)(!1)).push([e.i, "\n.home[data-v-324fb87d] {\n  font-size: 0.21333333rem;\n  text-align: center;\n}\n.logo[data-v-324fb87d] {\n  width: 1.33333333rem;\n  margin: 0.66666667rem;\n}", ""])
//}

可以看到template模板中的t其实就是一个render函数,在render中构建一个vnode来描述原来DOM,之后如果修改template,vue就使用diff算法更新DOM。

Logo

前往低代码交流专区

更多推荐