Webpack 提取公共代 CommonsChunkPlugin

背景 

若是不提取公共部分会有什么后果? react

  1. 相同资源重复加载引用,浪费用户流量以及服务器成本;webpack

  2. 每一个页面须要加载的资源太多,致使网页首页加载缓慢; web

提取以后有什么优势? 浏览器

  1. 相同资源只打包加载一次,减小网络传输流量,下降服务器压力; 缓存

  2. 页面加载速度加快,提交用户体验; bash

具体用法 

思路 

  1. 根据项目使用的技术栈,把全部页面都要使用到的基础库提取出来,造成一个`base.js`,这个文件包含技术栈运行所须要的全部基础环境依赖;(只要技术栈不变,基本能够持久缓存) 服务器

  2. 剔除全部公共基础依赖代码以后,再从全部页面中把都依赖的公共代码提取出来,造成一个`common.js`; 网络

  3. 再为每一个页面生成一个独立的文件,那这些文件就再也不包含`base.js`、`common.js`的代码,只包含各个页面独立的业务代码; async


定义与概念 

CommonsChunkPlugin用于提取公共代码,根据配置,把基础库以及业务逻辑公共代码抽离提取出来,减小资源重复引用; 
ui

CommonsChunkPlugin 对单入口文件不能提取公共的代码,只能提取 webpack runtime的环境代码;提取的对象是

配置参数

name: ''复制代码

提取公共代码的文件名

names: string[]复制代码

names中配置的是入口名,不是路径,若是这里配置的名字与 入口chunk(输出文件名,在entry中设置或在动态输出)中的对应起来,则直接提取,若是没有在entry中同名,则建立一个包含webpack运行环境的环境代码,并做为抽离内容,把运行环境从提取入口中抽离出来;

chunks: string[]复制代码

chunks 配置的是提取公共代码的源,即须要在哪些入口中提取公共的代码;个人理解是这里若是自由配置的话,应该是要在入口chunk那里选择须要提取的入口(这个不知道对不对,由于我若是直接引用文件路径的话,效果没看到)

若是不设置这个值,全部入口chunk,都会做为提取的对象

filename: string复制代码

common chunk 文件名模版,若是不设置,则不修改原来的文件名(也不会修改在name/names中配置的名字,可是若是配置了,优先使用)

minChunks: number | Infinity | function(module, count) => boolean复制代码

number  一个模块被提取以前,必需要在 入口chunks中出现的至少次数;

Infinity  默认是对全部chunk进行提取;

function(module, count) => boolean  自定义提取的规则

minChunks取值需大于2,小于chunks的长度(即chunks配置项的长度或全部入口的长度)

minSize: number复制代码

在公共模块建立以前,全部 公共模块的最小大小

children: boolean复制代码

若是设置为 true,全部 公共chunk 的子模块都会被选择;通常不设置这个值,毕竟咱们值为了对公共代码的抽离,而不是想要所有抽离;不过这个也要针对不一样的项目来处理,毕竟配置这个东西也是很自由的;

async:boolean|string复制代码

这个暂时没有研究出来是什么.....

具体配置

这个的配置一点也不复杂,主要是要根据实际状况进行配置比较复杂,状况通常分红下面几种

  1. 项目是单入口应用仍是多入口应用,这决定你是否合适使用CommonsChunkPlugin  

  2. 对哪些入口chunk进行提取,这决定了 nameschunkschildren配置项的设置

  3. 提取的粒度,这决定了minChunksminSize配置项的设置

基本上根据上面几条,而后配置entry以及plugin就OK了,抽取的思路文章开头也提到了,因此就不列举各类状况了

// 提取公共代码主要修改的范围以下,
// manifest 的提取是把webpack启动运行部分代码,把部分代码抽离出来,
// 那每次业务代码有修改时,并不会影响到这个文件的hash,那就能够持久化在浏览器,减小用户加载的流量
module.exports = {  
  entry: {    
    main: ['./src/index.js'],    
    vendor: ['react']  
  },  
  plugins: [    
    new webpack.optimize.CommonsChunkPlugin({      
      names:['vendor', 'manifest'],          
      children: false,     // 是否对全部源chunks的子模块都包含          
      minChunks: 2,        // 提取代码的粒度          
      // chunks: [],       // 须要提取公共代码的源chunks     
    }),  
  ]
}

复制代码
相关文章
相关标签/搜索