webpack高级应用篇(十四):splitChunks.chunks 中的 async、initial 和 all

前言

以下摘自 webpack SplitChunksPlugin 官方文档
在这里插入图片描述

然而官方文档中只说明了 async 是默认的选项,关于 asyncinitialall 之间的区别却没有很好的进行举例解释。

今天我们将来探讨一下这三者的区别。


三种模式含义

  • async表示动态引入的模块将会被拆分;
  • initial表示不会将动态引入和静态引入的同一模块一起处理,而是分开处理;
  • all对所有类型的模块进行拆分;

实验前准备

因为 webpack 将根据以下条件自动拆分 chunks:

  • 新的 chunk 可以被共享,或者模块来自于 node_modules 文件夹
  • 新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积)
  • 当按需加载 chunks 时,并行请求的最大数量小于或等于 30
  • 当加载初始化页面时,并发请求的最大数量小于或等于 30

因此本实验采用了两个第三方模块来做实验,分别是 lodashmoment,因为他们的体积足够大;

本实验基于 [email protected]单入口多入口 这两个方向进行测试;

本实验项目目录

// splitChunks.chunks
├── src
│   ├── index.js
│   ├── main-1.js
│   ├── main-2.js
├── webpack.config.js

单入口

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
    
     BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = {
    
    
  mode: 'development',

  output: {
    
    
    clean: true,
    filename: 'js/[name].[contenthash].js',
  },

  plugins: [
    new HtmlWebpackPlugin(),
    new BundleAnalyzerPlugin(),
  ],

  optimization: {
    
    
    splitChunks: {
    
    
      chunks: 'async',
      // chunks: 'initial',
      // chunks: 'all',
    },
  },
};

src/index.js

import moment from 'moment';

import(/* webpackChunkName: 'lodash-index' */ 'lodash').then(({
     
      default: lodash }) => {
    
    
  lodash.findIndex([1, 2, 3]);
});

console.log('index', moment().format('YYYY-MM-DD HH:mm:ss'));

console.log('My index is running');

执行 npx wp,可以得到如下打包结果


async 模式

在这里插入图片描述
在这里插入图片描述

可以看到最终打包出2️⃣个文件

其中动态引入的 lodash 被打包为 lodash-index.hash.js

index.js 打包为 main.hash.js,其中包含了 moment 模块


initial 模式

在这里插入图片描述
在这里插入图片描述

可以看到最终打包出3️⃣个文件

其中动态引入的 lodash 依旧被打包为 lodash-index.hash.js

index.js 打包后被拆分为 main.hash.jsvendors-node_modules_moment_locale.js


all 模式

在这里插入图片描述
在这里插入图片描述

可以看到最终打包出3️⃣个文件,

其中动态引入的 lodash 依旧被打包为 lodash-index.hash.js

index.js 打包后被拆分为 main.hash.jsvendors-node_modules_moment_locale.js

这时的 allinitial 是没有区别的


结论

async initial all
image-20220501134657123 image-20220501135637942 image-20220501135637942

在单入口的情况下 initialall 模式是一样的,async 只会拆分动态引入的模块。


多入口

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
    
     BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = {
    
    
  mode: 'development',

  entry: {
    
    
    main1: './src/main-1.js',
    main2: './src/main-2.js',
  },

  output: {
    
    
    clean: true,
    filename: 'js/[name].[contenthash].js',
  },

  plugins: [
    new HtmlWebpackPlugin(),
    new BundleAnalyzerPlugin(),
  ],

  optimization: {
    
    
    splitChunks: {
    
    
      chunks: 'async',
      // chunks: 'initial',
      // chunks: 'all',
    },
  },
};

src/mian-1.js

import moment from 'moment';

import(/* webpackChunkName: 'lodash-main-1' */ 'lodash').then(({
     
      default: lodash }) => {
    
    
  lodash.findIndex([1, 2, 3]);
});

console.log('main1', moment().format('YYYY-MM-DD HH:mm:ss'));

console.log('My main1 is running');

src/mian-2.js

import {
    
     findIndex } from 'lodash';
import moment from 'moment';

findIndex([1, 2, 3]);

console.log('main2', moment().format('YYYY-MM-DD HH:mm:ss'));

console.log('My main2 is running');

执行 npx wp,可以得到如下打包结果


async 模式

在这里插入图片描述
在这里插入图片描述

可以看到最终打包出3️⃣个文件,

其中 main-1.js 打包为 main1.hash.js,其中包含了moment 模块

main-1.js 中动态引入的 lodash 被打包为 lodash-main-1.hash.js

main-2.js 打包为 main2.hash.js,其中包含了 momentlodash 模块


分析

两个入口文件中都引入了 momentlodash 模块,但结果是这两个模块在整个的打包中都没有进行复用


initial 模式

在这里插入图片描述
在这里插入图片描述

可以看到最终打包出5️⃣个文件,

其中 main-1.js 打包后被拆分为 main1.hash.js

main-1.js 中动态引入的 lodash 被打包为 lodash-main-1.hash.js

main-1.js 中大模块 moment 被拆分为 vendors-node_modules_moment_locale.hash.js


main-2.js 打包后被拆分为 main2.hash.js

main-2.js 中静态引入的 lodash 被打包为 vendors-node_modules_lodash_lodash_js.b3a5668e68bc3ca616ad.js

main-2.js 中大模块 moment 被拆分为 vendors-node_modules_moment_locale.hash.js,与 main-1.js 公用。


分析

两个入口文件中都引入了 momentlodash 模块,其中同为静态引入的 moment 模块在打包后被拆分为一个进行复用

分别动态引入和静态引入的 lodash 模块在打包后还是两个文件,没有进行复用


all 模式

在这里插入图片描述
在这里插入图片描述

可以看到最终打包出4️⃣个文件,

其中 main-1.js 打包后被拆分为 main1.hash.js

main-1.js 中动态引入的 lodash 被打包为 lodash-main-1.hash.js

main-1.js 中大模块 moment 被拆分为 vendors-node_modules_moment_locale.hash.js


main-2.js 打包后被拆分为 main2.hash.js

main-2.js 中静态引入的 lodash 打包后在关系图中没有显示,但实际是与 main-1.js 中动态引入 的 lodash 进行了复用;

main-2.js 中大模块 moment 被拆分为 vendors-node_modules_moment_locale.hash.js,与 main-1.js 公用。


分析

两个入口文件中都引入了 momentlodash 模块,其中符合拆分条件的相同模块,无论是动态引入还是静态引入的,都被拆分为一个文件进行了复用


结论

async initial all
image-20220501134657123 image-20220501135637942 image-20220501135637942

通常情况下,all 模式更为强大。像官网中生涩的描述:设置为 all 可能特别强大,因为这意味着 chunk 可以在异步和非异步 chunk 之间共享。



源码地址:https://gitee.com/yanhuakang/webpack-demos/tree/master/advanced/step_14-splitChunks/chunks

猜你喜欢

转载自blog.csdn.net/qq_41887214/article/details/124527169
今日推荐