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


Posted in Javascript onFebruary 17, 2017

前言

随着移动设备的升级、网络速度的提高,用户对于web应用的要求越来越高,web应用要提供的功能越来越。功能的增加导致的最直观的后果就是资源文件越来越大。为了维护越来越庞大的客户端代码,提出了模块化的概念来组织代码。webpack作为一种模块化打包工具,随着react的流行也越来越流行。

使用 Vue 开发项目时,如果要使用其单文件组件特性,必然要使用 webpack 或者 browserify 进行打包,对于大型应用,为了提升加载速度,可以使用 webpack 的 code split 功能进行分割打包,生成较小的模块并按需加载,这在 Vue 文档及 vue-router 文档中均有介绍:Async Components、Lazy Loading。

webpack 的 code split 可以使用 webpack 的 require.ensure 特殊语法或者使用 AMD 风格的 callback-require 语法,以 AMD 风格的 callback-require 语法为例——

全局注册 Async Component:

let myAsyncComponent = resolve => {
 require(['./my-async-component'], resolve)
}
Vue.component('async-webpack-example', myAsyncComponent)

局部注册 Async Component,单文件组件中 script 块内容:

let myAsyncComponent = resolve => {
 require(['./my-async-component'], resolve)
}

// Vue 扩展实例选项,其他选项略
export default {
 components: {
 'async-webpack-example': myAsyncComponent
 }
}

在使用 vue-router 时,为实现不同路由下的组件异步加载,在路由映射中可以使用同样的方式来设置路由项的 component 属性。

这里的 myAsyncComponent 被定义为一个工厂函数,在需要时才会以 Vue 或者 vue-router 定义的用于解析组件选项的 resolve 回调函数(是的,在 Vue 和 vue-router 中有两个不同的解析组件选项的函数)为参数执行 callback-require 函数(resolve 回调函数的参数是组件选项),这样,在执行打包脚本时,my-async-component.vue 文件会被单独打包成一个文件,并且仅当该组件被使用时才会加载。

当要求异步加载的组件较多时,将会生成更多的单个文件,对于前端性能而言,虽然每个文件更小了,但可能意味着更多的网络连接建立和关闭的开销,因此在前端优化的实践中,通常需要在文件数量和单个文件大小之间取得平衡。

本文介绍如何将多个组件合并打包成一个单独的文件,一方面可以减少代码块的数量,另一方面,如果合并打包的这些组件在不同地方多次重复使用,由于 Vue 的缓存机制,可以加快后续组件的加载速度,并且如果这些通用组件长时间不会变化(如 UI 相关的组件),打包生成的文件也长期不会变化,可以充分利用浏览器的缓存功能,实现前端加载速度的优化。

先上效果图,在使用 vue-router 的 SPA 应用中,将除根路由之外的路由项对应的 ComponentA、ComponentB、ComponentC 等三个组件合并打包成一个文件。初次加载页面时,从开发者工具的 Network 面板上可以看到,此时未加载包含 ComponentA、ComponentB、ComponentC 这三个组件的 0.a5a1bae6addad442ac82.js 文件,当点击 Page A 链接时,加载了该文件,然后再点击 Page B、Page C 链接时,没有重新加载该文件。

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

我们首先通过 vue-cli 命令行工具使用 webpack 项目模板创建一个包含 vue-router 的项目,在其 src/components 目录下创建一个 CommonComponents 目录,在该目录中创建 ComponentA、ComponentB、ComponentC 这三个组件。

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

同时在 CommonComponents 目录下创建 index.js,其内容如下:

exports.ComponentA = require('./ComponentA')
exports.ComponentB = require('./ComponentB')
exports.ComponentC = require('./ComponentC')

这样,我们只需要使用 webpack 的 require.ensure 特殊语法或者使用 AMD 风格的 callback-require 语法异步加载 CommonComponents 目录下的 index.js,在使用 webpack 进行打包时,就可以实现将 ComponentA、ComponentB、ComponentC 这三个组件合并打包。以 AMD 风格的 callback-require 语法为例示范如下,这里的 callback 回调函数的形式没有任何特殊要求。

require(['component/CommonComponents'], function (CommonComponents) {
 // do whatever you want with CommonComponents
})

component/CommonComponents 模块加载成功时,这里的回调函数中的 CommonComponents 参数将会是一个包含 ComponentA、ComponentB、ComponentC 这三个组件选项的对象。

在定义异步解析组件时,我们使用的是一个工厂函数 resolve => {require(['./my-async-component'], resolve)},如果需要在路由配置文件中添加 component 属性为 ComponentA 组件的路由项,应该定义什么样的工厂函数呢?记住这里的 resolve 是一个用于解析组件选项的回调函数,其参数是所获取的组件选项,而上一段代码中的 CommonComponents 恰好是包含若干个组件选项的对象,因此我们可以将 CommonComponents 的子属性作为参数用于 resolve 调用,我们编写一个函数 getCommonComponent,用于根据组件名称返回获取相应的组件选项的工厂函数。

let getCommonComponent = componentName => resolve => require(['components/CommonComponents'], components => resolve(components[componentName]))

在组件模板或者路由映射等使用其中某一个组件的地方,可以使用类似于 getCommonComponent('ComponentA') 这样的函数调用进行组件设置,在路由映射中的使用示例如下:

routes: [
 {
 path: '/',
 name: 'Hello',
 component: Hello
 },
 {
 path: '/a',
 name: 'A',
 component: getCommonComponent('ComponentA')
 },
 {
 path: '/b',
 name: 'B',
 component: getCommonComponent('ComponentB')
 },
 {
 path: '/c',
 name: 'C',
 component: getCommonComponent('ComponentC')
 }
]

最终打包生成的文件列表如下图所示,其中的 0.a5a1bae6addad442ac82.js 包含了 ComponentA、ComponentB、ComponentC 这三个组件。

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery live
May 15 Javascript
Jquery Ajax学习实例4 向WebService发出请求,返回实体对象的异步调用
Mar 16 Javascript
jquery控制左右箭头滚动图片列表的实例
May 20 Javascript
禁止拷贝网页内容的js代码
Jan 22 Javascript
js 与 php 通过json数据进行通讯示例
Mar 26 Javascript
浅谈EasyUI中编辑treegrid的方法
Mar 01 Javascript
Javascript简写条件语句(推荐)
Jun 12 Javascript
简单实现的JQuery文本框水印插件
Jun 14 Javascript
Ionic 2 实现列表滑动删除按钮的方法
Jan 22 Javascript
通过一个简单的例子学会vuex与模块化
Nov 22 Javascript
微信小程序页面间跳转传参方式总结
Jun 13 Javascript
vue中使用极验验证码的方法(附demo)
Dec 04 Javascript
浅析JavaScript中var that=this
Feb 17 #Javascript
Bootstrap表格使用方法详解
Feb 17 #Javascript
BootStrap与Select2使用小结
Feb 17 #Javascript
解决给dom元素绑定click等事件无效问题的方法
Feb 17 #Javascript
Vue.js原理分析之observer模块详解
Feb 17 #Javascript
BootStrap的select2既可以查询又可以输入的实现代码
Feb 17 #Javascript
Bootstrap表单使用方法详解
Feb 17 #Javascript
You might like
《OVERLORD》第四季,终于等到你!
2020/03/02 日漫
PHP自动生成后台导航网址的最佳方法
2013/08/27 PHP
thinkphp的静态缓存用法分析
2014/11/29 PHP
深入理解PHP的远程多会话调试
2017/09/21 PHP
Js+Dhtml:WEB程序员简易开发工具包(预先体验版)
2006/11/07 Javascript
学习YUI.Ext 第三天
2007/03/10 Javascript
JavaScript中的其他对象
2008/01/16 Javascript
兼容IE和FF的图片上传前预览js代码
2013/05/28 Javascript
浅析JavaScript事件和方法
2015/02/28 Javascript
利用JavaScript的AngularJS库制作电子名片的方法
2015/06/18 Javascript
jQuery查找节点方法完整实例
2016/09/13 Javascript
JavaScript编写一个贪吃蛇游戏
2017/03/09 Javascript
微信小程序实现给循环列表添加点击样式实例
2017/04/26 Javascript
vue打包后显示空白正确处理方法
2017/11/01 Javascript
详解利用Angular实现多团队模块化SPA开发框架
2017/11/27 Javascript
js html实现计算器功能
2018/11/13 Javascript
如何在postman中添加cookie信息步骤解析
2020/06/30 Javascript
node中短信api实现验证码登录的示例代码
2021/01/20 Javascript
python计算auc指标实例
2017/07/13 Python
Python 反转字符串(reverse)的方法小结
2018/02/20 Python
python针对excel的操作技巧
2018/03/13 Python
Python实现微信消息防撤回功能的实例代码
2019/04/29 Python
使用python list 查找所有匹配元素的位置实例
2019/06/11 Python
基于Django的乐观锁与悲观锁解决订单并发问题详解
2019/07/31 Python
猫途鹰:全球领先的旅游点评社区
2017/04/07 全球购物
Uber Eats台湾:寻找附近提供送餐服务的餐厅
2018/05/07 全球购物
法国设计制造的扫帚和刷子:Andrée Jardin
2018/12/06 全球购物
美国最佳在线航班预订网站:LookupFare
2019/03/26 全球购物
Delphi笔试题
2016/11/14 面试题
巧克力蛋糕店创业计划书
2014/01/14 职场文书
优秀少先队辅导员先进事迹材料
2014/05/18 职场文书
关于青春的演讲稿500字
2014/08/22 职场文书
中职三好学生事迹材料
2014/08/24 职场文书
2014年大学生社会实践自我鉴定
2014/09/26 职场文书
小学大队干部竞选稿
2015/11/20 职场文书
PyTorch 如何自动计算梯度
2021/05/23 Python