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

Next.js13中用GFM扩展转MD到MDAST树时出现inTable错误

解决Next.js 13中mdast-util-from-markdown结合GFM扩展的报错问题

问题概况

在Next.js 13项目中,尝试通过mdast-util-from-markdown搭配GFM扩展将.md文件转换为MDAST树(JSON格式)时,出现两个问题:

  • VSCode中提示TypeScript错误
  • 浏览器端Next.js抛出Cannot set properties of undefined (setting 'inTable')异常

移除fromMarkdown的扩展配置后,普通Markdown可正常转换,但GFM语法(如表格、任务列表等)无法被识别。

报错原因

代码中对fromMarkdown的参数传递存在错误:
fromMarkdown的函数签名为fromMarkdown(value: string, options?: Options),第二个参数应为配置选项对象,但你额外传入了'utf8'作为第二个参数,导致配置选项被挤到第三个参数,GFM扩展的初始化逻辑无法正确读取配置,进而引发内部状态(如inTable所属的上下文)未被正确创建的错误。

同时,原代码直接将包含frontmatter的完整文件内容传入fromMarkdown,会导致frontmatter部分被错误转换。

解决方案

  1. 移除多余的'utf8'参数,因为fs.readFileSync已经以utf8编码读取了文件内容,fromMarkdown接收的是字符串类型,无需重复指定编码。
  2. 将matterResult.content(仅文章主体内容)传入fromMarkdown,避免转换frontmatter部分。
  3. 引入MDAST的Root类型,替换any以获得正确的TypeScript类型提示。

修正后的完整代码

"use server"
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { fromMarkdown } from "mdast-util-from-markdown"
import { gfm } from 'micromark-extension-gfm'
import { gfmFromMarkdown, gfmToMarkdown } from 'mdast-util-gfm'
import type { Root } from 'mdast'

const postsDirectory = path.join(process.cwd(), 'blogposts');

type BlogPost = {
  id: string;
  title: string;
  date: string;
  published: string;
}

export async function getPostDataToEdit(id: string) {
  const fullPath = path.join(postsDirectory, `${id}.md`);
  const fileContents = fs.readFileSync(fullPath, 'utf8');
  const matterResult = matter(fileContents);

  const tree: Root = fromMarkdown(matterResult.content, {
    extensions: [gfm()],
    mdastExtensions: [gfmFromMarkdown()]
  })

  const blogPost: BlogPost & { body: Root } = {
    id,
    title: matterResult.data.title,
    date: matterResult.data.date,
    published: matterResult.data.published ? "Published" : "Draft",
    body: tree,
  }

  return blogPost;
}

额外说明

  • 替换fileContents为matterResult.content后,只会转换Markdown文章的主体部分,frontmatter将由gray-matter单独处理,符合预期逻辑。
  • 使用Root类型代替any,可以在开发过程中获得更准确的类型检查和代码提示,减少潜在的TypeScript错误。

内容的提问来源于stack exchange,提问作者Nicolás Jorge Vera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:33:30