简单谈谈CommonsChunkPlugin抽取公共模块

 更新时间:2017年12月31日 10:04:21   作者:wonyun  
下面小编就为大家分享一篇简单谈谈CommonsChunkPlugin抽取公共模块,具有很的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

引言

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打包编译后的结果如下:

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

可以发现,在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来说这种方式的收益更大。如下图:

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

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

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

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

相关文章

  • 使用php的mail()函数实现发送邮件功能

    使用php的mail()函数实现发送邮件功能

    php中的mail()函数允许您从脚本中直接发送电子邮件,下面这篇文章主要给大家介绍了关于如何使用php的mail()函数实现发送邮件功能的相关资料,需要的朋友可以参考下
    2021-06-06
  • 原生js轮播特效

    原生js轮播特效

    这篇文章主要为大家详细介绍了原生js轮播特效,简单实用的代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • 原生Js页面滚动延迟加载图片实现原理及过程

    原生Js页面滚动延迟加载图片实现原理及过程

    页面滚动加载事件,获取元素在页面里的top值根据滚动条的位置判断何时显示图片;获取元素集合 加载过的图片从集合里删除,具体实现如下,感兴趣的朋友各位可以参考下哈
    2013-06-06
  • 浅谈JavaScript的innerWidth与innerHeight

    浅谈JavaScript的innerWidth与innerHeight

    下面小编就为大家带来一篇浅谈JavaScript的innerWidth与innerHeight。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • js 数组随机字符串(广告不重复)

    js 数组随机字符串(广告不重复)

    今天一个网友想让他的广告随机显示,每次刷新广告的内容都不一样,经过参考源码网站分析就是通过下面代码实现,特分享下方便需要的朋友
    2013-08-08
  • 浅析js中事件冒泡与事件捕获

    浅析js中事件冒泡与事件捕获

    js中事件冒泡、事件捕获一直都是困扰大家的问题,本文利用大量代码解释了js中事件冒泡与事件捕获,希望对小伙伴们有所帮助
    2021-08-08
  • 如何使用JS获取当前节点的兄弟/父/子节点

    如何使用JS获取当前节点的兄弟/父/子节点

    在日常的网页开发中,我们会遇到获取节点的问题,而js是写网页的最基础的语言,也是最常用的,这篇文章主要给大家介绍了关于如何使用JS获取当前节点的兄弟/父/子节点的相关资料,需要的朋友可以参考下
    2023-04-04
  • js实现页面图片消除效果

    js实现页面图片消除效果

    这篇文章主要为大家详细介绍了js实现页面图片消除效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • js propertychange和oninput事件

    js propertychange和oninput事件

    项目中常遇到输入框检查的需求,比如即时搜索,用change事件?change事件失去焦点才发生,无法做到即时。keypresss事件?能监听到键盘,但监听不到鼠标复制粘贴,不完美
    2014-09-09
  • 浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结

    浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结

    下面小编就为大家分享一篇浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结。小编觉得写的非常不错,需要的朋友可以过来参考一下
    2016-03-03

最新评论