SplitChunksPlugin简介及在多入口页项目中的实践

本文深入探讨了Webpack的SplitChunksPlugin,介绍了如何通过配置优化多入口项目,实现按需加载和减少冗余代码,提高应用性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SplitChunksPlugin是webpack4中官方plugin,用于做分包打包的,可以帮你把重复引入的模块按规则打包到指定的js里面。以下是SplitChunksPlugin的默认配置:

splitChunks: {
    chunks: "async", //在默认情况下,SplitChunksPlugin 仅仅影响按需加载的代码块,如果需要对同步的代码做代码分割打包,那么chunk配置为'all'
    minSize: 30000, // 模块的最小体积
    minChunks: 1, // 模块的最小被引用次数
    maxAsyncRequests: 5, // 按需加载的最大并行请求数
    maxInitialRequests: 3, // 一个入口最大并行请求数
    automaticNameDelimiter: '~', // 文件名的连接符
    name: true,
    cacheGroups: { // 缓存组
        vendors: {  //引入的node modules里面的库打包成一个vendor
            test: /[\\/]node_modules[\\/]/,
            priority: -10
        },
        default: {  //其他重复的模块,如业务组件、自定义公共组件等
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true
        }
    }
}

在单一入口页的项目开启splitChunk的功能其实配置很简单,只需要在 optimization 里面配置如下,splitChunk会使用默认的配置对项目进行拆包

splitChunks: {
    chunks: 'all',
    name: true
}

一般我们配置多入口页,都会使用 HtmlWebpackPlugin ,如果是 HtmlWebpackPlugin 结合SplitChunkPlugin 使用的话,需要在不同的入口页面指明该页面对应的chunk的名称,否则该页面引用的chunk文件对应不上的话,页面是无法正常加载的

下图是我的项目结构,app.js是主入口页,其他几个入口页都是分享出去的页面,对应app.js里面的一些模块(app.js里面的模块采取异步加载的方式引入)
在这里插入图片描述
如果不使用 SplitChunksPlugin ,我们利用 BundleAnalyzerPlugin 打包分析工具查看打包后的结果(下图),非常大,很多公共的库或业务组件被重复打包
在这里插入图片描述
接着,我们按SplitChunksPlugin的基础配置,在webpack.config.js里面引入,以~连接的chunk就是SplitChunksPlugin使用基础的配置给我们拆包出来的文件,这时我们的页面是不能正常加载的,因为这些拆包出来的chunk不能自动地注入到所引用的入口页里
在这里插入图片描述
那么我们先把项目里引用的node_modules的三方库拆出来,并在入口文件中注入,SplitChunksPlugin配置如下:

splitChunks: {
    chunks: 'all',
    name: true,
    cacheGroups: {
        vendors: { // 项目基本框架等
            chunks: 'all',
            test: /node_modules/,
            priority: 100,
            name: 'vendors',
        }
    }
}

HtmlWebpackPlugin配置:

new HtmlWebpackPlugin({
    template: './templete/index.html',
    filename: 'index.html',
    chunks: ['app', 'vendors']   //注入对应的入口js文件、拆包出来的verdor文件(命名跟SplitChunks cacheGroup里配置的名称一致)
}),
new HtmlWebpackPlugin({
    template: './templete/index-no-pb.html',
    filename: 'home.html',
    chunks: ['home', 'vendors']
}),
new HtmlWebpackPlugin({
    template: './templete/index-no-pb.html',
    filename: 'profile.html',
    chunks: ['profile', 'vendors']
}),
...

我们可以看到,除了公共库的chunk,webpack还帮我们打包出了一些其他的公共chunk,这是因为默认配置里还有个default参数,会帮我们打包一些别的重复引用的模块。同样,我们还是需要给这些打包的chunk配置一下,不然这些公共chunk也不能被正常地注入
在这里插入图片描述
修改一下SplitChunksPlugin的配置

splitChunks: {
    chunks: 'all',
    name: true,
    cacheGroups: {
        vendors: { // 项目引用的三方库,如mobx等
            chunks: 'all',
            test: /node_modules/,
            priority: 100,   //值越大,打包越优先参照此配置项
            name: 'vendors',
        },
        commons: { // 其他同步加载公共包,如自定义组件等
            chunks: 'all',
            minChunks: 2,
            priority: 80,
            name: 'commons'
            
        }
    }
}

重写了splitChunks 的 cacheGroups 默认参数后,可以按照我们的要求进行打包了,node_modules里面的部分打包到vendor.chunk里面,自定义的组件等其他重复引用模块被打包到了commons.chunk里,注意在HtmlWebpackPlugin 里面也要同时配置commons这个chunk
在这里插入图片描述
其实,按上面的配置,我们的打包结果已经比之前优化很多了,但是,这并不是最好的处理结果。因为commons.chunk里面打包的重复模块,在不同的入口页其实是用不上的。commons.chunk打包了所有引用超过两次的模块,其中就包括record chunk、profile chunk、home chunk、rank chunk等,因为这些部分同时在app.js和对应的入口页中引用了。比如说我只打开profile.html入口页,那我只需要profile chunk,而不需要另外的一些模块。那我们再修改一下配置

splitChunks: {
    chunks: 'all',
    name: true,
    cacheGroups: {
        vendors: { // 项目引用的三方库,如mobx等
            chunks: 'all',
            test: /node_modules/,
            priority: 100,
            name: 'vendors',
        },
        commons: { // 其他同步加载公共包,如自定义组件等
            chunks: 'all',
            minChunks: 3,   //最小引用次数修改为3,那么app.js和其他入口页共用的模块就不会被打包进来,而是只打包了引用次数超过三次的一些自定义组件
            name: 'commons',
            priority: 80,
        },
        default: false  //注意把cacheGroups的默认的default设置为false,不然还是会走default里面的配置,将引用了两次以上的模块进行打包
    }
}

最后结果如下图所示,公共包有两个,而业务逻辑模块(home|rank|record|profile)没有被打进commons.chunk里面,被单独打成了一个个异步chunk。

在这里插入图片描述

虽然最后的打包方式整体大小会比之前的稍大一点,但是在请求不同的入口页时,会按需引入,以record.js入口页为例,请求时加载vendor + commons + record + recordChunk(约等于930多k),但是按之前的方式全部打到一个commons.chunk里,请求时加载vendor + commons + record(约等于1019多k)

SplitChunksPlugin虽然好用,但是也不要盲目地使用,应该根据项目的具体情况而定,一般如果是单入口页面,就直接按默认配置即可;多入口页的话,可以根据具体情况再进行拆包,自己写cacheGroups的配置的时候注意要关闭或者覆盖默认配置。

【参考】

https://webpack.js.org/plugins/split-chunks-plugin/#defaults

https://www.jb51.net/article/151976.htm

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值