Skip to content
雲里
里雾

remark transformer 中 file.value 修改是 no-op

astro 开发 更新于 2026/3/23

在 remark transformer 函数中,修改 file.value(raw Markdown 字符串)不会影响输出,因为 AST 已在 parser 阶段建立完毕。

原因

unified 的处理流水线分三个阶段:

parse(raw text → AST)→ transform(AST 操作)→ stringify(AST → 输出)

transformer 函数在 transform 阶段运行,此时 AST 已经从 file.value 解析完成。修改 file.value 不会触发重新解析,stringify 阶段直接从 AST 生成输出,file.value 的改动完全被忽略。

错误示例

// ❌ 这是 no-op:transformer 阶段修改 file.value 无效
export function remarkObsidianComments() {
  return (tree: any, file: any) => {
    // 这行不会影响任何输出
    file.value = file.value.replace(/%%[\s\S]*?%%/g, "");

    // 需要操作 AST,而不是 raw text
  };
}

正确做法

在 transformer 中直接操作 AST 节点:

// ✅ 操作 AST text 节点
import { visit } from "unist-util-visit";

export function remarkObsidianComments() {
  return (tree: any) => {
    visit(tree, "text", (node: any) => {
      node.value = node.value.replace(/%%[\s\S]*?%%/g, "");
    });
    // 清除变为空的 paragraph 节点
    visit(tree, "paragraph", (node: any, index, parent) => {
      if (!parent || index == null) return;
      const hasContent = node.children.some(
        (c: any) => c.type !== "text" || c.value.trim() !== ""
      );
      if (!hasContent) { parent.children.splice(index, 1); return index; }
    });
  };
}

参见

参考