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

本文介绍了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-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模块机制,编译后的代码格式如下,并且我做了代码美化,并且插上了中文注释

/******/ (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

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

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

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

/***/ })

2号模块

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

webpack 有所配置,所以导出的 Vue 实际上是 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,实际上就是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 异步更新机制使用到了它,所以被引入。

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

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

和 App.vue 的解析有关,把 App.vue 中的 template 和 script 编译为一个 vue components,并把 style 标签内的样式插入到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 函数。
  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号模块做插入。
/* 7 */

/***/
(function (module, exports, __webpack_require__) {

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

  // load the styles
  var content = __webpack_require__(8);
  if (typeof content === 'string') content = [
    [module.i, content, '']
  ];
  if (content.locals) module.exports = content.locals;
  // add the styles to the DOM
  var update = __webpack_require__(10)("15459d21", content, true);

  /***/
}),
/* 8 */
/***/
(function (module, exports, __webpack_require__) {

  // css-loader 用于做css的sourceMap
  exports = module.exports = __webpack_require__(9)(undefined);
  // imports

  // module
  // 这就是 App.vue 文件中 style 里的的 css
  exports.push([module.i, "#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:400}ul{list-style-type:none;padding:0}li{display:inline-block;margin:0 10px}a{color:#42b983}", ""]);

  // exports

  /***/
}),
/* 9 */
/***/
(function (module, exports) {
  // css base code, injected by the css-loader
  module.exports = function (useSourceMap) {
    // 省略代码...
  }
}),
/* 10 */
/***/
(function (module, exports, __webpack_require__) {
  /*
    MIT License http://www.opensource.org/licenses/mit-license.php
    Author Tobias Koppers @sokra
    Modified by Evan You @yyx990803
  */

  // ...太长只贴了关键步骤,总之关键的函数就是这些
  var hasDocument = typeof document !== 'undefined'
  // ...
  var listToStyles = __webpack_require__(11)
  // ...
  var head = hasDocument && (document.head || document.getElementsByTagName('head')[0])

  // ...
  module.exports = function (parentId, list, _isProduction) {

    // ...
    var styles = listToStyles(parentId, list)
    addStylesToDom(styles)

    return function update (newList) {
      // ...
    }
  }

  function addStylesToDom (styles /* Array<StyleObject> */) {
    for (var i = 0; i < styles.length; i++) {
      // ...
      domStyle.parts.push(addStyle(item.parts[j]))
      // ....
    }
  }

  // 总之先调用了addStylesToDom,接着是addStyle,再是createStyleElement插入样式到head中。
  function createStyleElement () {
  var styleElement = document.createElement('style')
  styleElement.type = 'text/css'
  head.appendChild(styleElement)
  return styleElement
  }

  function addStyle (obj /* StyleObjectPart */) {
    // ...
    styleElement = createStyleElement()
    // ...
  }

  /***/
}),
/* 11 */
/***/
(function (module, exports) {

  /**
   * Translates the list format produced by css-loader into something
   * easier to manipulate.
   */
  module.exports = function listToStyles(parentId, list) {
    var styles = []
    var newStyles = {}
    for (var i = 0; i < list.length; i++) {
      var item = list[i]
      var id = item[0]
      var css = item[1]
      var media = item[2]
      var sourceMap = item[3]
      var part = {
        id: parentId + ':' + i,
        css: css,
        media: media,
        sourceMap: sourceMap
      }
      if (!newStyles[id]) {
        styles.push(newStyles[id] = {
          id: id,
          parts: [part]
        })
      } else {
        newStyles[id].parts.push(part)
      }
    }
    return styles
  }

  /***/
}),

12、13、14号模块

12号做 .vue 文件中的 template 和 script 解析并供6号输出,最终返回了一个 vue components 对象,在浏览器控制台打印如下:

Object
  beforeCreate: [ƒ]
  data: ƒ data()
  inject: {}
  name: "app"
  render: ƒ ()
  staticRenderFns: (2) [ƒ, ƒ, cached: Array(2)]
  _Ctor: {0: ƒ}
  _compiled: true
  __proto__: Object

而13号模块返回具体 script 中的代码,而14号模块则是把 template 解析为一堆 vue render 函数。

/* 12 */
/***/
(function (module, exports) {

  /* globals __VUE_SSR_CONTEXT__ */

  // IMPORTANT: Do NOT use ES2015 features in this file.
  // This module is a runtime utility for cleaner component module output and will
  // be included in the final webpack user bundle.

  module.exports = function normalizeComponent(
    rawScriptExports,
    compiledTemplate,
    functionalTemplate,
    injectStyles,
    scopeId,
    moduleIdentifier /* server only */
  ) {
    var esModule
    var scriptExports = rawScriptExports = rawScriptExports || {}

    // ES6 modules interop
    var type = typeof rawScriptExports.default
    if (type === 'object' || type === 'function') {
      esModule = rawScriptExports
      scriptExports = rawScriptExports.default
    }

    // Vue.extend constructor export interop
    var options = typeof scriptExports === 'function' ?
      scriptExports.options :
      scriptExports

    // render functions
    if (compiledTemplate) {
      options.render = compiledTemplate.render
      options.staticRenderFns = compiledTemplate.staticRenderFns
      options._compiled = true
    }

    // functional template
    if (functionalTemplate) {
      options.functional = true
    }

    // scopedId
    if (scopeId) {
      options._scopeId = scopeId
    }

    var hook
    if (moduleIdentifier) { // server build
      hook = function (context) {
        // 2.3 injection
        context =
          context || // cached call
          (this.$vnode && this.$vnode.ssrContext) || // stateful
          (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
        // 2.2 with runInNewContext: true
        if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
          context = __VUE_SSR_CONTEXT__
        }
        // inject component styles
        if (injectStyles) {
          injectStyles.call(this, context)
        }
        // register component module identifier for async chunk inferrence
        if (context && context._registeredComponents) {
          context._registeredComponents.add(moduleIdentifier)
        }
      }
      // used by ssr in case component is cached and beforeCreate
      // never gets called
      options._ssrRegister = hook
    } else if (injectStyles) {
      hook = injectStyles
    }

    if (hook) {
      var functional = options.functional
      var existing = functional ?
        options.render :
        options.beforeCreate

      if (!functional) {
        // inject component registration as beforeCreate hook
        options.beforeCreate = existing ?
          [].concat(existing, hook) :
          [hook]
      } else {
        // for template-only hot-reload because in that case the render fn doesn't
        // go through the normalizer
        options._injectStyles = hook
        // register for functioal component in vue file
        options.render = function renderWithStyleInjection(h, context) {
          hook.call(context)
          return existing(h, context)
        }
      }
    }

    return {
      esModule: esModule,
      exports: scriptExports,
      options: options
    }
  }

  /***/
}),
/* 13 */
/***/
(function (module, __webpack_exports__, __webpack_require__) {

  "use strict";

  /* harmony default export */
  // 这就是 App.vue 中 script 的部分
  __webpack_exports__["a"] = ({
    name: 'app',
    data: function data() {
      return {
        msg: 'Welcome to Your Vue.js App'
      };
    }
  });

  /***/
}),
/* 14 */
/***/
(function (module, __webpack_exports__, __webpack_require__) {

  "use strict";
  // 把template 解析为一堆 render 函数,扔给vue处理最终编译成Vnode节点在渲染成DOM输出到视图
  var render = function () {
    var _vm = this;
    var _h = _vm.$createElement;
    var _c = _vm._self._c || _h;
    return _c('div', {
      attrs: {
        "id": "app"
      }
    }, [_c('h1', [_vm._v(_vm._s(_vm.msg))]), _vm._v(" "), _c('h2', [_vm._v("Essential Links")]), _vm._v(" "), _vm._m(0, false, false), _vm._v(" "), _c('h2', [_vm._v("Ecosystem")]), _vm._v(" "), _vm._m(1, false, false)])
  }
  var staticRenderFns = [function () {
    var _vm = this;
    var _h = _vm.$createElement;
    var _c = _vm._self._c || _h;
    return _c('ul', [_c('li', [_c('a', {
      attrs: {
        "href": "https://vuejs.org",
        "target": "_blank"
      }
    }, [_vm._v("Core Docs")])]), _vm._v(" "), _c('li', [_c('a', {
      attrs: {
        "href": "https://forum.vuejs.org",
        "target": "_blank"
      }
    }, [_vm._v("Forum")])]), _vm._v(" "), _c('li', [_c('a', {
      attrs: {
        "href": "https://chat.vuejs.org",
        "target": "_blank"
      }
    }, [_vm._v("Community Chat")])]), _vm._v(" "), _c('li', [_c('a', {
      attrs: {
        "href": "https://twitter.com/vuejs",
        "target": "_blank"
      }
    }, [_vm._v("Twitter")])])])
  }, function () {
    var _vm = this;
    var _h = _vm.$createElement;
    var _c = _vm._self._c || _h;
    return _c('ul', [_c('li', [_c('a', {
      attrs: {
        "href": "http://router.vuejs.org/",
        "target": "_blank"
      }
    }, [_vm._v("vue-router")])]), _vm._v(" "), _c('li', [_c('a', {
      attrs: {
        "href": "http://vuex.vuejs.org/",
        "target": "_blank"
      }
    }, [_vm._v("vuex")])]), _vm._v(" "), _c('li', [_c('a', {
      attrs: {
        "href": "http://vue-loader.vuejs.org/",
        "target": "_blank"
      }
    }, [_vm._v("vue-loader")])]), _vm._v(" "), _c('li', [_c('a', {
      attrs: {
        "href": "https://github.com/vuejs/awesome-vue",
        "target": "_blank"
      }
    }, [_vm._v("awesome-vue")])])])
  }]
  var esExports = {
    render: render,
    staticRenderFns: staticRenderFns
  }
  /* harmony default export */
  __webpack_exports__["a"] = (esExports);

  /***/
})

总结

结构梳理,一图胜千言

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • webpack+vue.js快速入门教程

    前言 vuejs--轻量.学习成本低.双向绑定.无dom的操作.组件的形式编写 vuejs是个轻量级的mvvm框架, 集合了angular的基本功能,却又比angular更为精简,功能上涵盖了双向绑定.指令.逻辑控制.过滤器.事件监听.函数等.框架的特点使得项目 在状态变更.分页的场景下可以拥有很大的便利--所有的操作只需要变更数组,没有任何的dom操作. webpack--CommonJS的引用和编写方式.loader非常的丰富,包括vue-loader.css-loader.less-loa

  • 详解如何使用webpack打包Vue工程

    使用webpack打包Vue工程 前言 入行一年,从什么都不懂的小白,到现在什么都懂一点的小白,也算是飞跃了.感叹一下现在的前端,从nodejs出来到现在各种各样的工具如雨后春笋般的出现.大神们疯狂的造轮子,玩的不亦乐乎.我等小白们,疯狂追赶,学的心肝脾肺都快衰竭.而我的精力也仅限浅尝辄止,但是学多一点总有好处的.本篇文章就是介绍如何使用webpack构建前端工程. 目标 本次的工程以Vue.js为主角,Vue.js是一款小巧优雅而且强大的轻量级mvvm框架,配合webpack模块化打包.制作出

  • 详解使用vue脚手架工具搭建vue-webpack项目

    对于Vue.js来说,如果你想要快速开始,那么只需要在你的html中引入一个<script>标签,加上CDN的地址即可.但是,这并不算是一个完整的vue实际应用.在实际应用中,我们必须要一系列的工具,包括:模块化,转译,预处理,热加载,静态检测和自动化测试等.对于一个需要长期维护和大型的项目而言,这些工具是必不可少的,但是尝试配置初始化这些很痛苦.这就是我们发布vue官方提供的脚手架工具的原因,一个简单的构建工具,通过几个默认的步骤帮助你快速的构建Vue.js项目. 1.安装node环境 可以

  • Webpack+Vue如何导入Jquery和Jquery的第三方插件

    创建一个jquery-vendor.js文件 import $ from 'jQuery'; console.log($); window.$ = $; window.jQuery = $; export default $; 导入JQuery,并赋值给window对象,使其成为一个全局变量. 在vue组件做如下引用 import $ from './assets/jquery-v'; import 'bootstrap-material-design'; //调用初始化 $(function(

  • windows下vue-cli及webpack搭建安装环境

    1.安装Node.js,node.js安装包及源码下载地址为:https://nodejs.org/en/download/. 2.安装npm,由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了.同样可以通过输入 "npm -v" 来测试是否成功安装.命令如下,出现版本提示表示安装成功: $ npm -v 3.10.8 如果你安装的是旧版本的 npm,可以很容易得通过 npm 命令来升级,命令如下: npm install npm -g 你可以使用淘宝定制的 cnpm

  • Vue.js中用webpack合并打包多个组件并实现按需加载

    前言 随着移动设备的升级.网络速度的提高,用户对于web应用的要求越来越高,web应用要提供的功能越来越.功能的增加导致的最直观的后果就是资源文件越来越大.为了维护越来越庞大的客户端代码,提出了模块化的概念来组织代码.webpack作为一种模块化打包工具,随着react的流行也越来越流行. 使用 Vue 开发项目时,如果要使用其单文件组件特性,必然要使用 webpack 或者 browserify 进行打包,对于大型应用,为了提升加载速度,可以使用 webpack 的 code split 功能

  • webpack+vue.js实现组件化详解

    简介 在vue中实现组件化用到了vue特有的文件格式.vue,在每一个.vue文件就是一个组件,在组件中我们将html,css,js全部写入,然后在webpack中配置vue-loader就可以了. 建立vue组件 在src目录下建立components文件夹,并在其中建立app.vue文件,这样我们项目的目录结构如下: |--dist //webpack打包后生成的文件夹 | |--build.js |--node_modules //项目的依赖所在的文件夹 |--src //文件入口 | |

  • vue-cli的webpack模板项目配置文件分析

    由于最近在vue-cli生成的webpack模板项目的基础上写一个小东西,开发过程中需要改动到build和config里面一些相关的配置,所以刚好趁此机会将所有配置文件看一遍,理一理思路,也便于以后修改配置的时候不会"太折腾". 一.文件结构 本文主要分析开发(dev)和构建(build)两个过程涉及到的文件,故下面文件结构仅列出相应的内容. ├─build │ ├─build.js │ ├─check-versions.js │ ├─dev-client.js │ ├─dev-ser

  • 基于vuejs+webpack的日期选择插件

    基于vuejs+webpack环境使用的日期选择插件,希望大家喜欢. 支持单选和多选日期 支持限定开始和结束日期范围选择. 支持小时分钟 需要引入fontawesome.io 的图标库. Options :show 是否显示 :type date|datetime :value 默认值 :begin 可选开始时间 :end 可选结束时间 :x 显示x坐标 :y 显示y坐标 :range 是否多选 test.vue <template> <input type="text&quo

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

    本文介绍了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"> &l

  • 浅谈webpack打包生成的bundle.js文件过大的问题

    问题 使用webpack进行打包时,发现bundle.js竟然有2M多. 解决办法 网上有去除插件.提取第三方库.压缩代码等方法. 还有一个比较容易忽略的原因就是开了sourcemap 在生产环境中,应使用devtool: false 关闭sourcemap后bundle.js的大小从2.46M降到302k 以上这篇浅谈webpack打包生成的bundle.js文件过大的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: 彻底解决 webpa

  • 详解webpack打包vue项目之后生成的dist文件该怎么启动运行

    亲测,webpack打包vue项目之后生成的dist文件可以部署到 express 服务器上运行. 我的vue项目结构如下: 1. 进入该vue项目目录,打开git bash,执行:npm run build(在package.json的scripts配置) 执行成功如下图所示: 然后此时你会发现项目下多了一个 dist 文件夹,dist下文件便是项目打包之后生成的文件. 此时我们直接在浏览器中打开index.html,是会报错的,什么都看不到. 2. 安装express-generator生成

  • 浅谈webpack下的AOP式无侵入注入

    说起来, 面向切面编程(AOP)自从诞生之日起,一直都是计算机科学领域十分热门的话题,但是很奇怪的是,在前端圈子里,探讨AOP的文章似乎并不是多,而且多数拘泥在给出理论,然后实现个片段的定式)难免陷入了形而上学的尴尬境地,本文列举了两个生产环境的实际例子论述webpack和AOP预编译处理的结合,意在抛砖引玉.当然,笔者能力有限,如果有觉得不妥之处,还请大家积极的反馈出来, 共同进步哈. 重要的概念 AOP: 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. Joi

  • 浅谈webpack打包过程中因为图片的路径导致的问题

    最近在制作一个自己的个人博客的时候遇到这么一个问题, 在CSS中使用了相对路径来充当背景图片, 如下所示: 然后将整个工程使用webpack打包之后, 在浏览器上运行却报错了, 报错如下: 也就是说, 打包之后这个图片文件找不到了, 那么原因出在哪里呢? 先来看一下我在webpack.config.js文件中的配置: 在这里其实我的loader并没有使用错误的, 图片对应的就是使用url-loader来处理. 那么再来看一下通过webpack打包之后的目录: 发现dist文件夹中出现了我们想要打

  • 浅谈webpack构建工具配置和常用插件总结

    webpack构建工具已经火了好几年,也是当下狠火狠方便的构建工具,我们没有理由不去学习.既然选择webpack就要跟着时代走,我们要追随大牛的步伐,大牛等等我. 一.webpack基础 在根目录使用npm init 命令创建package.json,创建过程中一路回车. 本地安装webpack命令:npm install webpack webpack-cli --save-dev 安装成功后写入package.js的devDependencies中,可以通过 npm node_modules

  • webpack搭建vue 项目的步骤

    前期准备 webpack vue.js npm nodejs ES6语法 由于本文内容是通过npm来加载vue,所以开始之前需安装nodejs环境,安装完成之后再执行以下步骤: 创建项目 mkdir vue-demo cd vue-demo 使用 npm init 命令 生成package.json文件 npm init 大概生成的package.json 如下: { "name": "vue-demo", "version": "1.

  • 浅谈Webpack是如何打包CommonJS的

    目录 一.书写代码 二.使用webpack打包编译 三.解析 CommonJS 是 Node 中的一种模块化规范,其是一种运行在 Node 环境下的代码,这种代码是不能直接运行到浏览器环境中的.但是在日常使用 webpack 的项目中不用做额外的处理,我们也能使用 CommonJS 来书写代码,那么 webpack 在这背后做了什么呢? 我们这里不看编译时,只看运行时 一.书写代码 使用yarn init -y命令初始化一个package.json文件. 接着yarn add webpack安装

  • 详解如何使用webpack在vue项目中写jsx语法

    本文介绍了如何使用webpack在vue项目中写jsx语法,分享给大家,具体如下: 我们知道Vue 2.0中对虚拟DOM的支持.我们可以通过JavaScript动态的创建元素,而不用在template中写HTML代码.虚拟DOM最终将被渲染为真正的DOM. data: { msg: 'Hello world' }, render (h) { return h( 'div', { attrs: { id: 'my-id' }, [ this.msg ] ); } 渲染后的内容为: <div id=

  • 浅谈webpack打包之后的文件过大的解决方法

    以前一直使用 create-react-app 这个脚手架进行 react 开发,后面因为一些自定义的配置,转而使用 webpack 搭建一套自己的脚手架.但是在使用 webpack 打包之后发现,纳尼?怎么文件这么大??? 于是研究了一下如何处理 webpack 打包之后文件太大的情况,简单记录下来. 首先配置全局变量 首先,通过指定环境,告诉 webpack 我们当前处于 production 环境中,要按照 production 的方式去打包. //指定环境,将process.env.NO

随机推荐