没有了CommonsChunkPlugin,咱拿什么来分包

介绍了Webpack 4中取代CommonsChunkPlugin的新配置项optimization.splitChunks和optimization.runtimeChunk的使用方法及机制。详细解释了如何通过配置实现代码块的分割与优化。

webpack 4 移除 CommonsChunkPlugin,取而代之的是两个新的配置项(optimization.splitChunks 和 optimization.runtimeChunk),下面介绍一下用法和机制。

默认方式

webpack模式模式现在已经做了一些通用性优化,适用于多数使用者。

需要注意的是:默认模式只影响按需(on-demand)加载的代码块(chunk),因为改变初始代码块会影响声明在HTML的script标签。如果可以处理好这些(比如,从打包状态里面读取并动态生成script标签到HTML),你可以通过设置optimization.splitChunks.chunks: "all",应用这些优化模式到初始代码块(initial chunk)。

webpack根据下述条件自动进行代码块分割:

  • 新代码块可以被共享引用,OR这些模块都是来自node_modules文件夹里面
  • 新代码块大于30kb(min+gziped之前的体积)
  • 按需加载的代码块,最大数量应该小于或者等于5
  • 初始加载的代码块,最大数量应该小于或等于3

为了满足后面两个条件,webpack有可能受限于包的最大数量值,生成的代码体积往上增加。

我们来看一下一些例子:

Example 1

// entry.js
import("./a");
// a.js
import "react-dom";
// ...

结果:webpack会创建一个包含react-dom的分离代码块。当import调用时候,这个代码块就会与./a代码被并行加载。

为什么会这样打包:

  • 条件1:这个代码块是从node_modules来的
  • 条件2:react-dom大于30kb
  • 条件3:按需请求的数量是2(小于5)
  • 条件4:不会影响初始代码请求数量

这样打包有什么好处呢?

对比起你的应用代码,react-dom可能不会经常变动。通过将它分割至另外一个代码块,这个代码块可以被独立缓存起来(假设你在用的是长期缓存策略:chunkhash,records,Cache-Control)

Example 2

// entry.js
import("./a");
import("./b");
// a.js
import "./helpers"; // helpers is 40kb in size
// ...
// b.js
import "./helpers";
import "./more-helpers"; // more-helpers is also 40kb in size
// ...

结果:webpack会创建一个包含./helpers的独立代码块,其他模块会依赖于它。在import被调用时候,这个代码块会跟原始的代码并行加载(译注:它会跟a.jsb.js并行加载)。

为什么会这样打包:

  • 条件1:这个代码块会被两个导入(import)调用依赖(指的是a.jsb.js
  • 条件2:helpers体积大于30kb
  • 条件3:按需请求的数量是2(小于5)
  • 条件4:不会影响初始代码请求数量

这样打包有什么好处呢?

helpers代码放在每一个依赖的块里,可能就意味着,用户重复会下载它两次。通过用一个独立的代码块分割,它只需要被下载一次。实际上,这只是一种折衷方案,因为我们为此需要付出额外的一次请求的代价。这就是为什么默认webpack将最小代码块分割体积设置成30kb(译注:太小体积的代码块被分割,可能还会因为额外的请求,拖慢加载性能)。

通过optimizations.splitChunks.chunks: "all",上面的策略也可以应用到初始代码块上(inital chunks)。代码代码块也会被多个入口共享&按需加载(译注:以往我们使用CommonsChunkPlugin最通常的目的)。

配置

如果想要更深入控制这个按需分块的功能,这里提供很多选项来满足你的需求。

Disclaimer:不要在没有实践测量的情况下,尝试手动优化这些参数。默认模式是经过千挑万选的,可以用于满足最佳web性能的策略。

缓存组(Cache Group)

这项优化可以用于将模块分配到对应的Cache group

默认模式会将所有来自node_modules的模块分配到一个叫vendors的缓存组;所有重复引用至少两次的代码,会被分配到default的缓存组。

一个模块可以被分配到多个缓存组,优化策略会将模块分配至跟高优先级别(priority)的缓存组,或者会分配至可以形成更大体积代码块的组里。

Conditions

在满足下述所有条件时,那些从相同代码块和缓存组来的模块,会形成一个新的代码块(译注:比如,在满足条件下,一个vendoer可能会被分割成两个,以充分利用并行请求性能)。

有四个选项可以用于配置这些条件:

  • minSize(默认是30000):形成一个新代码块最小的体积
  • minChunks(默认是1):在分割之前,这个代码块最小应该被引用的次数(译注:保证代码块复用性,默认配置的策略是不需要多次引用也可以被分割)
  • maxInitialRequests(默认是3):一个入口最大的并行请求数
  • maxAsyncRequests(默认是5):按需加载时候最大的并行请求数。

Naming

要控制代码块的命名,可以用name参数来配置。

注意:当不同分割代码块被赋予相同名称时候,他们会被合并在一起。这个可以用于在:比如将那些多个入口/分割点的共享模块(vendor)合并在一起,不过不推荐这样做。这可能会导致加载额外的代码。

如果赋予一个神奇的值true,webpack会基于代码块和缓存组的key自动选择一个名称。除此之外,可以使用字符串或者函数作为参数值。

当一个名称匹配到相应的入口名称,这个入口会被移除。

Select chunks

通过chunks选项,可以配置控制webpack选择哪些代码块用于分割(译注:其他类型代码块按默认方式打包)。有3个可选的值:initialasyncall。webpack将会只对配置所对应的代码块应用这些策略。

reuseExistingChunk选项允许复用已经存在的代码块,而不是新建一个新的,需要在精确匹配到对应模块时候才会生效。

这个选项可以在每个缓存组(Cache Group)里面做配置。

Select modules

test选项用于控制哪些模块被这个缓存组匹配到。原封不动传递出去的话,它默认会选择所有的模块。可以传递的值类型:RegExpStringFunction

通过这个选项,可以通过绝对资源路径(absolute modules resource path)或者代码块名称(chunk names)来匹配对应模块。当一个代码块名称(chunk name)被匹配到,这个代码块的所有模块都会被选中。

配置缓存组(Configurate cache group)

这是默认的配置:

splitChunks: {
    chunks: "async",
    minSize: 30000,
    minChunks: 1,
    maxAsyncRequests: 5,
    maxInitialRequests: 3,
    name: true,
    cacheGroups: {
        default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true,
        },
        vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10
        }
    }
}

默认来说,缓存组会继承splitChunks的配置,但是testpriortyreuseExistingChunk只能用于配置缓存组。

cacheGroups是一个对象,按上述介绍的键值对方式来配置即可,值代表对应的选项:

除此之外,所有上面列出的选择都是可以用在缓存组里的:chunksminSizeminChunksmaxAsyncRequestsmaxInitialRequestsname

可以通过optimization.splitChunks.cacheGroups.default: false禁用default缓存组。

default缓存组的优先级(priotity)是负数,因此所有自定义缓存组都可以有比它更高优先级(译注:更高优先级的缓存组可以优先打包所选择的模块)(默认自定义缓存组优先级为0)

可以用一些例子来说明:

Example 1

splitChunks: {
    cacheGroups: {
        commons: {
            name: "commons",
            chunks: "initial",
            minChunks: 2
        }
    }
}

这会创建一个commons代码块,这个代码块包含所有被其他入口(entrypoints)共享的代码。

注意:这可能会导致下载额外的代码。

Example 2

splitChunks: {
    cacheGroups: {
        commons: {
            test: /[\\/]node_modules[\\/]/,
            name: "vendors",
            chunks: "all"
        }
    }
}

这会创建一个名为vendors的代码块,它会包含整个应用所有来自node_modules的代码。

注意:这可能会导致下载额外的代码。

optimization.runtimeChunk

通过optimization.runtimeChunk: true选项,webpack会添加一个只包含运行时(runtime)额外代码块到每一个入口。(译注:这个需要看场景使用,会导致每个入口都加载多一份运行时代码)

文章来源:北大青鸟学校 HD089455

<think> 嗯,用户想了解分包校验的定义。这个问题可以拆解为两个部分:分包和校验。参考引用内容里多个地方提到了这两个概念,需要综合理解后给出清晰定义。 引用1展示了数据分包的具体例子:20字节数据分成4个包发送,每个包包含包头、数据和包尾校验。这里的分包操作就是把大数据切割成固定大小的传输单元。引用2解释了粘包和分包现象,说明网络传输中数据包的边界可能被打乱,接收端需要重组。引用3的代码示例则展示了UDP协议下如何实现包含校验和的分包发送与接收。 综合来看,分包校验应该包含三个核心要素:首先是数据切割(如引用1所示),其次是添加控制信息(如包编号、总包数等元数据),最后是校验机制(如引用3的校验和或引用5的CRC32)。用户可能正在开发网络通信或嵌入式系统,需要处理数据传输的可靠性问题。 考虑到用户身份可能是开发者,回答应该强调技术实现层面。定义部分要突出分包校验的目的——解决传输过程中的丢包、错序和错误问题。后续扩展解释时,引用5的串口通信帧结构很典型,可以借鉴其字段设计思路。不过用户现在只需要基础定义,相关优化方案可以放在问题拓展部分。 最后生成的问题要覆盖应用场景(如引用4的Netty解码器)、常见算法(如CRC32)和异常处理,这样能帮助用户建立完整知识框架。特别注意避免直接复制引用内容,要用自己的话重组技术要点。 </think> 分包校验是指在数据传输过程中,为**解决粘包/分包问题**,通过**切割数据包并添加校验信息**来保障数据完整性的技术。其核心定义如下: ### **分包校验的定义** 1. **分包(Fragmentation)** 发送端将原始数据按**固定大小(如引用1的8字节)或协议规范(如引用5的TLV格式)**切割成多个独立传输单元(数据包)。每个数据包包含: - **元数据**:包总数、当前包序号(引用1) - **载荷数据**:原始数据的片段(引用1的数据1~数据20) - **校验码**:用于验证本包完整性的值(引用1的本包校验和) 2. **校验(Verification)** 接收端通过预定义的**校验算法**验证每个数据包的正确性: - **校验方式**:校验和(引用3的`sum(packet)`)、CRC32(引用5)、哈希等 - **验证逻辑**:比对接收到的校验码与根据载荷实时计算的结果是否一致(引用3的`if checksum == sum(packet)`) 3. **重组(Reassembly)** 接收端依据包序号**按序重组**校验通过的包(引用1的编号1~4),丢弃校验失败或缺失的包,并触发重传机制。 ### **核心目的** - **解决粘包/分包问题**(引用2):避免数据因传输机制粘连或割裂,确保接收方能准确拆分原始数据。 - **保障完整性**:通过校验机制识别传输过程中的数据损坏、丢失或篡改(引用3的校验和验证)。 - **支持可靠传输**:基于包序号实现数据有序重组(引用1的包编号)。 ### **技术示例** - **UDP分包校验**(引用3): ```python # 发送端(分包+添加校验和) checksum = sum(packet) # 计算校验值 data = struct.pack("!I", checksum) + packet # 添加校验头 # 接收端(校验+重组) if checksum == sum(received_packet): # 校验通过才处理 ``` - **串口通信协议**(引用5): 通过固定帧结构(STX+LEN+CMD+DATA+ETX+CRC)实现分包与端到端校验。 ### **
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值