webpack 利用Code Splitting 分批打包、按需下载
webpack中的解决方案——Code Splitting,简单来说就是按需加载(下载),如果是requireJS对应的AMD的方案中这本是在正常不过了。但是在webpack中All in one的思想就会显得很怪,但webpack并不死板(就像某著名AMD和CMD模块管理器中都有对方阵营的实现方案)。我查阅了不少的文档和论坛,终于找到了webpack中对于按需下载的支持方案(此处想吐槽webpack官方文档),好多的论坛文章都提到了使用require.ensure 但是却写得很简略,直接使用发现行不通、感觉少了点啥,比如下面的写法:
1 require.ensure(['需要动态加载的module'], function(require) {
2 require('需要动态加载的module');
3 });
4 //webpack会自动产生动态加载代码,结果和ensure产生的是一样的
我这里就详细整理一下,这种用法到底怎么用。对应的配置、发布流程是什么样的。
webpack的整体风格是All in one 就是将从入口文件开始的所有引用到的模块都打包到一个js文件(包括css 、图片,这里只说js)。在打包的过程中会有一系列的名称替换,细心的朋友会发现我们的模块被命名为更加简单,节省空间的数字了。不同于requireJS可以直接require线上文件的方式。webpack推荐将所有可能用到的文件(模块)都打包。但是这样做仅适合使用率较高的小体积模块。对于体积大有不常用的模块,反而显得不适合。如果你尝试过在webpack工程中直接require线上url。运行的时候会抛出一个异常——不能找到模块,那是因为对于打包后的js中默认是在这个包内查找模块,或者说webpack工程中的require函数默认是在包(文件)内找,压根儿就没打算发起http请求。所以就不要想直接require线上的url了。
拿到webpack工程就只能打包在一起,搞出一个超大的文件,把页面卡住?webpack官方给出了解决方案——Code Splitting。这种方式并不代表webpack有意投靠AMD,而是另辟蹊径弥补了自身的短板。简单来说,还是All in one 还是打包成一个包,还是在包内部找模块,只是这一个包不一定只有一个文件。我们直译Code Splitting为“代码拆分”,也就是说我们可以理解为将all in one的包在拆成多个包,当需要引用的时候再引用下载、加载,只是这种加载是通过webpack内部机制发起http请求实现的。我们将摸个不常用的大体积模块从包中分离出来,当包内的语句引用到了这个模块后,webpack会判断这个模块是被分离出去的,应当发起http请求拉取。不是不能拉向上模块,只是只拉和自己有渊源的模块。
那么webpack怎么知道这个模块被分离了?这就降到了上面提到的 require.ensure ,通过不同的API就相当于一种标记,在打包时分出去、引用时发请求动态加载。其实大家最关心的是怎么用?举个例子:我要引用A、B、C、D 四个插件,A、C可能往往一起用,B、D可能往往一起用。我就需要在webpack打包后生成3个文件:包含主文件的js(大量常用模块)、包含A和C的分离包、包含B和D的分离包。

1 /*别的事XXXX*/
2 if(bIsAC === true ){
3 require.ensure(["A","C"], function(require){
4 var A = require('A');
5 var C = require("C");
6 var ac = A+C;
7 /*一大堆业务逻辑*/
8 });
9
10 }else{
11 require.ensure(["B","D"], function(require){
12 var B = require('B');
13 var D = require("D");
14 var bd = B+D;
15 /*一大堆业务逻辑*/
16 });
17 }
18 /*别的事XXXX*/

这时候编译webpack,会生成3个文件。如果你在webpack.config.js文件中定义输出是bundle.js,同时还会生成两个文件1.bundle.js和2.bundle.js,把他俩放在我们实验的页面的同一级目录下载会发现页面先加载bundle.js。然后根据条件加载1.bundle.js或2.bundle.js。为了更直观的看到现象我去掉了if判断加载3个文件(如图)。
问题来了:两个分离的模块文件一定要放在页面同一级吗?当然是可以自定义的。有一个细节,我们并没有设定过引用1.bundle.js和2.bundle.js的线上url的语句,看来它必然是有默认设置的。如果对webpack有了解的朋友一定会想到webpack.config.js文件。如图就是两个分离文件的根路径:

它会直接影响编译后的 __webpack_require__.p = "http://yoururl.com/";进而影响下面的路径:

这样页面发出的请求就是在__webpack_require__.p = "http://yoururl.com/" 指定下的静态服务器的路径。
需要注意的是与AMD不同的是AMD中封装到其他文件的部分模块可以直接被其他的AMD工程加载,如果是三方的库更可以作为cdn直接被其他页面引用。但是webpack打包分离的文件与主文件有着密切的联系,尽可以被当前主文件使用,每次打包生成两个文件,建议同步更新上线。
这样就利用Code Splitting实现了webpack的分批打包、按需下载
webpack 利用Code Splitting 分批打包、按需下载的更多相关文章
- webpack 和 code splitting
Code Splitting指的是代码分割,那么什么是代码分割,webpack和code splitting又有什么样的联系呢? 使用npm run dev:"webpack-dev-ser ...
- Webpack之Code Splitting 代码分块
如何实现代码分块 默认情况webpack会将资源文件打包成一个js文件,比如app.bundle.js 实际情况我们需要按需加载 方法如下: require.ensure(dependencies, ...
- webpack Code Splitting浅析
Code Splitting是webpack的一个重要特性,他允许你将代码打包生成多个bundle.对多页应用来说,它是必须的,因为必须要配置多个入口生成多个bundle:对于单页应用来说,如果只打包 ...
- [转] react-router4 + webpack Code Splitting
项目升级为react-router4后,就尝试着根据官方文档进行代码分割.https://reacttraining.com/react-router/web/guides/code-splittin ...
- react-router4 + webpack Code Splitting
项目升级为react-router4后,就尝试着根据官方文档进行代码分割.https://reacttraining.com/react-router/web/guides/code-splittin ...
- webpack优化之code splitting
作为当前风头正盛的打包工具,webpack风靡前端界.确实作为引领了一个时代的打包工具,很多方面都带来了颠覆性的改进,让我们更加的感受到自动化的快感.不过最为大家诟病的一点就是用起来太难了. 要想愉快 ...
- webpack async load modules & dynamic code splitting
webpack async load modules & dynamic code splitting webpack 按需/异步加载/Code Splitting webpack loade ...
- [Webpack 2] Maintain sane file sizes with webpack code splitting
As a Single Page Application grows in size, the size of the payload can become a real problem for pe ...
- 借助Code Splitting 提升单页面应用性能
近日的工作集中于一个单页面应用(Single-page application),在项目中尝试了闻名已久的Code splitting,收获极大,特此分享. Why we need code spli ...
随机推荐
- 能说明你的Javascript技术很烂的五个原因
Javascript在互联网上名声很臭,但你又很难再找到一个像它这样如此动态.如此被广泛使用.如此根植于我们的生活中的另外一种语言.它的低学习门槛让很多人都称它为学前脚本语言,它另外一个让人嘲笑的东西 ...
- 带"叉叉"的GridView
由于需要用到“删除图片”的功能,需要写这样一个小demo: 对之前博文的修改 发现imageView监听点击事件 效果实在不敢恭维,因此换个方式:设置Touch的监听函数, 下面的Demo没有改过来哈 ...
- glassfish--服务搭建
集群配置: 1. DAS节点执行: 1)./asadmin start-domain domain1 2)./asadmin change-admin-password 3)./asadmin ena ...
- 第一节,学习cocos2d-x的前期准备
1,我用的mac系统,在mac系统上装上cocos2d-x的模板 2,用doxygen工具装上API,这个非常重要,没有API的开发不叫开发,因此我们要习惯看API 3,知道怎么查看cocos2d-x ...
- asp.net 使用JS获得串口数据
使用JS获得串口数据 JavaScript语言通常是一种网页编程语言,比较适合前台的一些应用设计.对于本地设备和数据的操作有比较大的限制.由于项目的需要,我需要获得本机的串口数据并显示在web端.我们 ...
- Android 笔记-Fragment 与 Activity之间传递数据
Fragment 与 Activity之间传递数据有两种方法.一种是使用setArgument,一种是使用接口回调.以下先学习第一种方法. (1)使用setArgument方法: 为了便于理解,我在这 ...
- 【教程】HTML5+JavaScript编写flappy bird
作者: 风小锐 新浪微博ID:永远de风小锐 QQ:547953539 转载请注明出处 PS:新修复了两个bug,已下载代码的同学请查看一下 大学立即要毕业了. ...
- h5 微场景
兔展: http://www.rabbitpre.com/ 易企秀: http://www.eqxiu.com/site/show 云来: http://www.liveapp.cn/
- Java的代理模式(通过公共接口实现)
代理模式的一种常见的实现方案是,定义一个接口或抽象类,并派生出目标子类,和代理子类.我们要操作的是目标子类里的方法,而很多时候,我们需要为目录子类中的方法增加额外的处理,如果增加日志功能.条件判断等, ...
- mariadb多实例搭建
测试环境基于centos7.2,腾讯云实验室,学习搭建! https://www.qcloud.com/developer 多实例mysql,能更加理解mysql安装的基本过程!及简单使用... ma ...