简单谈谈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 相关文章推荐
JavaScript使用prototype定义对象类型(转)[
Dec 22 Javascript
js处理自己不能定义二维数组的方法详解
Mar 03 Javascript
Javascript动态创建表格及删除行列的方法
May 15 Javascript
js+HTML5基于过滤器从摄像头中捕获视频的方法
Jun 16 Javascript
jQuery获得字体颜色16位码的方法
Feb 20 Javascript
微信小程序数据存储与取值详解
Jan 30 Javascript
通过jquery获取上传文件名称、类型和大小的实现代码
Apr 19 jQuery
JavaScript基础教程之如何实现一个简单的promise
Sep 11 Javascript
jQuery pjax 应用简单示例
Sep 20 jQuery
Vue 自定义指令实现一键 Copy功能
Sep 16 Javascript
node.js开发辅助工具nodemon安装与配置详解
Feb 06 Javascript
如何在vue 中使用柱状图 并自修改配置
Jan 21 Vue.js
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
php获取当月最后一天函数分享
2015/02/02 PHP
php htmlentities()函数的定义和用法
2016/05/13 PHP
CodeIgniter 完美解决URL含有中文字符串
2016/05/13 PHP
php 输出json及显示json中的中文汉字详解及实例
2016/11/09 PHP
通过DOM脚本去设置样式信息
2010/09/19 Javascript
javascript简单性能问题及学习笔记
2014/02/04 Javascript
ajax提交表单实现网页无刷新注册示例
2014/05/08 Javascript
JavaScript实现的使用键盘控制人物走动实例
2014/08/27 Javascript
javascript实现类似于新浪微博搜索框弹出效果的方法
2015/07/27 Javascript
js表单中选择框值的获取及表单的序列化
2015/12/17 Javascript
简单总结JavaScript中的String字符串类型
2016/05/26 Javascript
原生js实现省市区三级联动代码分享
2018/02/12 Javascript
图文介绍Vue父组件向子组件传值
2018/02/17 Javascript
微信小程序通过保存图片分享到朋友圈功能
2018/05/24 Javascript
vue 音乐App QQ音乐搜索列表最新接口跨域设置方法
2018/09/25 Javascript
微信小程序实现的动态设置导航栏标题功能示例
2019/01/31 Javascript
微信小程序的授权实现过程解析
2019/08/02 Javascript
layui实现数据表格自定义数据项
2019/10/26 Javascript
Vue.js页面中有多个input搜索框如何实现防抖操作
2019/11/04 Javascript
JS如何在不同平台实现多语言方式
2020/07/16 Javascript
[41:54]2018DOTA2亚洲邀请赛 4.1 小组赛A组加赛 TNC vs Liquid
2018/04/03 DOTA
Python人脸识别初探
2017/12/21 Python
Python语言描述随机梯度下降法
2018/01/04 Python
Python实现的字典值比较功能示例
2018/01/08 Python
python实现简易通讯录修改版
2018/03/13 Python
python 列表,数组,矩阵两两转换tolist()的实例
2018/04/04 Python
基于Python 装饰器装饰类中的方法实例
2018/04/21 Python
pandas通过loc生成新的列方法
2018/11/28 Python
Jupyter Notebook 文件默认目录的查看以及更改步骤
2020/04/14 Python
Python 字节流,字符串,十六进制相互转换实例(binascii,bytes)
2020/05/11 Python
HTML5 canvas 瀑布流文字效果的示例代码
2018/01/31 HTML / CSS
武汉某公司的C#笔试题面试题
2015/12/25 面试题
黄继光的英雄事迹材料
2014/02/13 职场文书
2014年女职工工作总结
2014/11/27 职场文书
2016庆祝国庆67周年宣传语
2015/11/25 职场文书
幼儿园教学反思范文
2016/03/02 职场文书