尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

rolldown `jsx: “preserve“` 模式下的注释保留差异:`comment_preservation_preserve_jsx` 用例源码级剖析

rolldown `jsx: “preserve“` 模式下的注释保留差异:`comment_preservation_preserve_jsx` 用例源码级剖析 rolldownjsx: preserve模式下的注释保留差异comment_preservation_preserve_jsx用例源码级剖析【免费下载链接】rolldownFast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.项目地址: https://gitcode.com/GitHub_Trending/ro/rolldown本文围绕 rolldown 仓库中 esbuild 兼容性测试套件的comment_preservation_preserve_jsx用例展开以该用例的 diff 快照diff.md为主体结合测试配置、输入源码与快照生成机制剖析 rolldown 在transform.jsx preserve模式下对 JSX 注释的保留行为与 esbuild 的差异并解释这套 diff 快照是如何被自动化生成与维护的。读完本文你将理解该测试用例覆盖的每一种注释场景、差异产生的具体位置以及如何通过crates/rolldown/tests/esbuild/目录定位 rolldown 与 esbuild 的兼容性缺口。一、用例背景esbuild 兼容性测试与 diff 快照rolldown 以 Rollup 兼容 API 为目标同时也把 esbuild 的打包行为作为重要的对齐参照。仓库在 crates/rolldown/tests/esbuild/ 下维护了按 esbuild 官方 Go 测试源文件划分的测试套件default、dce、importstar、loader、ts、lower、splitting、glob等每个用例目录内通常包含输入源文件如entry.jsx_config.json测试配置artifacts.snaprolldown 构建产物的 insta 快照diff.mdesbuild 输出与 rolldown 输出的结构化 diff仅在两者不一致时生成。comment_preservation_preserve_jsx位于 crates/rolldown/tests/esbuild/default/属于default套件对应 esbuild 的bundler_default_test.go。该用例名本身就点明了主题在 JSX preserve不转译、原样保留模式下测试注释保留行为。diff.md的核心信息是在当前仓库的 rolldown 版本中JSX 内的注释并未被保留到输出而 esbuild 会保留——这是一个真实存在、被快照固定下来的兼容性差异。二、测试配置与输入_config.json与entry.jsx2.1 测试配置crates/rolldown/tests/esbuild/default/comment_preservation_preserve_jsx/_config.json 内容如下{ expectExecuted: false, config: { input: [ { name: entry, import: entry.jsx } ], transform: { jsx: preserve } } }关键字段解读config.input声明入口模块name为entryimport指向entry.jsx即打包入口为同一目录下的 entry.jsxconfig.transform.jsx值为preserve表示对 JSX 不做转译与transform模式相对。这也是本用例的核心变量——只有在 preserve 模式下JSX 才会以近似原样的形态进入输出注释差异才有讨论空间expectExecuted为false表示该用例不要求产物可执行仅验证打包输出形态。从测试生成脚本 scripts/src/esbuild-tests/gen-tests.ts 看这类_config.json并非手工编写脚本用 tree-sitter 解析 esbuild 的 Go 测试源文件如bundler_default_test.go提取每个TestXxx函数中的files、entryPaths等字段自动落盘为输入文件与配置。gen-tests.ts中processEntryPath会把 esbuild 的 entry path 转为{ name, import }形式的 input 条目并在缺少 entry 时回退到/*所有文件作为入口。换言之该用例的输入与配置源头是 esbuild 官方测试TestCommentPreservationPreserveJSX。2.2 输入源码覆盖五类注释场景entry.jsx 精心构造了多组 JSX 写法用以探测注释出现在不同 AST 节点位置时的保留情况console.log( div x{/*before*/x} /, div x{/*before*/y} /, div x{/*before*/true} /, div {/*before*/...x} /, div{/*before*/x}/div, {/*before*/x}/, // Comments on absent AST nodes divbefore{}after/div, divbefore{/* comment 1 *//* comment 2 */}after/div, divbefore{ // comment 1 // comment 2 }after/div, before{}after/, before{/* comment 1 *//* comment 2 */}after/, before{ // comment 1 // comment 2 }after/, )可以将这些用例归纳为五类注释场景场景输入写法注释位置JSX 属性值注释x{/*before*/x}、x{/*before*/y}、x{/*before*/true}属性表达式容器{}内、表达式之前JSX 展开属性注释div {/*before*/...x} /展开属性spread attribute之前子元素表达式注释div{/*before*/x}/div、{/*before*/x}/子元素表达式容器内空表达式容器注释块注释divbefore{/* comment 1 *//* comment 2 */}after/div空{}内的连续块注释空表达式容器注释行注释divbefore{// comment 1 // comment 2}after/div空{}内的连续行注释其中倒数第二组// Comments on absent AST nodes之后的六行专门针对一种边界情况表达式容器{}内部没有任何表达式只有注释。此时注释没有可附着的表达式节点属于缺失 AST 节点上的注释最容易在解析与输出阶段被丢弃。用例同时覆盖了div与 Fragment.../两种容器以及块注释与行注释两种语法。三、diff 详解esbuild 保留、rolldown 移除diff.md 中并排给出了三方内容esbuild 输出、rolldown 输出、以及两者之间的 unified diff。这是理解差异的第一手材料。3.1 esbuild 的输出// entry.jsx console.log( div x{ /*before*/ x } /, ... // Comments on absent AST nodes divbefore{}after/div, divbefore{ /* comment 1 */ /* comment 2 */ }after/div, ... );esbuild 的输出保留了所有注释属性值前的/*before*/、展开属性前的/*before*/、子元素表达式前的/*before*/、空表达式容器内的块注释与行注释甚至包括输入中// Comments on absent AST nodes这行说明性注释。它只是把单引号字符串y规范化为双引号y并按自身风格换行排版。3.2 rolldown 的输出//#region entry.jsx console.log(div x{x} /, div x{y} /, div x{true} /, div {...x} /, div{x}/div, {x}/, divbefore{}after/div, divbefore{}after/div, divbefore{}after/div, before{}after/, before{}after/, before{}after/); //#endregionrolldown 的输出与 artifacts.snap 中的快照完全一致把所有 JSX 合并为一行所有注释均被移除x{/*before*/x}→x{x}{/*before*/...x}→{...x}{/*before*/x}→{x}六处absent AST nodes场景全部退化为before{}after块注释、行注释均消失输入中// Comments on absent AST nodes这行注释也未保留。同时注意输出结构rolldown 用//#region entry.jsx///#endregion包裹了产物这与 esbuild 在输出顶部直接注释// entry.jsx的风格不同属于 rolldown 自身在 generate 阶段的模块标注约定也是 diff 中可见的格式差异之一。3.3 unified diff 解读diff.md第三部分的 diff 头信息--- esbuild /out/entry.jsx rolldown entry.jsx说明比较双方分别为 esbuild 的产物/out/entry.jsx与 rolldown 的产物entry.jsx。 -1,46 1,3 表示 esbuild 侧 46 行被替换为 rolldown 侧 3 行含 region 标记即注释保留差异叠加排版差异后的总体变化。diff 行内容与 3.1、3.2 两节一致不再赘述。四、差异根源推断preserve 模式下的注释附着diff.md本身只记录现象不解释原因。结合仓库源码结构可以做一些谨慎推断jsx: preserve意味着 rolldown 不调用 JSX 转译JSX 元素以 AST 形式原样通过各个阶段在 crates/rolldown/src/utils/pre_process_ecma_ast.rs 等 AST 预处理环节中注释的保留策略会影响最终产物从输出看rolldown 保留了x、y、true、...x等有实际意义的表达式丢掉的只是注释说明问题不在于表达式容器被删除而在于容器内的注释没有附着点。JSX 属性表达式x{...}与子元素表达式{...}在解析为 AST 后注释若不能挂到对应的属性值或表达式节点上就会在序列化时丢失输入中特意构造的absent AST nodes场景空{}中只有注释进一步印证了这一点{}内部没有任何子节点时块注释与行注释都无处安放最容易在 AST 重建/打印时被丢弃。需要强调的是这属于从快照与源码结构可以观察到的现状而非对设计意图的定论。diff 快照的价值恰恰在于把这种当前未对齐的行为显式固定下来供后续对齐 esbuild 行为时回归验证。五、快照与 diff 的自动化生成机制理解这套 diff 快照如何产生有助于判断其可信度与维护方式。测试用例生成scripts/src/esbuild-tests/gen-tests.ts 通过 tree-sitter 解析 esbuild 官方 Go 测试源suites表将default映射到bundler_default_test.go用自定义 Query 抓取TestXxx函数中的文件内容与 entry path生成输入文件和_config.json。用例名由 Go 函数名去掉Test前缀后转 snake_case 得到comment_preservation_preserve_jsx即对应 esbuild 的TestCommentPreservationPreserveJSX产物快照rolldown 构建结果由 insta 机制记录在artifacts.snap其中source字段注明生成来源为 crates/rolldown_testing/src/integration_test.rs即测试框架以集成测试方式驱动打包并固定产物diff 快照生成scripts/src/esbuild-tests/snap-diff/diff.ts 中的diffCase函数负责比对先用defaultResolveFunction把 esbuild 产物名如/out/entry.jsx映射到 rolldown 产物名再做内容改写rewriteEsbuild/rewriteRolldown最后用diff.structuredPatch生成结构化 patch仅当 hunk 非空时才写入 diff 列表。也就是说diff.md的存在本身就意味着该用例 esbuild 与 rolldown 输出不一致若两者一致diffCase 会返回same不会产出 diff 文件过滤机制diff 生成支持通过用例目录下的diff.config.js提供rewrite与resolver自定义规则用于处理文件名映射等差异但本用例目录下并未放置该文件说明comment_preservation_preserve_jsx的比对走的是默认规则。这套输入 配置 产物快照 diff 快照四件套的布局让任何开发者都能在一个目录内复现差异、定位原因并在修复后通过更新快照来确认对齐结果。六、从该用例可以得出的实践结论jsx preserve 模式下注释保留是兼容性指标之一若你的项目依赖 JSX 中的注释例如在属性表达式旁书写说明性注释或在空{}中保留标记切换到 rolldown 当前版本时这些注释不会出现在产物中注释保留与转译无关即使不做 JSX 转译preserve注释仍可能在 AST 往返过程中丢失说明问题出在注释附着机制而非转译器diff 快照是跟踪兼容性缺口的有效手段diff.md的存在即未对齐的信号修复后应同步更新 artifacts.snap 与该用例目录下的快照文件使差异状态保持可见、可回归。七、延伸阅读测试套件总览crates/rolldown/tests/esbuild/default、dce、importstar、ts、loader等子目录同类 JSX preserve 用例loader/jsx_preserve_capital_letter、default/mangle_props_jsx_preserve等见crates/rolldown/tests/esbuild/下各套件的_config.json差异快照生成器scripts/src/esbuild-tests/snap-diff/diff.ts测试用例生成器scripts/src/esbuild-tests/gen-tests.ts集成测试驱动crates/rolldown_testing/src/integration_test.rs总体而言comment_preservation_preserve_jsx是一个小而精准的兼容性探针它以 esbuild 官方测试为蓝本用五类 JSX 注释场景量化了 rolldown 在 preserve 模式下注释保留的现状。对于关注 rolldown 与 esbuild 行为对齐进度的开发者这是一个可以直接复现、对照与跟踪的典型样本。【免费下载链接】rolldownFast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.项目地址: https://gitcode.com/GitHub_Trending/ro/rolldown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表