DEBUG.WIKI
丽萨主机;为跨境业务选好 IP;原生 / 住宅 IP · 按套餐选择;查看 IP →
PanstarCloud:部署应用,接入 AI,云服务器与 AI 网关
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证

yaml 把显式字符串键 << 仍当成合并指令

yaml 2.9.1 开启 merge 后,!!str << 仍可能合并对象或抛 Merge sources must be maps or map aliases。字面键需核对节点样式与解析后的结构。

YAML 中明明写了 !!str <<: 5,npm 的 yaml 库仍抛出 Merge sources must be maps or map aliases;把值改成对象后,它又把对象里的键合并到了外层。这时需要检查是否开启了 merge,而不是只检查值是不是合法字符串。

yaml 2.9.1 在 merge: true 下有一条回退识别:只要键是 plain 样式的 Scalar、值为 <<,便可能被当成合并键。显式的 !!str 或非特定标签 ! 没有在这条路径中排除它。

字面 << 可以改为带引号的键

如果业务确实需要一个名为 << 的普通键,输入文本可以写成:

"<<":
  x: 1

读取时仍保留现有的 merge 选项:

import { parseDocument } from 'yaml';

const doc = parseDocument('"<<": { x: 1 }', { merge: true });
if (doc.errors.length > 0) throw doc.errors[0];
const value = doc.toJS();

value 应保留外层的 << 键,而不是只留下 x。这里修改的是键的语法样式,不需要删除值中的真实数据。若文件由其他工具生成,应在生成入口保持引号,避免下一次保存又还原为 plain 键。

不要对整份 YAML 做字符串替换;注释、字符串正文和真正的合并键都可能包含相同字符。通过 AST 修改时,还要核对 Scalar 的 type 和最终写出的文本,单独设置一个标签并不能避开当前的回退检查。

关闭 merge 会改变整份文档的继承结果

项目如果完全不使用 YAML merge,可以评估在对应解析入口关闭 merge。这个决定会让真正的 <<: *defaults 不再执行原来的合并,不适合只为一个字面键全局关闭。

混合使用配置继承和字面键时,优先改清具体键的表示。不要捕获错误后忽略该字段,也不要为了满足合并器把数字 5 包装成一个无关对象;那只会把原来的数据契约改掉。

正式 2.9.1 的 isMergeKey 仍未检查显式 tag。后续升级需要核对正式包的对应逻辑和回归结果,不能把“正在准备补丁”的状态写成已经修复。

验收至少覆盖带引号的字面键、真正的别名合并,以及相同文件中二者并存的情形。除了确认没有异常,还应比较生成对象的键和值、默认配置是否继续继承,避免从显式报错变成静默丢失字段。