Rspack 支持摇树优化,这个术语在 JavaScript 生态系统中被广泛使用,指的是删除未使用的代码,通常被称为“死代码”。当模块中的某些导出没有被使用,并且它们没有副作用时,就会出现死代码,这种情况下可以安全地删除这些代码,以减少最终的输出大小。
在将 mode 设置为 production 后,Rspack 默认情况下会启用一系列与摇树优化相关的优化,包括
以下是一些示例,说明这些配置选项如何工作。
请注意,Rspack 不会直接删除死代码,而是将未使用的导出标记为潜在的“死代码”。这些标签可以被后续的压缩工具识别和处理。因此,如果关闭了压缩功能,则不会观察到实际的代码删除。为了提高可读性,可能会使用伪代码来演示代码删除的效果。
让我们通过一个示例来更好地理解这种机制,假设 src/main.js 是项目的入口点
在这个示例中,util.js 中的 bar 未使用。在 production 模式下,Rspack 默认情况下会启用 usedExports 优化,检测哪些导出被积极使用。未使用的导出,比如 bar,会被安全地删除。最终的输出将类似于
在 production 模式下,Rspack 通常还会分析模块是否有副作用。如果模块中的所有导出都没有被使用,并且模块没有副作用,那么整个模块就可以被删除。让我们稍微修改一下之前的示例
在这种情况下,util.js 中的导出都没有被使用,并且它被分析为没有副作用,允许删除整个 util.js。
您可以通过 package.json 或 module.rules 手动指定模块是否保留副作用。有关如何操作的信息,请参阅 sideEffects。
重新导出在开发中很常见。但是,一个模块可能会引入许多其他模块,而实际上可能只需要其中一部分。Rspack 通过确保引用方可以直接访问实际导出的模块来优化这种情况。考虑以下涉及重新导出的示例
Rspack 默认情况下会启用 providedExports,它可以分析重新导出模块的所有导出并识别其各自的来源。
如果 src/re-exports.js 没有副作用,Rspack 可以将 src/main.js 中的导入从 src/re-exports.js 直接转换为从 src/value.js 的导入,实际上
这种方法的好处是完全忽略了 src/re-exports.js 模块。
通过能够分析 src/re-exports.js 中的所有重新导出,可以确定 src/value.js 中的 foo 没有被使用,并且将在最终输出中被删除。
在某些情况下,即使访问了导出,它们也可能没有实际使用。例如
在上述情况下,即使 log 函数和变量 bar 依赖于 foo,由于两者都没有被使用,foo 仍然可以被认为是死代码,并被删除。
在启用 innerGraph 优化(在 production 模式下默认启用)后,对于复杂的跨模块情况,Rspack 保持了追踪变量使用情况的能力,从而实现了精确的代码优化。
在这种情况下,由于 value 最终被使用,它依赖的 foo 被保留。