You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中用@milkdown/preset-gfm解析序列化Markdown并结合Yjs存盘

解决Yjs + Milkdown GFM格式文档本地存储问题

核心问题分析

你代码里的几个关键错误:

  • 手动创建的空Schema无法处理任何节点和标记,必须用@milkdown/preset-gfm提供的完整schema
  • ParserState和SerializerState初始化参数错误,需要构建完整的unified处理器链,而非单独传入remarkGFM
  • 转换YDoc与Prosemirror节点时,未指定正确的Yjs文档默认字段

修正后的可运行代码

import remarkGFM from 'remark-gfm';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
import { unified } from 'unified';
import { ParserState, SerializerState } from '@milkdown/transformer';
import { schema } from '@milkdown/preset-gfm';
import * as Y from 'yjs';
import { prosemirrorToYDoc, yDocToProsemirror } from 'y-prosemirror';

// 构建支持GFM的Markdown解析/序列化处理器
const parseProcessor = unified()
  .use(remarkParse)
  .use(remarkGFM);

const stringifyProcessor = unified()
  .use(remarkStringify)
  .use(remarkGFM);

// 使用Milkdown GFM预设的完整schema初始化解析器和序列化器
const parser = ParserState.create(schema, parseProcessor);
const serializer = SerializerState.create(schema, stringifyProcessor);

// YDoc转GFM格式字符串
export function yDocToGFM(doc: Y.Doc): string {
  const prosemirrorNode = yDocToProsemirror(schema, doc);
  return serializer(prosemirrorNode);
}

// GFM格式字符串转YDoc
export function gfmToYDoc(mdContent: string): Y.Doc {
  const prosemirrorNode = parser(mdContent);
  return prosemirrorToYDoc(prosemirrorNode);
}

关键说明

  • 必须引入remark-parse和remark-stringify完成Markdown的解析与序列化全流程,remarkGFM仅负责扩展语法支持
  • 全程使用@milkdown/preset-gfm提供的schema,保证Yjs、Milkdown、Prosemirror三者的节点结构一致
  • Yjs与Prosemirror的转换默认使用prosemirror作为文档字段,无需额外配置

内容的提问来源于stack exchange,提问作者Navanshu Rastogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 12:59:14