55 npm run serve 和 npm run build 的分包策略

前言

这里我们来看一下 vue 这边 打包的时候的一些 拆分包的一些策略

我们经常会使用到 npm run build 进行服务的打包

然后 打包出来的情况, 可能如下, 可以看到 chunk-vendors 是进行了包的拆分, 我们这里就是 来看一下 这里 npm run build 的时候的, 一个分包的策略

3349532ecefa4a6d893ffc0f31cbd540.png

 

 

测试配置

在 vue.config.js 中配置 webpack 打包配置如下

对于 node_modules 下面的所有的依赖, 限定分包策略为 最小10kb, 最大10kb

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    optimization: {
      splitChunks: {
        cacheGroups: {
          defaultVendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            minSize: 10000,
            maxSize: 10000,
          },
          default: {
            chunks: "all",
            minSize: 10000,
            maxSize: 10000,
          },
        }
      }
    }
  }
})

 

 

chunk-vendors 分组的分包策略

首先超过 maxSize 的包会被单独拧出来形成一个单独的包, 不管他的大小多大

a23b5de626504cfa906f96b86832ea27.png

 

然后其次就是 具体的分包的处理了

如果当前 js 添加到当前包未超过 maxSize, 继续迭代下一个

如果当前 js 太小了, 则重新放回队列, 继续迭代下一个

接下来就是 这里定义的一个拆包的算法了,  这里不细说, 我们也不关注具体的拆分的细节

循环结束, 拆分包的过程就结束了, 拆分成了 n 个小包

3212200534cb47fbbdc6313621fff005.png

 

 

拆分的过程调试如下

比如这里 vue.runtime.esm.js 包 268kb, 超过了配置的 10kb 的大小, 直接拧出来形成一个单独的 chunk

40bdcc62063e414db567e2ddf7359574.png

 

接下来 32 个 js, 合计 15kb, 形成一个 chunk

a243c842422a47d9b47dddc300f3f31b.png

 

接下来也是 32 个 js 形成一个 chunk

2c43da1ba51f4013bfc201400a9543c1.png

 

接下来是 剩余的 14 个 js 形成一个 chunk

1102e338718c49978dc26751c8a97724.png

 

当前 chunk 的命名方式是获取 第一个元素的名称 和 最后一个元素名称 的最大公共部分

ebc2a08a894045beb42f62563545628d.png

 

然后这里是在 compilation 中新增各个 chunk 的地方

chunk 的的名称后缀是根据 group 的名称进行 hash 生成的

bc4d6555c69e460eaf441e386c1e21b9.png

 

然后 如图, 就是编译结果的 chunk-vendors-7a6313df 文件, 里面包含了 32 个 js 文件, 然后 minify 压缩之后, 只有 6kb

要看各个 chunk-vendors 中包含了那些 js, 只能通过运行时调试查看

然后 chunk-vendors-2afcb3e6 这个显然就是 vue.runtime.esm.js 文件, minifiy 压缩之后, 只有 70kb

5771dd4b111d48d19e5441903ef0f0fa.png

 

示例项目中各个 module 大小, 以及各个 chunk 对应的 module 列表如下 excel

d36631b2318b4592b595c579551f0cff.png

 

 

npm run serve 中的 app.js 中默认情况下的 chunk 的拆分

app.js 的拆分分了很多种情况, 这里 我们先来看下 默认的行为

vue.config.js 配置如下

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    optimization: {
      splitChunks: {
        cacheGroups: {
          defaultVendors: {
            test: /[\\/]node_modules[\\/]/,
            name(module) {
              return "defaultVendors"
            },
            // chunks: "all",
            // minChunks: 3,
            priority: 10,
            // minSize: 10000,
            maxSize: 10000,
          },
          // default: {
          //   chunks: "all",
          //   name(module) {
          //     return "app11"
          //   },
          //   // filename: "app112"
          //   // priority: -10,
          //   // minSize: 10000,
          //   maxSize: 10000,
          // },
        }
      }
    }
  }
})

 

增加路由配置文件如下, 如下配置了三个路由

import Vue from "vue";
import Router from "vue-router";

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: () => import('../components/snake/Game.vue')
    }, {
      path: '/HelloWorld',
      name: 'HelloWorld',
      component: () => import('../components/HelloWorld')
    }, {
      path: '/AsyncQueue',
      name: 'AsyncQueue',
      component: () => import('../components/AsyncQueue.vue')
    }
  ]
})

 

编译之后的生成的 js 相关的目录结构如下, 我们这里关注 app.js 相关的

即 app.js 和 src_components_xxx 相关的三个文件, 其他的为 node_modules 编译之后生成的项目文件

4354757e42ec44fa8f0d1b07448cfb98.png

 

然后我们看一下 app.js 中 chunk 的拆分

在 visit “src\router\index.js” 的时候, 发现了三个 import(), 然后 采集为 blocks

然后 这里单独拆分出来, 成为单独的 chunk

97ae45fa2f5e444590b9c97e500dcd76.png

 

该 chunk 里面没有保存上下文的任何信息, 上下文的信息是保存在 chunkGroup 中的, 后面对 chunk 和 chunkGroup 进行了关联

9dcb45254f854e2586af081b5be702cc.png

 

为目标 chunk 生成 chunkName 的地方是在 NamedChunkIdsPlugin.js 中, 从 chunkGroup 中相关数据中可以拿到目标 chunk 是属于哪一个文件的

9ace82f536f84b46a7409e4a1a6c8e27.png

39899cf0c0244645b4025ce6a9fd6b90.png

 

 

npm run build 中的 app.js 中默认情况下的 chunk 的拆分

整体的流程 和 上面 npm run serve 中的 app.js 的拆分情况如下

计算 chunk 的 id, 名称如下

1b6ce0e3bbd34d7e93292ca2bbe87baf.png

 

使用 numberHash 进行计算, 如果重复了, 就重新计算

e18bd9a7d81e4ea3aeec2ab947e89e89.png

 

整体来说, chunk 名称和其内容没有什么较为明显的关联

因此, 只能通过 文件内容, 来定位具体的业务组件是在哪一个文件中了

fc4ec0a359f548928430c20208a05463.png

 

但是可以通过 app.js 来进行一个粗略的查找, entryPoint 编号为 3208

37ca0b67675f4f2d988f6b18242fd5e0.png

 

这里便是整个路由, 这两批可以看到 具体的路由信息, 以及组件信息, 比如 “/HelloWorld” 对应于组件 575

c41c0fd77cf34c92a157dda74475df8f.png

 

 

app.js 的手动拆包配置

和上面 chunk-vendors 的拆包的配置类似, app.js 相关, 也是可以手动配置 拆包

配置 vue.config.js 的配置如下, 其中 default 下面的配置对应的是 app.js 的配置

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    optimization: {
      splitChunks: {
        cacheGroups: {
          defaultVendors: {
            test: /[\\/]node_modules[\\/]/,
            name(module) {
              return "defaultVendors"
            },
            // chunks: "all",
            // minChunks: 3,
            priority: 10,
            // minSize: 10000,
            maxSize: 10000,
          },
          default: {
            chunks: "all",
            name(module) {
              return "app11"
            },
            // filename: "app112"
            // priority: -10,
            // minSize: 10000,
            maxSize: 10000,
          },
        }
      }
    }
  }
})

 

打包之后结果如下, 可以看到的是 拆分的和 chunk-vendors 的拆分貌似类似

26be90b0b55b4376a8188d9ae0905b2a.png

 

假设是手动配置了分包的相关配置, 这里 具体的拆分就是和 chunk-vendors 类似的分包拆分处理

在 SplitChunksPlugin 中进行的处理, 这里可以参见上面的 chunk-vendors 的分包策略处理

a93951de34704af8a541aa8144f62f51.png

 

 

app.js 的默认分包 和 手动配置的分包 的差异

这个是从另外的一个维度 来进行的分析

在默认的分包处理下, 可以看到 我们这里访问 HelloWorld, 仅仅是请求了 HelloWorld 的相关的组件

412698767fc6463fbd50775a357c8031.png

 

编译出来的 index.html 如下, 可以看到的是 仅仅是导入了 app.js 这个入口的 chunk

9c2252773e8e44a2bf34d632f0236f1e.png

 

对于路由下面的各个情况, 是导入的各自的 js

703a73f5d6ca4e60a5ab9091a5ec2921.png

 

js 的映射如下

cc34a94329fa42008290e8f9b58305cb.png

 

在手动分包的处理下, 可以看到 请求了 app.js 囊括的所有的 js

74b2048748f84887b0c9b958635e336b.png

 

编译出来 index.html 如下, 可以看到是 引入了所有的包, 不管是进入哪一个页面, 都是请求的全量的 app.js 和 chunk-vendors.js

5c7c068758464f4ca42fecece3f4978c.png

 

 

app.js 的默认分包的每一个组件包含了那些东西?

HelloWorld.vue 文件内容如下

5733b7e8058041489d10759fcb80bd03.png

 

AsyncQueue.vue 文件内容如下, 导入了一个 HelloWorld.vue 的组件

498e6c5b7f6a419b885620fe0f88f6b4.png

 

然后编译完之后的 import('../components/HelloWorld') 如下

a7cb1ed96fa54d878372f710da3b4f64.png

 

然后编译完之后的 import('../components/AsyncQueue) 如下

可以看到 编译之后的结果 是将使用到的组件都内联进来了, 这样可能导致一些公用组件的内容被内联很多次, app.js 总共的包大小 膨胀

但是 页面时按照需要导入的对应的 js

增加了一些 编译器编译的开销, 服务器存储的开销, 减小了客户端请求的开销

42416971f1b44f3fa5f15c8bf93ffe18.png

 

 

完 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/506414.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Leetcode每日一题】模拟 - 提莫攻击(难度⭐)(45)

1. 题目解析 题目链接:495. 提莫攻击 2.算法原理 一、分情况讨论 要计算中毒的总时长,我们需要考虑时间点之间的差值,并根据这些差值来确定中毒的实际持续时间。 情况一:差值大于等于中毒时间 假设你的角色在时间点A中毒&#…

C语言 | Leetcode C语言题解之两数相加

题目: 题解: struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {struct ListNode *head NULL, *tail NULL;int carry 0;while (l1 || l2) {int n1 l1 ? l1->val : 0;int n2 l2 ? l2->val : 0;int sum n1 n2 …

C#(winform) 调用MATLAB函数

测试环境 VisualStudio2022 / .NET Framework 4.7.2 Matlab2021b 参考:C# Matlab 相互调用 Matlab 1、编写Matlab函数 可以没有任何参数单纯定义matlab处理的函数,输出的数据都存在TXT中用以后期读取数据 function [result,m,n] TEST(list) % 计算…

上海亚商投顾:沪指低开高走 5.5G概念股午后走强

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 沪指3月 29日震荡反弹,尾盘涨幅扩大至1%,深成指、创业板指跟随上扬。周期股再度走强&a…

基于SpringBoot+Vue企业级工位管理系统(源码+部署说明+演示视频+源码介绍+lw)

您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦。💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精通…

Modbus取数测试程序

modbus协议,modbus-tcp协议取数测试程序 Java实现modbus-tcp协议取数操作,数据类型转换操作

list(链表)容器(一)

一、list基本概念 链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的 链表的组成:链表由一系列结点组成 结点的组成:一个是存储数据元素的数据域&#xff0…

Mac OS上使用matplotlib库显示中文字体

文章目录 问题描述解决步骤参考文章 问题描述 如果我们想要使用matplotlib画图的话,可能会出现下面的这种warning: UserWarning: Glyph 24212 (\N{CJK UNIFIED IDEOGRAPH-5E94}) missing from current font.解决步骤 解决这个问题,可以按照下面的做法…

【Leetcode】331. 验证二叉树的前序序列化

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 序列化二叉树的一种方法是使用 前序遍历 。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录&#x…

Tidb和MySQL性能简单测试对比

一、单SQL性能对比 由于TiDB的并发能力优秀,但是单个SQL执行延迟较差,为了客观对比,所以只用1个线程来压测tidb和mysql,以观察延迟情况 二、并发SQL性能对比 TiDB:v6.5.2 MySQL:8.0.26 (单机) 三、结论 …

构建安全高效的用户登录系统:登录流程设计与Token验证详解

在当今数字化时代,用户登录系统是几乎所有在线服务的基础。然而,随着网络安全威胁的不断增加,设计一个安全可靠的登录系统变得至关重要。本文将深入探讨用户登录流程的设计原则以及Token验证的实现方式,带您了解如何构建安全高效的…

【MySQL笔记】行转列+列转行+行转列为什么用SUM()

文章目录 行转列思路实现行转列为什么要用SUM等聚合函数 列转行思路回顾下Union 实现列转行 Reference 行转列 思路 GROUP BY聚合函数 实现行转列 SELECT product_id,SUM(IF(store store1, price, NULL)) AS store1,SUM(IF(store store2, price, NULL)) AS store2,SUM(IF(…

Vulnhub:BROKEN: GALLERY

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb WEB wen信息收集 目录扫描 进制转换 ssh登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali/vulnhub] └─# arp-scan -l Interface: eth0, type: EN10MB, M…

上位机图像处理和嵌入式模块部署(qmacvisual形状匹配)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 在qmacvisual软件当中,提供了两种模板匹配的方法。除了前面介绍的灰度匹配,就是今天讲的形状匹配。当然,对于使…

AI如何影响装饰器模式与组合模式的选择与应用

​🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》《MYSQL应用》 💪🏻 制定明确可量化的目标,坚持默默的做事。 🚀 转载自热榜文章:设计模式深度解析:AI如何影响…

【动手学深度学习】深入浅出深度学习之利用神经网络识别螺旋状数据集

目录 🌞一、实验目的 🌞二、实验准备 🌞三、实验内容 🌼1. 生成螺旋状数据集 🌼2. 打印数据集 🌼3. 编程实现 🌻仿射层-Affine类 🌻传播层-Sigmoid类 🌻损失函数…

[数据结构初阶]堆的应用

各位读者老爷好,鼠鼠又来了捏!鼠鼠上一篇博客介绍的堆,那么今天来浅谈以下堆的应用,那么好,我们先来看两个问题: 1.如果有一组乱序的数组数据,希望你将这组数组的数据排成升序或降序&#xff0c…

【Spring MVC】快速学习使用Spring MVC的注解及三层架构

💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:【Spring MVC】快速学习使用Spring MVC的注解及三层架构 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 Spring Web MVC一: 什么是Spring Web MVC&#xff1…

大促销活动时期如何做好DDoS防护?

每一次活动大促带来的迅猛流量,对技术人而言都是一次严峻考验。如果在活动期间遭受黑产恶意DDoS攻击,无疑是雪上加霜。电商的特性是业务常态下通常不会遭受大流量DDoS攻击,且对延迟敏感,因此只需要在活动期间按需使用DDoS防护。本…

分享three.js实现乐高小汽车

前言 Web脚本语言JavaScript入门容易,但是想要熟练掌握却需要几年的学习与实践,还要在弱类型开发语言中习惯于使用模块来构建你的代码,就像小时候玩的乐高积木一样。 应用程序的模块化理念,通过将实现隐藏在一个简单的接口后面&a…