vue按需加载组件webpack require.ensure的方法


Posted in Javascript onDecember 13, 2017

vue-cli是由vue官方发布的快速构建vue单页面的脚手架。

使用 vue-cli构建的项目,在 默认情况下 ,执行 npm run build 会将所有的js代码打包为一个整体,

打包位置是 dist/static/js/app.[contenthash].js

类似下面的路由代码

router/index.js 路由相关信息,该路由文件引入了多个 .vue组件

import Hello from '@/components/Hello'
import Province from '@/components/Province'
import Segment from '@/components/Segment'
import User from '@/components/User'
import Loading from '@/components/Loading'

执行 npm run build 会打包为一个整体 app.[contenthash].js ,这个文件是非常大,可能几兆或者几十兆,加载会很慢

vue按需加载组件webpack require.ensure的方法

所以我们需要分模块打包,把我们想要组合在一起的组件打包到一个 chunk块中去,分模块打包需要下面这样使用 webpack的 require.ensure,并且在最后加入一个 chunk名,相同 chunk名字的模块将会打包到一起。

webpack中利用require.ensure()实现按需加载

1、require.ensure()

webpack 在编译时,会静态地解析代码中的 require.ensure(),同时将模块添加到一个分开的 chunk 当中。这个新的 chunk 会被 webpack 通过 jsonp 来按需加载。

语法如下:

require.ensure(dependencies: String[], callback: function(require), chunkName: String)

依赖 dependencies

这是一个字符串数组,通过这个参数,在所有的回调函数的代码被执行前,我们可以将所有需要用到的模块进行声明。

回调 callback

当所有的依赖都加载完成后,webpack会执行这个回调函数。require 对象的一个实现会作为一个参数传递给这个回调函数。因此,我们可以进一步 require() 依赖和其它模块提供下一步的执行。

chunk名称 chunkName

chunkName 是提供给这个特定的 require.ensure() 的 chunk 的名称。通过提供 require.ensure() 不同执行点相同的名称,我们可以保证所有的依赖都会一起放进相同的 文件束(bundle)。

让我们来看以下的项目

\\ file structure
  |
  js --|
  |  |-- entry.js
  |  |-- a.js
  |  |-- b.js
  webpack.config.js
  |
  dist
\\ entry.js
require('a');
require.ensure([], function(require){
  require('b');
});
\\ a.js
console.log('***** I AM a *****');
\\ b.js
console.log('***** I AM b *****');
\\ webpack.config.js
var path = require('path');
module.exports = function(env) {
  return {
    entry: './js/entry.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  }
}

通过执行这个项目的 webpack 构建,我们发现 webpack 创建了2个新的文件束, bundle.js 和 0.bundle.js。

entry.js 和 a.js 被打包进 bundle.js.

b.js 被打包进 0.bundle.js.

2、require.ensure() 的坑点

(1)、空数组作为参数

require.ensure([], function(require){
  require('./a.js');
});

以上代码保证了拆分点被创建,而且 a.js 被 webpack 分开打包。

(2)、依赖作为参数

require.ensure(['./a.js'], function(require) {
  require('./b.js');
});

上面代码, a.js 和 b.js 都被打包到一起,而且从主文件束中拆分出来。但只有 b.js 的内容被执行。a.js 的内容仅仅是可被使用,但并没有被输出。

想去执行 a.js,我们需要异步地引用它,如 require(‘./a.js'),让它的 JavaScritp 被执行。

(3)、单独打包成自己写的名字配置

需要配置chunkFilename,和publicPath。publicPath是按需加载单独打包出来的chunk是以publicPath会基准来存放的,chunkFilename:[name].js这样才会最终生成正确的路径和名字

module.exports={
  entry:'./js/entry.js',
  output:{
    path:path.resolve(__dirname,"./dist"),
    filename:'js/a.bundle.js',
    publicPath:"./",
    chunkFilename:'js/[name].js'
  }

所以router/index.js 修改为懒加载组件:

const Province = r => require.ensure([], () => r(require('@/components/Province.vue')), 'chunkname1')
const Segment = r => require.ensure([], () => r(require('@/components/Segment.vue')), 'chunkname2')
const Loading = r => require.ensure([], () => r(require('@/components/Loading.vue')), 'chunkname3')
const User = r => require.ensure([], () => r(require('@/components/User.vue')), 'chunkname3')

根据 chunkame的不同, 上面的四个组件, 将会被分成3个块打包,最终打包之后与组件相关的js文件会分为3个 (除了app.js,manifest.js, vendor.js)

分模块打包之后在 dist目录下是这样的, 这样就把一个大的 js文件分为一个个小的js文件了,按需去下载,其他的使用方法和import的效果一样

vue按需加载组件webpack require.ensure的方法

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

Javascript 相关文章推荐
能说明你的Javascript技术很烂的五个原因分析
Oct 28 Javascript
jQuery 借助插件Lavalamp实现导航条动态美化效果
Sep 27 Javascript
js字符串操作方法实例分析
May 06 Javascript
微信小程序前端源码逻辑和工作流
Sep 25 Javascript
Jquery根据浏览器窗口改变调整大小的方法
Feb 07 Javascript
Vue.js之slot深度复制详解
Mar 10 Javascript
Angularjs+bootstrap+table多选(全选)支持单击行选中实现编辑、删除功能
Mar 27 Javascript
微信小程序使用radio显示单选项功能【附源码下载】
Dec 11 Javascript
vue-lazyload图片延迟加载插件的实例讲解
Feb 09 Javascript
Vue props用法详解(小结)
Jul 03 Javascript
JS的Ajax与后端交互数据的实例
Aug 08 Javascript
javascript拖曳互换div的位置实现示例
Jun 28 Javascript
vue实现某元素吸顶或固定位置显示(监听滚动事件)
Dec 13 #Javascript
vue组件中使用iframe元素的示例代码
Dec 13 #Javascript
vue中路由验证和相应拦截的使用详解
Dec 13 #Javascript
vue实现nav导航栏的方法
Dec 13 #Javascript
vue实现导航栏效果(选中状态刷新不消失)
Dec 13 #Javascript
仿京东快报向上滚动的实例
Dec 13 #Javascript
Angular2使用vscode断点调试ts文件的方法
Dec 13 #Javascript
You might like
re0第二季蕾姆被制作组打入冷宫!艾米莉亚女主扶正,原因唏嘘
2020/04/02 日漫
Yii2创建表单(ActiveForm)方法详解
2016/07/23 PHP
form自动提交实例讲解
2017/07/10 PHP
关于Laravel-admin的基础用法总结和自定义model详解
2019/10/08 PHP
List all the Databases on a SQL Server
2007/06/21 Javascript
利用Ext Js生成动态树实例代码
2008/09/08 Javascript
基于jQuery的简单九宫格实现代码
2012/08/09 Javascript
减少访问DOM的次数提升javascript性能
2014/02/24 Javascript
JQuery 使用attr方法实现下拉列表选中
2014/10/13 Javascript
JavaScript原生对象之Date对象的属性和方法详解
2015/03/13 Javascript
javascript实现类似百度分享功能的方法
2015/07/27 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
2015/11/02 Javascript
理解AngularJs指令
2015/12/10 Javascript
原生js二级联动效果
2017/06/20 Javascript
node中koa中间件机制详解
2017/08/22 Javascript
js仿微信抢红包功能
2020/09/25 Javascript
如何在 JavaScript 中更好地利用数组
2018/09/27 Javascript
typescript nodejs 依赖注入实现方法代码详解
2019/07/21 NodeJs
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
JS前端模块化原理与实现方法详解
2020/03/17 Javascript
vue+elementUI实现简单日历功能
2020/09/24 Javascript
[42:32]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第二场 11.27
2020/12/01 DOTA
python实现nao机器人手臂动作控制
2019/04/29 Python
python读取大文件越来越慢的原因与解决
2019/08/08 Python
python怎么提高计算速度
2020/06/11 Python
Why do we need Unit test
2013/01/03 面试题
七年级音乐教学反思
2014/01/26 职场文书
《蚂蚁和蝈蝈》教学反思
2014/02/24 职场文书
《鲁班和橹板》教学反思
2014/04/27 职场文书
户籍证明格式
2014/09/15 职场文书
合同和协议有什么区别?
2014/10/08 职场文书
会计电算化实训报告
2014/11/04 职场文书
考研英语复习计划
2015/01/19 职场文书
2015小学语文教师个人工作总结
2015/05/20 职场文书
2015年乡镇食品安全工作总结
2015/10/22 职场文书
MySQL连表查询分组去重的实现示例
2021/07/01 MySQL