在上一篇 webpack练手项目之easySlide(一):初探webpack 中我们一起为大家介绍了webpack的基本用法,使用webpack对前端代码进行模块化打包。
但是乍一看webpack只是将所有资源打包到一个JS文件中而已,并没有做到真正的按需加载,这当然不是我们所想要的。
不急,今天的这一章我们就来一起继续探索webpack的另外一个功能:code split.
1.什么是code split
英文不好,暂且将其翻译为代码分割。也就是我们根据实际业务需求将代码进行分割,然后在合适的时候在将其加载进入文档中。
这里举一个实际应用场景:上次我们做的图片轮播,我们为每张图片都添加一个点击事件,点击以后我们弹出一个对话框,里面介绍一些详细内容,然后可以点击关闭按钮进行关闭。
在这个需求中我们发现,对话框这个组件比较特殊,他是在用户点击图片以后才需要加载,如果用户不点击,那么他就没有必要加载出来了。
OK,很好。webpack通过code split方法将页面必须加载的资源放在bundle.js中,然后对于按需加载的资源通过ajax进行异步加载。
webpack通过 require.ensure 来判断是否对资源进行按需加载。
下面是官网的简单用例:
1 require.ensure(["module-a", "module-b"], function(require) {
2 var a = require("module-a");
3 // ...
4 });
2.Demo与Code
同样的,我已经将上面所说的对话框按需加载实现,大家感兴趣的话可以前往查看:
Demo: http://xiaoyunchen.github.io/easySlide/
Code: https://github.com/xiaoyunchen/easySlide
大家可以打开控制台网络面板,查看资源的加载情况:
页面加载的时候只有7个请求,这其中其实并没有包含我们的对话框组件:
然后大家可以点击任意一张图片,这个时候网络浏览器发送了新的网络请求,然后页面上也打开了对话框:
这个2.chunk.js也就是webpack为我们打包的对话框组件,包括JS逻辑,HTML模板以及CSS样式,稍后我们将为大家作详细介绍。
(demo上有几个menu的link,大家先不用管,那是我们下一章将要介绍的内容)
3.组件引用与webpack打包
接下来我们来看看代码上都发生了哪些变动。
首先是index.html与index.css,并没有任何修改。(index.html中增加了header与footer,增加了多个图片轮播组件,为下一章做的准备。但是都与对话框组件没有任何关系)
那来看看index.js的修改,具体的源码大家可以查看github,这里只对后面新增的代码进行分析:
1 //添加对话框事件
2 var pageDialog=false;
3 $('.pictureShow a').click(function(){
4 var _id=$(this).attr('dialog-for');
5 require.ensure(["../module/dialog.js","../module/dialogConfig.js"], function(require) {
6 var dialogModule=require("../module/dialog.js");
7 var dialogConfig=require("../module/dialogConfig.js");
8 if(!pageDialog){ //判断对话框组件是否存在,避免重复创建
9 pageDialog=new dialogModule();
10 }
11 pageDialog.openDialogWith(dialogConfig[_id]);
12 });
13 });
首先我们定义了一个对象,然后为页面上所有的滑动元素增加了一个单击事件。
第4行:获取当前事件元素的dialog-for属性,这是我们在每个滑动元素上新增的属性,用于指定其对应的对话框id
第5行:使用了webpack的require.ensure异步加载了两个组件:dialog与dialogConfig,这两个组件分别是对话框的具体实现逻辑以及对话框内容配置信息,详细的代码我们后面再分析
第6/7行:加载完成后得到两个组件的引用
第8-10行:判断pageDialog是否存在,如果不存在我们通过调用dialog组件new一个实例,并将赋值给pageDialog。
这里主要是为了避免多次点击时页面重复创建dialog Html元素,降低页面性能
第11行:使用pageDialog实例,调用openDialogWith方法来打开对话框,同时要从dialogConfig中加载指定的对话框配置内容。
是的,哪怕是在我们没有查看dialog组件具体源码的情况下,整个逻辑还是相对比较清晰的。我们不用理会dialog组件调用了什么模板,用了什么css样式,内部实现了哪些方法。
定义组件的一大目的就是降低代码之前的耦合性,作为组件,我只管定义如何实现一个组件;作为组件调用者,我只管衣来伸手饭来张口的拿来主义,
不管你内部是如何实现的。
接下来看webpack是如果对上面的代码进行打包的:
以下是webpack.config.js配置文件部分内容:
1 module.exports = {
2 entry: {
3 index:"./src/js/page/index.js",
4 delegate:"./src/js/page/jsEvent.js"
5 },
6 output: {
7 path: path.join(__dirname,'dist'),
8 publicPath: "/easySlide/dist/",
9 filename: "[name].js",
10 chunkFilename: "[id].chunk.js"
11 },
12 module: {
13 loaders: [ //加载器
14 {test: /\.css$/, loader: "style!css" },
15 {test: /\.html$/, loader: "html" },
16 {test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
17 ]
18 }
19
20 };
改动的地方不多,主要是以下几点:
第10行:定义了chunk的文件名命名规则,这里除了id以外,还可以使用[hash]
第8行:publicPath 这个配置很容易被疏忽。我们的chunk文件默认是跟bundle放在一块的,都是在dist目录下,如果不配置正确的publicPath的话,webpack请求chunk文件时将会默认请求根目录
第15行:新增了HTML加载器,主要是给dialog组件加载模板使用的
codeSplit作为webpack一个比较核心的功能,所以也需要额外的plugins插件配置就能支持。
在项目根目录下运行 webpack 打包命令以后可以看到dist目录下就会新增一个 2.chunk.js文件 (2是chunk的ID值)
值得一提的是,chunk文件完全由webpack进行管理和使用,我们无需额外的干预
4.dialog组件的实现
dialog的实现原理比较简单,我们定义了一个dialog容器,通过css控制其固定在整个页面之上,然后在生成一个mask阴影层。
具体的实现css样式大家也可以前往github查看源码。
dialog组件的实现方法也是与我们之前做的slideModule比较类似:
第10-11行:加载了dialog组件的HTML模板,并将其放置在body中。嗯,之所有是要使用html模板也是为了解耦合,方便对模板和JS进行单独维护。这里webpack在打包的时候
会自动将html模板压缩成字符串保存在chunk文件中。
第16-44行:定义了dialog组件的几个接口方法,其中openDialogWith 就是我们之前调用的根据配置内容更新dialog DOM信息,然后将dialog展示出来。
对于dialogConfig我们也简单的来看下:
这里全部都是对话框的数据配置项,单独维护的好处也是解耦合,以外咱们可以将这些数据配置在数据库中,通过接同样的接口格式返回来就行了。
其实我这里的组件定义还有一个问题:
我们是将自定义的对象直接作为组件导出,开放给调用者使用。这在操作上其实存在一定的风险性,因为所有接口方法和属性都是开放的,那就有可能被使用者
给篡改,影响到组件的正常使用。正确的做法是:
在组件内部定义一个私有变量,用户存放组件所有属性与方法,然后再将接口方法(一般不建议开放属性给调用者直接修改)导出给调用者使用。
webpack练手项目之easySlide(二):代码分割(转)的更多相关文章
-
webpack练手项目之easySlide(二):代码分割
Hello,大家好. 在上一篇 webpack练手项目之easySlide(一):初探webpack 中我们一起为大家介绍了webpack的基本用法,使用webpack对前端代码进行模块化打包. 但 ...
-
webpack练手项目之easySlide(三):commonChunks(转)
Hello,大家好. 在之前两篇文章中: webpack练手项目之easySlide(一):初探webpack webpack练手项目之easySlide(二):代码分割 与大家分享了webpack的 ...
-
webpack练手项目之easySlide(三):commonChunks
Hello,大家好. 在之前两篇文章中: webpack练手项目之easySlide(一):初探webpack webpack练手项目之easySlide(二):代码分割 与大家分享了webpack的 ...
-
webpack练手项目之easySlide(一):初探webpack (转)
最近在学习webpack,正好拿了之前做的一个小组件,图片轮播来做了下练手,让我们一起来初步感受下webpack的神奇魅力. webpack是一个前端的打包管理工具,大家可以前往:http:/ ...
-
webpack练手项目之easySlide(一):初探webpack
最近在学习webpack,正好拿了之前做的一个小组件,图片轮播来做了下练手,让我们一起来初步感受下webpack的神奇魅力. webpack是一个前端的打包管理工具,大家可以前往:http:/ ...
-
微信小程序初体验,入门练手项目--通讯录,部署上线(二)
接上一篇<微信小程序初体验,入门练手项目--通讯录,后台是阿里云服务器>:https://www.cnblogs.com/chengxs/p/9898670.html 开发微信小程序最尴尬 ...
-
Python之路【第二十四篇】:Python学习路径及练手项目合集
Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...
-
微信小程序初体验,入门练手项目--通讯录,后台是阿里云服务器(一)
内容: 一.前言 二.相关概念 三.开始工作 四.启动项目起来 五.项目结构 六.设计理念 七.路由 八.部署线上后端服务 同步交流学习社区: https://www.mwcxs.top/page/4 ...
-
80个Python练手项目列表
80个Python练手项目列表 我若将死,给孩子留遗言,只留一句话:Repetition is the mother of all learning重复是学习之母.他们将来长大,学知识,技巧.爱情 ...
随机推荐
-
Celery 框架学习笔记
在学习Celery之前,我先简单的去了解了一下什么是生产者消费者模式. 生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是 ...
-
localStorage、sessionStorage在无痕模式下被禁用
在移动web开发中,经常会使用到localStorage去缓存一些数据,一般情况下,我们只需要按照下面的代码去使用就不会有 问题. if(window.localStorage){ localStor ...
-
TCP协议三次握手过程分析【图解,简单清晰】
转自:http://www.cnblogs.com/rootq/articles/1377355.html TCP(Transmission Control Protocol) 传输控制协议 TCP是 ...
-
scu - 3254 - Rain and Fgj(最小点权割)
题意:N个点.M条边(2 <= N <= 1000 , 0 <= M <= 10^5),每一个点有个权值W(0 <= W <= 10^5),现要去除一些点(不能去掉 ...
-
【转】独立游戏如何对接STEAM SDK
独立开发者在对接STEAM SDK之前 首先得先登上青睐之光,也就是我们俗称的"绿光" 一般要先对接G胖家的SDK,然后提交版本,最后等待审核... 我本身是unity 开发,对C ...
-
Python-序列号和模块复习-64
# 序列化模块 # 数据类型转化成字符串的过程就是序列化 # 为了方便存储和网络传输 # json # dumps # loads # dump 和文件有关 # load load不能load多次 i ...
-
Qt 学习-----helloword
(参考:http://www.qter.org/portal.php?mod=view&aid=27&page=3) 1. 打开“文件→新建文件或项目”菜单项(也可以直接按下Ctrl+ ...
-
Nagios监控配置文件及监控流程
1.安装路径/usr/local/nagios/下存在etc.bin.sbin.share.var 这五个目录.Nagios 各个目录用途说明如下: bin Nagios 可执行程序所在目录 etc ...
-
python3.6使用f-string来格式化字符串
这里的f-string指的是以f或F修饰的字符串,在字符串中使用{}来替换变量,表达式和支持各种格式的输出.详细的格式化定义可以看官方文档 >>> a, b = 30, 20 > ...
-
ruby中的私有方法和保护方法
ruby中的私有方法是指方法只能被隐含调用,不能被显示调用.而当没有显示接收者的时候,会把self当成接收者.因此,只能在自身中调用私有方法,这也是私有方法的调用规则. ruby的私有方法机制目的是: ...