简单谈谈CommonsChunkPlugin抽取公共模块


Posted in Javascript onDecember 31, 2017

引言

webpack插件CommonsChunkPlugin的主要作用是抽取webpack项目入口chunk的公共部分,具体的用法就不做过多介绍,不太了解可以参考webpack官网介绍;

该插件是webpack项目常用的一个优化功能,几乎在每个webpack项目中都会用到。使用该插件带来的好处:

提升webpack打包速度和项目体积:将webpack入口的chunk文件中所有公共的代码提取出来,减少代码体积;同时提升webpack打包速度。

利用缓存机制:依赖的公共模块文件一般很少更改或者不会更改,这样独立模块文件提取出可以长期缓存。

但是在项目中,若插件打开方式不正确的话,上面的第二点其实是无法实现,因为这种情况下:

没有被修改过的公有代码或库代码打包出的Entry Chunk,会随着其他业务代码的变化而变化,导致页面上的长缓存机制失效。

那么,下面就来开启CommonsChunkPlugin正确的打开方式。

CommonsChunkPlugin不正确用法

假如将我们项目的公共库如react、react-dom、react-router与业务代码隔离,将其提取为vendor chunk,webpack配置如下:

const webpack = require("webpack");
const path = require('path');
module.exports = {
 entry: {
 app: "./app.js",
 vendor: ["react","react-dom", "redux", "react-redux", "react-router-redux"]
 },
 output: {
 path: path.resolve(__dirname, 'output'),
 filename: "[name].[chunkhash].js"
 },
 plugins: [
 new webpack.optimize.CommonsChunkPlugin({names: ["vendor"]})
 ]
};

上面将项目一些基础库打包成一个名为vendor的chunk中,并将业务相关的代码打包到一个名为app的chunk中;

webpack打包编译后的结果如下:

简单谈谈CommonsChunkPlugin抽取公共模块

我们对其中的业务代码app.js进行修改后,重新编译结果如下:

简单谈谈CommonsChunkPlugin抽取公共模块

可以发现,在CommonsChunkPlugin这种配置下,当业务代码app发生变化,而库代码也跟着变化,vender的chunkhash也跟着变化,这样vendor的引用的名称跟着变化,导致浏览器端的长缓存机制失效。

引起问题的原因

引起webpack每次打包编译时vendor跟着变化的原因:

webpack每次build的时候都会生成一些运行时代码。当只有一个文件时,运行时代码直接塞到这个文件中。当有多个文件时,运行时代码会被提取到公共文件中,也就是上面CommonsChunkPlugin配置的vendor chunk中。

webpack每次编译时产生的运行时代码,包括全局webpackJsonp方法的定义和维护模块依赖关系,具体可以参考这里的commons.js。

所以,上面webpack的CommonsChunkPlugin配置中,每次编译时这些代码都会打包到vendor中,导致每次vendor的chunkhash每次都会变化。

那么,我们可以在对vendor chunk进行配置,抽取其中的公共代码,即webpack运行时代码,这样就可以将项目依赖的基础库模块与业务模块隔离开来,因为不会对这些文件进行修改,所以这些文件可达到长缓存的作用。具体配置如下:

module.exports = {
 entry: {
 app: "./app.js",
 vendor: ["react","react-dom", "redux", "react-redux", "react-router-redux"]
 },
 ....
 plugins: [
 new webpack.optimize.CommonsChunkPlugin({names: ["vendor"]}),
 new webpack.optimize.CommonsChunkPlugin({
 name: 'manifest',
 chunks: ['vendor']
 })
 ]
};

这样,即使修改业务app代码,项目依赖的基础库vendor chunk也不会发生变化;只是抽取的manifest chunk每次还会变化,但是这个文件体积非常小,相比vendor来说这种方式的收益更大。如下图:

简单谈谈CommonsChunkPlugin抽取公共模块

修改app代码后的打包编译结果如下,可以看到vendor的chunkhash没有变化

简单谈谈CommonsChunkPlugin抽取公共模块

在webpack中配置CommonsChunkPlugin时需要注意一点:

配置webpack的output项时,其filename和chunkFilename必须使用chunkhash。不要使用hash,否则即使按照上面的配置也不能达到预期的效果。至于hash与chunkhash的区别,可参考github的回答

以上这篇简单谈谈CommonsChunkPlugin抽取公共模块就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
层序遍历在ExtJs的TreePanel中的应用
Oct 16 Javascript
B/S模式项目中常用的javascript汇总
Dec 17 Javascript
jquery如何判断表格同一列不同行input数据是否重复
May 14 Javascript
javascript正则表达式基础知识入门
Apr 20 Javascript
js实现模拟计算器退格键删除文字效果的方法
May 07 Javascript
js实现仿京东2级菜单效果(带延时功能)
Aug 27 Javascript
探讨AngularJs中ui.route的简单应用
Nov 16 Javascript
React-Native 组件之 Modal的使用详解
Aug 08 Javascript
利用JS判断客户端类型你应该知道的四种方法
Dec 22 Javascript
js实现同一个页面,多个enter事件绑定的示例
Oct 10 Javascript
jQuery模拟html下拉多选框的原生实现方法示例
May 30 jQuery
Vue 实现从小到大的横向滑动效果详解
Oct 16 Javascript
AngularJS基于MVC的复杂操作实例讲解
Dec 31 #Javascript
jQuery实现页码跳转式动态数据分页
Dec 31 #jQuery
React数据传递之组件内部通信的方法
Dec 31 #Javascript
javascript 通过键名获取键盘的keyCode方法
Dec 31 #Javascript
vue vuex vue-rouert后台项目——权限路由(适合初学)
Dec 29 #Javascript
Angular实现的内置过滤器orderBy排序与模糊查询功能示例
Dec 29 #Javascript
Angular实现的敏感文字自动过滤与提示功能示例
Dec 29 #Javascript
You might like
150kHz到30Mhz完全冲浪手册
2020/03/20 无线电
php escape URL编码
2008/12/10 PHP
PHP 全角转半角实现代码
2010/05/16 PHP
PHP mb_convert_encoding文字编码的转换函数介绍
2011/11/10 PHP
ThinkPHP的Widget扩展实例
2014/06/19 PHP
PHP永久登录、记住我功能实现方法和安全做法
2015/04/27 PHP
详解PHP的Yii框架中的Controller控制器
2016/03/29 PHP
PHP通过引用传递参数用法分析
2016/12/01 PHP
php curl获取到json对象并转成数组array的方法
2018/05/31 PHP
类似php的js数组的in_array函数自定义方法
2013/12/27 Javascript
Js判断CSS文件加载完毕的具体实现
2014/01/17 Javascript
JavaScript fontsize方法入门实例(按照指定的尺寸来显示字符串)
2014/10/17 Javascript
js获取字符串字节数方法小结
2015/06/09 Javascript
JavaScript中有关一个数组中最大值和最小值及它们的下表的输出的解决办法
2016/07/01 Javascript
Vue.js每天必学之组件与组件间的通信
2016/09/08 Javascript
Bootstarp 基础教程之表单部分实例代码
2017/02/03 Javascript
微信小程序 密码输入(源码下载)
2017/06/27 Javascript
使用webpack3.0配置webpack-dev-server教程
2018/05/29 Javascript
vue路由跳转传递参数的方式总结
2020/05/10 Javascript
js实现星星海特效的示例
2020/09/28 Javascript
[00:31]2016完美“圣”典风云人物:国士无双宣传片
2016/12/04 DOTA
在Python的Django框架中用流响应生成CSV文件的教程
2015/05/02 Python
numpy中矩阵合并的实例
2018/06/15 Python
使用selenium和pyquery爬取京东商品列表过程解析
2019/08/15 Python
业务代表的岗位职责
2013/11/16 职场文书
寒假实习自荐信
2014/01/26 职场文书
大学生村官演讲稿
2014/04/25 职场文书
市场调查策划方案
2014/06/10 职场文书
2014年最新个人对照检查材料范文
2014/09/25 职场文书
五好文明家庭事迹材料
2014/12/20 职场文书
红色经典观后感
2015/06/18 职场文书
酒店厨房管理制度
2015/08/06 职场文书
MyBatis 动态SQL全面详解
2021/10/05 MySQL
SQL实战演练之网上商城数据库商品类别数据操作
2021/10/24 MySQL
python解析json数据
2022/04/29 Python
java实现自定义时钟并实现走时功能
2022/06/21 Java/Android