webpack中的Code Splitting以及配置参数

代码分割 Code Splitting

在最开始的时候,webpack都是将全部的代码打包到一个文件中,可是当项目过大的时候,页面所须要加载的时间就会变长,这个时候咱们就须要Code Splitting对文件进行分块,实现代码的按需加载。node

接下来咱们来看看下面两种方式:webpack

当用第一种方式的时候, 咱们须要等打包文件加载完成以后,才会去实现文件里面的逻辑,再将页面展现出来。那么这样带来的问题是什么呢,有一个问题想必你们都很清楚,那就是打包文件很大,加载时间很长web

那还有一个问题是什么呢,咱们都知道,lodash是一个第三方库,咱们不会随便去修改它,可是业务逻辑是常常会被改变的。假设咱们修改了业务代码,那咱们就须要从新去加载打包中的js文件,才能获取到最新的代码,显示最新的内容。由于业务代码和第三方库都在同一个文件中,因此lodash相应的也要被从新加载。缓存

index.jsapp

// 同步逻辑
// 第一种方式
// 首次访问页面的时候, 加载main.js 2mb
// 当业务逻辑发生变化时 又要加载main.js 2mb的内容
import _ from 'lodash' //假设1mb
// 业务逻辑 1mb
console.log(_.join(['a','d','c'], "***"));
// 中间省略几千行代码....
console.log(_.join(['a','b','c'], "***"));
复制代码

第二种方式咱们将上面代码拆分红了两个文件main.jslodash.js,咱们将不须要修改的第三方库拎出来放在一个单独的文件中,当页面业务逻辑发生变化的时候,只须要加载main.js页面就能够了。异步

这种动态加载的方式就能提高咱们页面展现的速度,相应的也提升了性能。async

index.js性能

// 第二种方式
// main.js被拆成lodash.js(1Mb), main.js(1mb)
// 当业务逻辑发生变化时,只要加载main.js便可(1MB)
// 业务逻辑 1mb
console.log(_.join(['a','d','c'], "***"));
console.log(_.join(['a','b','c'], "***"));
复制代码

lodash.js学习

// 加载了lodash,而后将lodash挂载到了全局上面
import _ from 'lodash'; //1mb

window._ = _
复制代码

webpack插件帮助代码自动拆分

Code Splitting其实本质上是和webpack没有任何关系的,但为何只要一说到webpack,咱们在不少时候都能听到webpack里面有Code Splitting呢?这是由于webpack里面有一些插件能够很是容易的帮助咱们实现Code Splittingui

在webpack4里面有一个插件splitChunksPlugin,这个插件直接与webpack作了捆绑,不须要安装,直接就能够拿来用了。这样的话咱们进行代码分割就很是容易了。

同步代码分割

咱们先将以前的lodash.jsindex.js合并,而后咱们在webpack.config.js里面配置一个optimization

optimization: {
    splitChunks: {
      chunks: 'all'
    }
}
复制代码

咱们从新对代码进行打包,查看dist目录:

咱们能看见,只要作一个很是简单的配置,就能实现代码分割,彻底不须要咱们再手动进行文件的拆分。

异步代码的分割

上面咱们说的是同步加载。那么接下来咱们看看异步加载吧!

// 异步加载lodash
function getComponent() {
  return import('lodash').then(({default: _}) => {
    const element =  document.createElement('div')
    element.innerHTML = _.join(["linna", "mao"], '-')
  })
}

getComponent().then(element => {
  document.body.appendChild(element)
})
复制代码

若是你们实践过的话,就知道即使咱们不在webpack.config.js中配置optimization,异步载入的组件也会自动打包再一个单独的文件中。

SplitChunksPlugin配置详解

从上图中咱们能够看到,异步代码分割中,dist目录中打包生成的文件是一个0.js这个0是Code Splitting产生的一个id的值

若是咱们想要将它改为咱们能够识别的名字,咱们就能够在上面异步代码的第一个参数前面添加/*webpackChunkName:"lodash"*/,这个是在异步加载组件中存在的一个magic comment(语法注释)。

magic comment只能在官方动态加载组件的插件使用

//详细代码看异步代码中的index.js
return import(/*webpackChunkName:"lodash"*/'lodash').then(({default: _})
复制代码

打包后咱们能够看到vendors~lodash.js,那么为何会在lodash前面添加vendors呢?这里咱们就须要去看咱们的配置了,官方文件中在optimization中会有一个默认配置

splitChunks: {
    chunks: "async",
    minSize: 30000,
    minChunks: 1,
    maxAsyncRequests: 5,
    maxInitialRequests: 3,
    automaticNameDelimiter: '~',
    name: true,
    cacheGroups: {
        vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10
        },
    default: {
            priority: -20,
            reuseExistingChunk: true
        }
    }
}
复制代码

其中:

更多详解参考官网split-chunks-plugin

  • chunks:默认配置aysnc的意思是对异步代码进行分割,这就是为何在以前代码中异步代码分割不须要进行配置的缘由。
  • minSize:引入的模块的大小大于30000才能进行代码分割。
  • minChunks:当模块被引用了至少1次的时候进行代码分割。
  • maxAsyncRequests:同时加载的模块数最可能是5个。若是加载模块超出了五个,那就加载前五个,后面的就不会再进行代码分割了。
  • maxInitialRequests:入口文件引入的库最多能分割成3个代码文件。
  • automaticNameDelimiter:文件生成时候,组和文件名之间的链接,就像以前咱们说到的vendors~lodash.js
  • name: 默认为true,打包生成的文件,取名的时候让cacheGroup里的名字有效。
  • cacheGroup: 至关一个缓存组。
    • 当引入的模块在node_modules中的时候,符合vendors,就会在分割文件中添加前缀vendors,当有多个node_modules模块时候,就会将全部引用模块先进行缓存,最后的时候一块儿打包成vendors文件。
    • index.js引入一个本身写的js文件,它就找到cacheGroup,不符合vendors的时候,就会进入default中,这个时候打包文件的前缀就会有default
    • priority: default中全部的模块都是符合的,当一个模块既符合vendors又符合default的时候,那么priority的值越大,优先级越高。
    • reuseExistingChunk: 若是一个模块已经被打包过,再打包的时候就会忽略这个模块,直接使用以前被打包过的模块。

注:此文为本人学习过程当中的笔记记录,若是有错误或者不许确的地方请大佬多多指教~

相关文章
相关标签/搜索