美文网首页
webpack代码分割之SplitChunksPlugin和魔法

webpack代码分割之SplitChunksPlugin和魔法

作者: 喜剧之王爱创作 | 来源:发表于2020-08-21 14:34 被阅读0次
    webpack.jpg

    写在前面

    我们在上篇的文章中,介绍了Code Splitting,其中有通过SplitChunksPlugin加同步引入的方式进行代码分割,和通过异步加载的方式让webpack自动帮我们完成代码分割,上篇中,我们也是主要对代码分割的概念和方式做了介绍和操作,其中提到的SplitChunksPlugin和异步加载只是简单使用了一下,这篇我们将详细学习SplitChunksPlugin的参数配置和异步加载。

    异步加载中的魔法注释

    我们再来看这段代码

    function getComponent () {
        return import('lodash').then(({ default: _ }) => {
            var element = document.createElement('div')
            element.innerHTML = _.join(['a', 'b', 'c'])
            return element
        })
    }
    
    getComponent().then(element => {
        document.body.appendChild(element)
    })
    

    其中lodash是一种通过异步引入的,那么webapck在打包的时候就会自动帮我们把代码做分割,我们知道现在lodash会生成一个0.js的文件,其实这是一个ID,那我们想把这个名字换成一个相应的英文名字,那该怎么做呢?这就是魔法注释。我们将动态引入改成下面这样

    import(/* webpackChunkName:"lodash" */'lodash')
    

    代表我们将异步引入的文件,打包后生成名为“lodash”的文件
    再打包试一下,这时候会发现目录变成了这样

    |--dist
      |--index.html
      |--main.js
      |--vendors~lodash.js
    

    (对于一些webapck 低版本v4可能达到预期,这时候,你需要装一个官方的babel插件,让异步加载来支持这种魔法注释(@babel/plugin-syntax-dynamic-import))
    这时候有人就会疑问了“我们明明给他的文件明明是“lodash”为什么打包出来的文件前面加入了一个‘vendors~呢?’”加下来大家就和我一起学习插件SplitChunksPlugin

    SplitChunksPlugin

    在上篇中,我们曾简单用了它一下,体验了一下code splitting,但其实他的配置内容有很多,这里我将对这个插件做详细的配置讲解,这是官网对他的介绍,同学们也可以参考官网SplitChunksPlugin
    我们将webpack.common.js中的optimization项先改成下面这样,这次再对刚才的项目做打包看一下。

    optimization: {
      splitChunks: {
        chunks: 'all',
          cacheGroups: {
            vendors: false,
            default: false
            }
        }
    },
    

    我们发现打包文件中vendors~lodash.js变成了lodash。这说明
    SplitChunksPlugin插件对于异步加载的模块也是有影响的,无论是我们做同步的代码分割还是异步的代码分割,我们都需要用到这个插件!!
    下面就是每一个参数的详解,看官网,这个插件是有一个默认配置如下

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

    我们将vendors和default都置为false,以免对其他配置项进行影响。

    chunks:initialasyncall

    chunks有三个值,意思是我们对哪种代码做分割,有异步,有同步,有所有类型,上面的默认配置中他的值是async,意思是这个插件只对异步加载的模块生效,下面我们将index.js中的模块改成同步引入

    import _ from 'lodash'
    var element = document.createElement('div')
    element.innerHTML = _.join(['a', 'b', 'c'])
    document.body.appendChild(element)
    

    打包一下,大家可以看到,对于同步的模块引入是没有进行代码分割的,下面我们将chunks的值改为all,再打包一下,发现还是没有生效哈,这是因为,当我们将chunks的值设为all的时候,webpack会知道我们将对同步引入的模块进行打包,但业务代码中各种逻辑的引入其实一般都是同步引入的方式,这样就会给分割带来困难,于是他会跳转到cacheGroups中查看相关配置,那现在我们先将cacheGroups.vendors改为官网默认的

    vendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10
    },
    

    这时候再打包,发现打包目录变成了下面这样

    |--dist
      |--index.html
      |--main.js
      |--vendors~main.js
    

    意思是我们代码分割成功了,看vendors.main.js中,也是对lodash库的引用。vendors~main.js前面的vendors代表,我们的lodash符合vendors组的要求,所以前缀就变成了这个组的名字,其中的main代表这个库的引入是入口是main.js,也就是其对应的index.js。

    cacheGroups.vendors

    有时候我们希望我们将所有的类库都打包到一个'vendors.js'的文件中,这时候,我们就可以在vendors.filename中配置

    vendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10,
        filename: 'vendors.js'
    },
    

    这时候打包看一下。文档目录变成了这样

    |--dist
      |--index.html
      |--main.js
      |--vendors.js
    

    这样配置的意思是,一旦我们对同步代码做风格,他就会到cacheGroups里面找匹配,一旦匹配了相应的组,就会按照这个组的一些配置做相应的分割,他和chunks是配合使用的

    minSize

    当引入的库大于该值时才做代码分割,小于的话就不做大吗风格了,大家可以在这里把minSize设的特别大来验证一下

    cacheGroups.default

    这里我们新建一个test.js导出一个特别简单的内容,并将minSize改为0,来打包测试一下

    export default {
        name: 'hello webpack'
    }
    

    index.js

    import test from './test'
    console.log(test.name)
    

    现在的内容和你简单,按照上面minsize的配置,我们将其设为0,他是理应会执行代码分割的,但打包发现,他并没有按照预期去执行代码分割,这是因为webpack在打包时,因其满足minsize,又是代码,就会去执行cacheGroups中的代码,但他又不符合vendors组的规则(不是node_modules下的内容),所以就没有将其正常风格,这时候我们就需要用到cacheGroups.default,我们先将官网的默认配置拷贝过来,去掉cacheGroups.default.minChunks参数,执行打包,我们发现,打包目录变成了这样

    |--dist
      |--index.html
      |--main.js
      |--default~main.js
    

    其打包的命名规则和配置规则和cacheGroups.vendors相同。我们也可以给其设置一个filename。

    minChunks

    minChunks代表一个模块被应用了多少次的时候才进行代码分割。

    maxAsyncRequests

    代表同时加载的模块数最大值,这里的默认值是5,假如我们有10个模块文件被分割,这里会将前五个模块分割,其他的就不分割了,一般取默认配置

    maxInitialRequests

    代表整个网站首页加载的时候,入口文件最大的加载数,如果入口文件引入的模块数大于这个值,其他的将不会被做代码分割,一般取默认配置

    automaticNameDelimiter

    代表组和文件名之前的连接符

    name

    设置为true代表我们在组中设置的文件名有效,一般不改默认配置

    cacheGroups.*.priority

    代表组的权重,有的模块会同事满足多个组的规则,比如我们现在的lodash就同时满足vendorsdefault两个组的要求,这时候就需要一个权重值来让模块优先执行哪个组的打包。

    cacheGroups.**.reuseExistingChunk

    默认为true,遇到多个模块相互引用的时候,当一个模块被重复使用,那么将不会重新打包,将使用之前打包的路径

    写在最后

    本篇也是比较详细的介绍了SplitChunksPlugin这个插件,其实其内容还远比文章中介绍的多,有兴趣的同学可以去官网再去查阅相关的资料。用好SplitChunksPlugin你的代码打包将变的效率更高,学习一下吧~

    相关文章

      网友评论

          本文标题:webpack代码分割之SplitChunksPlugin和魔法

          本文链接:https://www.haomeiwen.com/subject/ottejktx.html