Web 之 Webpack 异步加载(懒加载)分包和使用SplitChunksPlugin 进行简单拆解分包

Web  之 Webpack 异步加载(懒加载)分包和使用SplitChunksPlugin 进行简单拆解分包

目录

Web  之 Webpack 异步加载(懒加载)分包和使用SplitChunksPlugin 进行简单拆解分包

一、简单介绍

二、基础工程(未使用 SplitChunksPlugin 时)

三、懒加载分包的方式重新打包

四、SplitChunksPlugin 插件分包


一、简单介绍

       Web 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。

本节介绍,Web 前端开发中使用 webpack ,测试 webpack 懒加载分包和使用SplitChunksPlugin 进行简单分包整理,如果有不足之处,欢迎指出,或者你有更好的方法,欢迎留言。

操作环境:

  •         win 10
  •         node 16.14.0 版本
  •         npm 8.3.1 版本
  •         webpack: 5.73.0
  •         webpack-cli: 4.10.0
     

官网 SplitChunksPlugin 介绍:SplitChunksPlugin | webpack 中文文档

github 对 SplitChunksPlugin 介绍:GitHub - gexiaolin/SplitChunksPlugin: 文档翻译

最初,chunks(以及内部导入的模块)是通过内部 webpack 图谱中的父子关系关联的。CommonsChunkPlugin 曾被用来避免他们之间的重复依赖,但是不可能再做进一步的优化。

从 webpack v4 开始,移除了 CommonsChunkPlugin,取而代之的是 optimization.splitChunks

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async', // 仅提取按需载入的module
      minSize: 30000, // 提取出的新chunk在两次压缩(打包压缩和服务器压缩)之前要大于30kb
      maxSize: 0, // 提取出的新chunk在两次压缩之前要小于多少kb,默认为0,即不做限制
      minChunks: 1, // 被提取的chunk最少需要被多少chunks共同引入
      maxAsyncRequests: 5, // 最大按需载入chunks提取数
      maxInitialRequests: 3, // 最大初始同步chunks提取数
      automaticNameDelimiter: '~', // 默认的命名规则(使用~进行连接)
      name: true,
      cacheGroups: { // 缓存组配置,默认有vendors和default
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};

一些名词解释:

1、chunks:

  • all: 不管文件是动态还是非动态载入,统一将文件分离。当页面首次载入会引入所有的包
  • async: 将异步加载的文件分离,首次一般不引入,到需要异步引入的组件才会引入。
  • initial:将异步和非异步的文件分离,如果一个文件被异步引入也被非异步引入,那它会被打包两次(注意和all区别),用于分离页面首次需要加载的包。

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

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

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

3、automaticNameDelimiter: 连接符

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

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

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

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

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

6、优先级关系

maxInitialRequest / maxAsyncRequests <maxSize <minSize。

7、cacheGroups 定制分割包的规则

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

8、minChunks

最少引入的次数

二、基础工程(未使用 SplitChunksPlugin 时)

1、首先 npm init -y 进行基本的环境搭建,然后创建 src 文件夹,并添加一个 webpack.config.js 脚本

 2、npm install lodash ,作为后面测试使用

 3、在src 中添加文件夹 index.js\pageA.js\pageB.js文件,并添加简单代码

// index.js
import './pageA'
import './pageB'

console.log('this is index')



// pageA.js
console.log('this is pageA')
export default 'pageA'



// pageB.js
console.log('this is pageB')
export default 'pageB'

4、在 webpack.config.js 中添加代码,进行基本的代码打包

const path = require('path')

module.exports={
	entry:{
		index:"./src/index.js"
	},
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'[name].[hash:8].js'
	},
	mode:'development'
}

5、在控制台,使用 webpack 进行打包,生成 index.xxxxxx.js 5.08kb

 

 

6、添加 index.js 添加引入 lodash ,然后打包 ,生成 index.xxxxxx.js 555 kb

 

7、在控制台,安装npm install  webpack-bundle-analyzer --save-dev,用来打包分析,webpack.config.js 添加 webpack-bundle-analyzer 插件

module.exports={
	entry:{
		index:"./src/index.js"
	},
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'[name].[hash:8].js'
	},
	mode:'development',
	plugins:[
		new require('webpack-bundle-analyzer').BundleAnalyzerPlugin()
	]
}

8、运行webpack,浏览器打开 http://127.0.0.1:8888

三、懒加载分包的方式重新打包

1、index.js 使用懒加载的方式加载 pageA.js 和 pageB.js

2、webpak 就会把之前的 pageA.js 和 pageB.js 拆分出来

3、新建一个index.html ,引入懒加载打包生成的 index.xxxx.js 脚本,浏览器打印和加载资源如下,正常显示,以及按需加载 pageA

4、webpack-bundle-analyzer 包分析图如下

四、SplitChunksPlugin 插件分包

1、安装一个 npm install jquery 插件,在 pageA.js 和 pageB.js 中引入 jquery

 2、在 webpack.config.js 中添加对应的 optimization / splitChunks 信息

const path = require('path')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports={
	entry:{
		index:"./src/index.js"
	},
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'[name].[hash:8].js'
	},
	mode:'development',
	plugins:[
		new BundleAnalyzerPlugin()
	],
	optimization: {
	  splitChunks: {
	   chunks: 'async', // 代码分割时对异步代码生效,all:所有代码有效,inital:同步代码有效
	   minSize: 30000, // 代码分割最小的模块大小,引入的模块大于 30000B 才做代码分割
	   minChunks: 1, // 引入的次数大于等于1时才进行代码分割
	   maxAsyncRequests: 6, // 最大的异步请求数量,也就是同时加载的模块最大模块数量
	   maxInitialRequests: 4, // 入口文件做代码分割最多分成 4 个 js 文件
	   cacheGroups: { // 缓存组配置,默认有vendors和default
		   vendors: {
			 test: /[\\/]node_modules[\\/]/, // 匹配需拆分chunk的目录
			 priority: -10, // 拆分优先级
			 name:'venders'
		   },
		   default: {
			 minChunks: 2, // 覆盖外层minChunks,用于提取被引用指定次数的公共模块,这里默认2次
			 priority: -20,
			 name:'common',
			 reuseExistingChunk: true // 是否重用已存在的chunk
		   }
		},
			 
	  }
	 }
}

 3、根据这些规则,控制台 webpack 进行打包的时候,就会根据规则,进行分包

4、在 index.html 中引入Split 后的 index.xxxxxxx.js

 

5、把 lodash 从  index 中分离,在 webpack.config.js 中修改

const path = require('path')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports={
	entry:{
		index:"./src/index.js",
	},
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'[name].[hash:8].js'
	},
	mode:'development',
	plugins:[
		new BundleAnalyzerPlugin()
	],
	optimization: {
	  splitChunks: {
	   chunks: 'async', // 代码分割时对异步代码生效,all:所有代码有效,inital:同步代码有效
	   minSize: 30000, // 代码分割最小的模块大小,引入的模块大于 30000B 才做代码分割
	   minChunks: 1, // 引入的次数大于等于1时才进行代码分割
	   maxAsyncRequests: 6, // 最大的异步请求数量,也就是同时加载的模块最大模块数量
	   maxInitialRequests: 4, // 入口文件做代码分割最多分成 4 个 js 文件
	   cacheGroups: { // 缓存组配置,默认有vendors和default
		   vendors: {
			 test: /[\\/]node_modules[\\/]/, // 匹配需拆分chunk的目录
			 priority: -10, // 拆分优先级
			 name:'venders'
		   },
		   lodashVenodr: { // 将体积较大的lodash单独提取包,指定页面需要的时候再异步加载
		      test: /lodash/,
		      priority: -10,
		      name: 'lodashVenodr',
		      chunks: 'all'
		     },
		   default: {
			 minChunks: 2, // 覆盖外层minChunks,用于提取被引用指定次数的公共模块,这里默认2次
			 priority: -20,
			 name:'common',
			 reuseExistingChunk: true // 是否重用已存在的chunk
		   }
		},
			 
	  }
	 }
}

6、根据提示,在index.html 引入生成的 index.xxxxx.js,以及 lodashVendor.xxxxx.js

 

 

 这里简单分包操作如此,当然不是包越小越多越好,而是,根据实际项目运行结果需要拆解分包

猜你喜欢

转载自blog.csdn.net/u014361280/article/details/125737041