详解webpack4之splitchunksPlugin代码包分拆

详解webpack4之splitchunksPlugin代码包分拆

项目有home和topic两个入口文件,主要包括:

react、mobx、antd作为项目的基本框架,

echarts和d3(画图)是项目中部分页面用到比较大的组件库

src下的工作的组件和代码

其他的非公共代码。

两个入口文件都用react-loadable做了异步加载

import Loadable from 'react-loadable'; ... const LoadableLogin = Loadable({ loader: () => import('../../common/components/login'), loading: Loading, }); ...

webpack部分配置相关如下:

module.exports = { ... mode: 'production', entry: { // 多入口 home: './src/home', topic: './src/topic', }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, }, plugins: [ new HtmlWebpackPlugin({ // home页面 filename: 'home.html', template: './template.html', }), new HtmlWebpackPlugin({ // topic页面 filename: 'topic.html', template: './template.html', inject: true, }), ], ... }

splitChunks

chunks:

all: 不管文件是动态还是非动态载入,统一将文件分离。当页面首次载入会引入所有的包

async: 将异步加载的文件分离,首次一般不引入,到需要异步引入的组件才会引入。

initial:将异步和非异步的文件分离,如果一个文件被异步引入也被非异步引入,那它会被打包两次(注意和all区别),用于分离页面首次需要加载的包。

minSize: 文件最小打包体积,单位byte,默认30000

比如说某个项目下有三个入口文件,a.js和b.js和c.js都是100byte,当我们将minSize设置为301,那么webpack就会将他们打包成一个包,不会将他们拆分成为多个包。

比如说某个项目下有三个入口文件,a.js和b.js和c.js都是100byte,当我们将minSize设置为301,那么webpack就会将他们打包成一个包,不会将他们拆分成为多个包。

automaticNameDelimiter: 连接符

假设我们生成了一个公用文件名字叫vendor,a.js,和b.js都依赖他,并且我们设置的连接符是"~"那么,最终生成的就是 vendor~a~b.js

maxInitialRequests 入口点处的最大并行请求数,默认为3

如果我们设置为1,那么每个入口文件就只会打包成为一个文件

maxAsyncRequests 最大异步请求数量,默认5

如果我们设置为1,那么每个入口文件就只会打包成为一个文件

优先级关系

maxInitialRequest / maxAsyncRequests <maxSize <minSize。

cacheGroups 定制分割包的规则

test可以配置正则和写入function作为打包规则。其他属性均可继承splitChunks,这里必须说一下 priority,设置包的打包优先级,非常重要! (后面结合实践)

minChunks

最少引入的次数

实践

我们以一个最简单的配置开始,将公共代码打包出来

splitChunks: { chunks: 'all', // initial、async和all minSize: 30000, // 形成一个新代码块最小的体积 maxAsyncRequests: 5, // 按需加载时候最大的并行请求数 maxInitialRequests: 3, // 最大初始化请求数 automaticNameDelimiter: '~', // 打包分割符 name: true, cacheGroups: { vendors: { // 打包两个页面的公共代码 minChunks: 2, // 引入两次及以上被打包 name: 'vendors', // 分离包的名字 chunks: 'all' }, } },

两个入口文件的公共代码被打包到vendor文件夹下面,包括echarts d3 amcharts等一些三方包和src下的公共代码。

详解webpack4之splitchunksPlugin代码包分拆

这当然不是我们想要的结果!存在以下问题:

其实当我们进入网站,一般第一步都是进入一个登陆页面,需要的只是项目的基本框架代码,例如react,react-dom.antd等,我们可以用all(或者initial)将它们单独打包,作为首页必须载入的包

我们打包的公共包,首次加载页面的时候,只想把同步加载的加载进来,所以需要一个同步的Common包

像echarts,d3,以及一些src下面一些异步加载的包,将它们利用async将打包成一个独立异步加载包

我们修改cacheGroups为:

cacheGroups: { vendors: { // 项目基本框架等 chunks: 'all', test: /(react|react-dom|react-dom-router|babel-polyfill|mobx)/, priority: 100, name: 'vendors', }, 'async-commons': { // 异步加载公共包、组件等 chunks: 'async', minChunks: 2, name: 'async-commons', priority: 90, }, commons: { // 其他同步加载公共包 chunks: 'all', minChunks: 2, name: 'commons', priority: 80, }, }

详解webpack4之splitchunksPlugin代码包分拆

这次webpack帮我们打出来的包主要有:

async-common:是两个入口文件都异步加载的三方包和利用react-loader做的懒加载代码,有echarts,d3等

vendors: 包括react,react-dom,antd等

commons: 引用超过两次的同步代码

这里说两个需要注意的地方:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/339abee221122aa7152e077dd266dd62.html