
Rolldown 死代码消除与 Tree Shaking 能力全景基于 esbuild 兼容性测试套件的分析【免费下载链接】rolldownFast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.项目地址: https://gitcode.com/GitHub_Trending/ro/rolldown导读dce.md是 Rolldown 仓库中 esbuild 兼容性测试snap-diff在死代码消除DCE / Dead Code Elimination与 Tree Shaking维度上的执行结果摘要它按Failed Cases、Passed Cases、Ignored Cases三类逐条记录了 Rolldown 与 esbuild 在 DCE 行为上的对齐程度。本文以该摘要为骨架结合 crates/rolldown/tests/esbuild/dce/ 下的真实测试夹具、diff.md 差异快照以及 reasons.ts 中的原因标注系统梳理 Rolldown 当前在 DCE 领域已覆盖的能力、已知的次优实现与主动忽略的行为边界。读完本文你将能够快速定位 Rolldown 在 tree shaking、常量折叠、sideEffects处理、__PURE__注释等场景下的现状并理解这套 esbuild 兼容性测试的运作方式。摘要文档在测试体系中的位置dce.md位于 scripts/src/esbuild-tests/snap-diff/summary/与default.md、loader.md、packagejson.md、splitting.md、ts.md等并列是 snap-diff 流程按测试分类生成的多个维度摘要之一。该目录下还有stats/stats.md汇总统计diff.ts、snap-parser.ts、runner.ts、download-snapshots.ts、rewrite.ts等负责下载 esbuild 快照、解析产物、生成差异与摘要的脚本gen-tests.ts生成测试用例reasons.ts集中登记“失败原因”“不支持原因”“忽略原因”三张映射表。每一份摘要的结构都由reasons.ts中的三张表驱动命中failedReasons的用例归入Failed Cases命中ignoreReasons的归入Ignored Cases其余进入Passed Cases。因此本文解读的dce.md本质上是“esbuild 官方 DCE 测试集在 Rolldown 上的行为快照”其背后有大量可直接查阅的 diff 与配置证据。Failed Cases当前未对齐的 4 个用例摘要文档共记录了 4 个失败用例失败原因分为“上游依赖oxc待修复”与“Rolldown 自身次优实现”两类全部指向dce/目录下的对应夹具。dce_of_iifeIIFE 未解包摘要crates/rolldown/tests/esbuild/dce/dce_of_iife/diff.md原因标注https://github.com/oxc-project/oxc/issues/17480 and sub optimal: IIFEs are not unwrapped in some cases该用例通过 _config.json 声明两个入口remove-these.js与keep-these.js用于验证无副作用的立即执行函数表达式IIFE应当被整体移除。从diff.md的差异快照可以看到具体分歧esbuild 将keepMe();一条独立调用语句原样保留而 Rolldown 将其输出为(() { keepMe(); })();对于var keepThis stuff(); keepThis();esbuild 保留为两条语句Rolldown 则折叠为(() stuff())()();该用例同时验证了/* __PURE__ */标注的调用可被移除、带默认参数的箭头函数不可移除等语义Rolldown 在这些点上与 esbuild 一致。结论是Rolldown 在部分场景下不会把 IIFE“解包”为裸语句导致输出体积略大于 esbuild属于次优实现sub optimal其修复还部分受制于 oxc 项目的 issue 17480。tree_shaking_lowered_class_static_field降级后的类静态字段可被进一步移除摘要目录crates/rolldown/tests/esbuild/dce/tree_shaking_lowered_class_static_field/原因标注sub optimal: REMOVE_ME class can be removed当类静态字段被降级lowering为赋值语句后本应有机会连同其声明一起被 tree shaking 移除测试中以REMOVE_ME命名该类。Rolldown 目前仍保留该类说明在“降级产物再参与 DCE”这一链路上的优化深度还不及 esbuild。值得一提的是同族用例tree_shaking_lowered_class_static_field_assignment与tree_shaking_lowered_class_static_field_minified已进入 Passed 列表说明该族能力已部分覆盖。tree_shaking_react_elementsReact.Fragment 未被移除摘要目录crates/rolldown/tests/esbuild/dce/tree_shaking_react_elements/原因标注sub optimal: React.Fragment should be removed该用例考察 JSX 转换后产生的React.Fragment引用是否能在未被使用时被消除。当前 Rolldown 会将其保留属于可优化的空间与 oxc 的 JSX 转换/常量折叠能力相关。tree_shaking_unary_operators一元运算符场景被拒绝摘要目录crates/rolldown/tests/esbuild/dce/tree_shaking_unary_operators/原因标注rejected due to https://github.com/rolldown/rolldown/issues/7009该用例涉及with语句相关语义issue 7009 是with语句被拒绝的登记项同样的原因也出现在default/comment_preservation、ts/ts_print_non_finite_number_inside_with等用例上。属于主动拒绝而非实现缺陷详见下文“Ignored Cases”一节对拒绝机制的说明。Passed Cases已对齐的能力版图通过用例是摘要的主体约 90 个展示了 Rolldown 在 DCE 领域已具备的广度。按技术主题归纳如下。loader 产物中的未使用移除base64_loader_remove_unusedbase64 加载的资源未使用时被移除data_url_loader_remove_unuseddata URL 资源同理file_loader_remove_unused文件加载资源同理json_loader_remove_unusedJSON 加载结果未使用时被移除text_loader_remove_unused文本加载资源同理。这些用例共同验证无论资源以何种 loader 内联进包只要其导出未被消费就能被整段剔除。跨模块常量折叠与常量值内联cross_module_constant_folding_number、cross_module_constant_folding_string、cross_module_constant_folding_computed_property_name跨模块的const常量在编译期完成折叠包括计算属性名场景const_value_inlining_bundle、const_value_inlining_no_bundle、const_value_inlining_direct_eval常量值内联的三种形态——打包、不打包以及存在直接eval内联需谨慎的场景。typeof相关的守卫条件消除dce_type_of家族覆盖了typeof与字符串常量比较后的分支消除包括dce_type_of基础形态dce_type_of_equals_string、dce_type_of_equals_string_guard_condition、dce_type_of_equals_string_mangletypeof x string形式的守卫条件消除以及标识符压缩mangle后的表现dce_type_of_compare_string_guard_condition比较式守卫条件。package.json的sideEffects语义这是通过用例中最庞大的族群约 30 个覆盖三种取值形态sideEffects: false整包视为无副作用。代表性用例包括 package_json_side_effects_false_remove_bare_import_es6、package_json_side_effects_false_remove_bare_import_common_js裸导入被移除、package_json_side_effects_false_keep_named_import_es6、package_json_side_effects_false_keep_star_import_es6具名/星号导入被保留还包括中间文件链chain/diamond/unused/used四种拓扑package_json_side_effects_false_intermediate_files_chain_all 等以及跨平台路径分隔符package_json_side_effects_false_cross_platform_slash和 node_modules 内免警告package_json_side_effects_false_no_warning_in_node_modules_issue999。sideEffects: [*.css, ...]数组 globpackage_json_side_effects_array_glob 验证 glob 匹配package_json_side_effects_array_remove 与 package_json_side_effects_array_keep 验证按 main/module 字段命中的保留与移除组合。sideEffects: truepackage_json_side_effects_true_keep_es6、package_json_side_effects_true_keep_common_js 验证默认全保留。此外还有 package_json_side_effects_keep_export_default_expr、package_json_side_effects_nested_directory_remove 等边界用例说明这套sideEffects语义已被系统性地对齐。纯注释/* __PURE__ */与// __PURE__no_side_effects_comment 是 DCE 目录下夹具最多的用例之一通过 多条输入文件 覆盖函数声明/箭头函数/导出默认函数等十余种放置形态。同族用例包括no_side_effects_comment_ignore_annotationsignoreAnnotations开关no_side_effects_comment_minify_whitespace压缩空格后注释仍生效no_side_effects_comment_type_script_declareTSdeclare场景no_side_effects_comment_unused_calls未使用调用的移除。配套的 remove_unused_pure_comment_calls、pure_calls_with_spread 与 inline_empty_function_calls 则验证了更细的纯调用与空函数调用处理。语法降级与压缩下的 DCEdce_class_static_blocks 与 dce_class_static_blocks_minify_syntax类静态块及其压缩形态dce_of_using_declarationsusing声明dce_of_decorators 与 dce_of_experimental_decorators两种装饰器语法dce_of_destructuring解构dce_of_negated_bigints取负的 BigInt 字面量折叠dce_template_literal模板字符串折叠multiple_declaration_tree_shaking 与 multiple_declaration_tree_shaking_minify_syntax多重声明消除preserve_directives_minify_bundle、preserve_directives_minify_iife、preserve_directives_minify_pass_through压缩时对指令directive的保留策略。控制流与死代码dead_code_following_jump跳转后的死代码dead_code_inside_empty_try空 try 块内的死代码remove_code_after_label_with_return 与 drop_label_tree_shaking_bug_issue3311带标签语句drop_labels标签消除remove_trailing_return尾部return消除tree_shaking_binary_operators二元运算常量折叠。函数内联inline_identity_function_calls、inline_function_call_behavior_changes、inline_function_call_for_init_decl、nested_function_inlining_with_spread、top_level_function_inlining_with_spread 共同验证了空函数、恒等函数在init声明、嵌套、spread参数等形态下的内联与行为保持。Symbol、import 与导出dce_of_symbol_ctor_call、dce_of_symbol_for_call、dce_of_symbol_instancesSymbol相关调用语义dce_var_exports、dce_of_expr_after_keep_names_issue3195、dce_of_iterator_superclass_issue4310与已知 issue 关联的边界行为import_re_export_of_namespace_import、tree_shaking_import_identifier、tree_shaking_in_esm_wrapper导入标识符与命名空间再导出remove_unused_imports 与 remove_unused_imports_eval、remove_unused_imports_eval_ts未使用 import 的移除以及存在eval时的保守行为remove_unused_import_metaimport.meta未使用时移除tree_shaking_no_bundle_cjs、tree_shaking_no_bundle_esm、tree_shaking_no_bundle_iife三种输出格式下“不打 bundle”时的 tree shakingtree_shaking_object_property、tree_shaking_class_property、tree_shaking_class_static_property对象属性、类实例属性与静态属性的摇树disable_tree_shaking显式关闭 tree shaking 时的行为。从测试夹具的 _config.json 可以看到每个用例通过input数组声明入口部分用例带expectExecuted: false标记表示该用例不要求运行时执行只比对静态产物这套元数据直接驱动快照对比流程。Ignored Cases主动忽略与暂不支持的行为摘要末尾的 Ignored Cases 分两段普通忽略与“not supported”忽略两者在 reasons.ts 中分别由ignoreReasons与notSupportedReasons登记。对齐 esbuild 的“hacky”行为普通忽略package_json_side_effects_array_keep_main_implicit_main、package_json_side_effects_array_keep_module_implicit_main、package_json_side_effects_array_keep_module_use_main原因标注为 “this is a hacky behavior of esbuild”esbuild 的取巧行为Rolldown 选择不模仿remove_unused_no_side_effects_tagged_templates涉及 compiler-notations-spec__NO_SIDE_EFFECTS__规范草案的 issue 8规范尚未定稿故忽略。因 CSS 打包能力缺失而忽略tree_shaking_js_with_associated_css及其 6 个变体export_star_side_effects_false、re_export_side_effects_false、unused_nested_import_side_effects_false及各自的_only_js版本全部以 “CSS bundling is not supported”issue 4271为原因被忽略。这属于明确的能力边界而非缺陷JS 的 tree shaking 逻辑本身不受影响只是“JS 关联 CSS”的整体场景暂不在覆盖范围内。明确不支持的场景not supported摘要末尾单列了 dead_code_inside_unused_cases原因标注为 “dce inside unused switch cases is not supported”即未命中的switch分支内部的死代码消除暂不支持与reasons.ts中notSupportedReasons的登记一一对应。如何进一步查看差异细节当某个用例进入 Failed Cases 时其对应目录内通常包含diff.md可直接查看 esbuild 与 Rolldown 产物的逐行差异。以 dce_of_iife/diff.md 为例其结构为三段### esbuildesbuild 的产物代码块### rolldownRolldown 的产物代码块并带#region注释标注模块边界### diff统一 diff 格式的逐行对比--- esbuild与 rolldown。这使得任何差异都能被精确归因到具体语法构造也为后续优化提供了最小复现单元。Passed Cases 的目录同样保留_config.json与artifacts.snap可作为回归测试的基线快照。小结从dce.md这份摘要可以得出 Rolldown 在 DCE 领域的整体画像广度已相当可观loader 产物移除、跨模块常量折叠、typeof守卫消除、sideEffects三种形态false / 数组 glob / true、__PURE__注释、类静态块、装饰器、using、Symbol 调用、函数内联、多格式 no-bundle 摇树等均已有通过用例佐证剩余差距集中在“次优实现”而非功能缺失IIFE 未解包、降级类静态字段未再摇掉、React.Fragment未移除都属于可进一步压缩输出体积的优化空间行为边界清晰且显式登记esbuild 的 hacky 行为、CSS 打包缺失、未命中 switch 分支内的 DCE均在 reasons.ts 中留下原因便于后续按 issue 跟踪。对于希望为 Rolldown 贡献 DCE 相关优化、或评估其 tree shaking 能力的读者建议从本文列出的 4 个 Failed Cases 的diff.md入手它们既是差距清单也是可直接运行的回归夹具。【免费下载链接】rolldownFast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.项目地址: https://gitcode.com/GitHub_Trending/ro/rolldown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考