一、SplitChunksPlugin简介
SplitChunksPlugin是webpack4中的一个插件,用于抽离公共代码,减少打包体积,提高加载速度,让页面更快地展现出来。
在基于webpack构建的项目中,通常存在着多个共同依赖的模块,每次打包时都会将这些共同依赖的模块进行打包,导致打包体积较大,下载速度慢,用户体验不佳。SplitChunksPlugin的作用就是将这些共同依赖的模块抽离成单独的chunk文件,避免重复打包,减小打包体积,提高页面加载速度,从而提升用户体验。
二、SplitChunksPlugin配置方式
SplitChunksPlugin的配置有两种方式:通过optimization属性配置和通过插件方式配置。我们主要介绍optimization属性配置方式。
三、optimization属性中的SplitChunksPlugin配置
optimization属性是webpack4中新引入的属性,用于优化webpack打包构建,其中的SplitChunksPlugin是用于分离代码的插件。
optimization属性中常见的配置项如下:
module.exports = { optimization: { // 压缩JS minimize: true, // 压缩CSS minimizer: [new CssMinimizerPlugin()], // 分离公共代码 splitChunks: { // 分离代码的规则 test: /\.js$/, // 分离出来的代码块的名称 name: 'common', // 源代码块的最小大小 minSize: 10000, // 共同依赖的模块的引入次数,大于等于该值才会被分离 minChunks: 2, // 同步代码块之间的并行请求次数,0表示关闭 maxAsyncRequests: 5, // 异步代码块之间的并行请求次数,0表示关闭 maxInitialRequests: 3, // 模块路径抽取,默认采用模块名或包名 automaticNameDelimiter: '~', // 拆分出来的块的策略 chunks: 'all', // 只考虑会被切割出去的chunk enforceSizeThreshold: 50000, // 分离的代码块需要满足的条件 cacheGroups: { // node_modules中的模块抽离 vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all' }, // 把src下的模块切割到一个单独的块中 util: { test: /[\\/]src[\\/]utils[\\/]/, name: 'util', chunks: 'all' } } } } }
以上代码中的属性含义如下:
test
:用于选择出需要分离的模块。name
:抽离出来的chunk的名称。minSize
:限制最小大小,如果不满足,不会抽离。minChunks
:共同依赖的模块的引入次数,大于等于该值才会被分离。maxAsyncRequests
:同步代码块之间的并行请求次数,0表示关闭。maxInitialRequests
:异步代码块之间的并行请求次数,0表示关闭。automaticNameDelimiter
:模块路径抽取,默认采用模块名或包名。chunks
:拆分出来的块的策略,一般设置为'all'cacheGroups
:定义缓存组,用于分组配置。
四、cacheGroups配置项详解
cacheGroups是具体的分组配置,包含了name, test, priority, reuseExistingChunk的选项,是SplitChunksPlugin中非常重要的配置项。cacheGroups中常用的配置项如下:
name
:抽离出来的chunk的名称。test
:用于选择出需要分离的模块。priority
:用于定义组抽取的优先级。reuseExistingChunk
:表示如果一个模块已经被分离出来了,是否继续重复分离。
以下是cacheGroups的配置实例。
module.exports = { optimization: { splitChunks: { cacheGroups: { // node_modules中的模块抽离 vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', priority: 1, reuseExistingChunk: true }, // 把src下的模块切割到一个单独的块中 util: { test: /[\\/]src[\\/]utils[\\/]/, name: 'util', chunks: 'all', priority: 2, reuseExistingChunk: true } } } } }
以上配置中vendor为node_modules中的模块抽离,util为把src下的模块切割到一个单独的块中。
五、SplitChunksPlugin使用案例
下面来介绍一个使用SplitChunksPlugin插件的案例。
首先,配置webpack.config.js文件,如下:
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry: { index: './src/index.js', detail: './src/detail.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, optimization: { runtimeChunk: 'single', splitChunks: { minSize: 20000, maxAsyncRequests: 30, maxInitialRequests: 30, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', enforce: true } } } }, plugins: [ new HtmlWebpackPlugin({ title: 'SplitChunksPlugin Demo', template: './src/index.html' }) ] };
之后,你可以在src/index.js文件中导入react和react-dom模块,如下所示:
import React from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render(Hello, world!
, document.getElementById('root') );
如果你在src/detail.js文件中也导入react和react-dom模块,那么这两个模块将会被重复打包。为了避免重复打包,使用SplitChunksPlugin,把这两个模块抽离出公共的chunk中,只需要在webpack.config.js中加入如下代码块即可:
optimization: { runtimeChunk: 'single', splitChunks: { minSize: 20000, maxAsyncRequests: 30, maxInitialRequests: 30, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', enforce: true } } } }
其中,cacheGroups用于指定需要抽离的模块,这里的vendor表示需要抽离node_modules目录下的模块,因为React和React-DOM都在这个目录下,所以可以使用下面的代码引入React和React-DOM。
import React from 'react'; import ReactDOM from 'react-dom';
最后,我们运行webpack,就可以看到在dist目录下生成如下文件:
dist/ index.html index.js vendors.js
index.js和vendors.js文件中分别包含了应用自身的代码和抽离出来的公共代码,index.html中引用的是index.js和vendors.js两个文件。
六、总结
通过使用SplitChunksPlugin插件可以抽离共同依赖的模块,减小打包体积,提高页面加载速度,提升用户体验。本文通过介绍SplitChunksPlugin的基本用法和案例,希望能够帮助读者更加深入地了解这个重要的webpack插件。