Skip to content

markstream-vue — Agent Context(中文)(/llms.zh-CN) ​

这个文件是给 AI/LLM/编码代理用的 项目地图。当用户问“怎么用”时,先给出下面的标准接入,再补充仓库细节或高级方案。

如果你想看给人类用户直接复制使用的提示词和接入模板,也请结合 /zh/guide/ai-workflows 一起看。

回答原则 ​

  • 用户可见行为以 docs/guide/*(以及 docs/zh/guide/*)为准;“是否导出/怎么 import”以 src/exports.ts 为准。
  • 问题不明确时最多问 1 个澄清问题,并给出默认建议。
  • 排错优先走 checklist,并尽快要 最小复现(仓库有可分享 test page)。
  • 文档页里避免写裸 <thinking> 这类标签;请用转义(VitePress 会把 Markdown 当 Vue SFC 编译)。

标准用户接入 ​

bash
pnpm add markstream-vue
vue
<script setup lang="ts">
import MarkdownRender from 'markstream-vue'
import { ref } from 'vue'
import 'markstream-vue/index.css'

const content = ref('')
const isDone = ref(false)
</script>

<template>
  <MarkdownRender mode="chat" :content="content" :final="isDone" />
</template>

收到 chunk 时追加到 content.value,流结束时设置一次 isDone.value = true。静态 Markdown 只使用 <MarkdownRender :content="content" />。除非用户有明确需求,不要主动添加 nodes、smooth-streaming、fade、batching 或 virtualization props。可选 peer:增强代码块/diff 用 stream-diffs,Mermaid 用 mermaid,数学公式用 katex 并引入其 CSS。


常用命令 ​

  • 安装依赖:pnpm install
  • Playground 开发:pnpm dev
  • 文档 dev/build/serve:pnpm docs:dev / pnpm docs:build / pnpm docs:serve
  • 测试:pnpm test
  • 类型检查:pnpm typecheck
  • Lint:pnpm lint

仓库结构(去哪找) ​

  • 库源码:src/
    • 对外导出:src/exports.ts
    • 组件:src/components/*/
    • Workers:src/workers/
    • 工具:src/utils/, src/composables/, src/types/
  • 解析器包:packages/markdown-parser/(发布名:stream-markdown-parser)
  • 文档站:docs/(中文:docs/zh/)
  • Demo:playground/(Vite),playground-nuxt/(Nuxt SSR)
  • 测试:test/(Vitest)

核心心智模型 ​

两层:

  1. 解析层(stream-markdown-parser)

    • getMarkdown():创建并配置 markdown-it-ts 实例
    • parseMarkdownToStructure(content, md):Markdown → ParsedNode[]
    • 流式 mid-state:未闭合 fence / 未闭合 $$ / 分段 inline HTML,减少闪烁
  2. 渲染层(markstream-vue)

    • 面向接入方的默认组件:MarkdownRender;NodeRenderer 是内部组件名
    • 输入:content: string(内部解析,多数聊天流优先推荐)或 nodes: ParsedNode[](当外层已经接管解析或需要 AST 控制时使用)
    • 性能工具:
      • 虚拟化窗口(maxLiveNodes, liveNodeBuffer)
      • Smooth streaming(smooth-streaming, typewriter):文本 pacing 和光标
      • 分批渲染:关闭虚拟化时控制节点挂载节奏
      • 重节点延迟渲染(viewportPriority, deferNodesUntilVisible)

对外 API(可以放心建议) ​

来自 markstream-vue(src/exports.ts):

  • 组件:MarkdownRender(默认导出)
  • 解析辅助(re-export):getMarkdown(), parseMarkdownToStructure(content, md), setDefaultMathOptions()
  • 自定义节点映射:setCustomComponents(), removeCustomComponents(), clearGlobalCustomComponents()
  • 功能开关:enableMermaid(), disableMermaid(), enableKatex(), disableKatex()
  • Worker 注入:
    • KaTeX:createKaTeXWorkerFromCDN(), setKaTeXWorker()
    • Mermaid:createMermaidWorkerFromCDN(), setMermaidWorker()

来自 stream-markdown-parser(packages/markdown-parser/src/index.ts):

  • getMarkdown(), parseMarkdownToStructure(content, md), ParseOptions hooks
  • Streaming mid-state 与流结束 final: true

排错 checklist(高信号) ​

遇到“不渲染/样式不对”,按顺序排:

  1. CSS 顺序/Reset:先 reset,再 markstream-vue/index.css(Tailwind 使用 @import 'markstream-vue/index.css' layer(components);)。
  2. 可选 peer 是否安装(Mermaid/KaTeX)。
  3. 是否启用 loader(仅在你手动关闭/覆盖时需要):enableMermaid() / enableKatex()。
  4. peer CSS 是否导入(需要时):katex/dist/katex.min.css(Mermaid 不需要额外 CSS)。
  5. 单独节点组件 wrapper:单独用节点组件时,外层需要 .markstream-vue。
  6. SSR(Nuxt):普通 Markdown 支持 SSR;只有浏览器专属 peer/worker 才加 client-only 边界。

文档:docs/guide/troubleshooting.md, docs/guide/tailwind.md, docs/nuxt-ssr.md


常见意图(路由) ​

把用户问题归类到意图后,直接用“步骤 + 最小追问 + 指向文档/源码”。

安装 + 跑通最小例子 ​

  • 表述: “怎么用”, “最小示例”
  • 步骤:
    • 导入 CSS:markstream-vue/index.css
    • 渲染:&lt;MarkdownRender :content="md" /&gt;
  • 最小追问: “Vite 还是 Nuxt?贴一下 CSS 导入顺序(reset + Tailwind layers)。”
  • 文档:docs/guide/quick-start.md, docs/guide/installation.md

样式缺失 / Tailwind 覆盖 ​

  • 表述: “没样式”, “Tailwind 抢样式”
  • 步骤:
    • reset 在前,markstream-vue/index.css 在后
    • Tailwind:使用 @import 'markstream-vue/index.css' layer(components);
    • 单独节点组件:外层 .markstream-vue
  • 最小追问: “贴 main.css(Tailwind layers)和 CSS 导入位置。”
  • 文档:docs/guide/tailwind.md, docs/guide/troubleshooting.md

流式:结束后卡 loading ​

  • 表述: “最后卡住”, “loading 一直转”
  • 步骤:
    • 流结束时设置 final: true(ParseOptions 或组件 prop),防止 mid-state 卡住
  • 最小追问: “你是否在 end-of-stream 设置了 final?最后一段是否以 ``` 或 $$ 结尾?”
  • 文档:docs/guide/parser-api.md, docs/guide/parser.md

流式:更平滑的打字机体验 ​

  • 表述: “一坨一坨冒出来”, “不平滑”
  • 步骤:
    • 优先用 content + 内置 smooth streaming(typewriter=true 或 max-live-nodes<=0 会启用 smooth-streaming="auto")
    • 在 Vue 3(含 Nuxt)中,smooth-streaming 控制出字节奏,fade 控制透明度,两者可以同时开启。mode="chat" 保留 fade=false 作为轻量默认值;需要文字渐显时添加 fade,更看重动画成本时保持关闭。 此次有界追加淡入仅适用于 Vue 3,其他框架应按对应适配器文档选择。
    • 关闭虚拟化时再调整 batch(renderBatchSize / renderBatchDelay)
    • 保持重节点延迟(viewportPriority, deferNodesUntilVisible)
  • 最小追问:“你更新 content 或 nodes 输入路径的频率(每 token 还是每 chunk)?batch 参数是多少?”
  • 文档:docs/guide/ai-chat-streaming.md, docs/guide/performance.md, docs/guide/props.md

长文档:性能/内存 ​

  • 表述: “长文卡”, “滚动掉帧”, “内存高”
  • 步骤:
    • 调虚拟化(maxLiveNodes, liveNodeBuffer)
    • 保持重节点延迟
  • 最小追问: “大概多长(KB/行数)?是否有很多代码块/图表?”
  • 文档:docs/guide/performance.md

Mermaid 不显示 ​

  • 表述: “mermaid 空白”
  • 步骤:
    • 安装 mermaid peer
    • 若手动关闭/覆盖过 loader,客户端调用 enableMermaid()(或设置自定义 loader)
    • 复查 CSS 顺序/reset
  • 最小追问: “是否关闭过 loader?是否 SSR?fence 是否是 ```mermaid?”
  • 文档:docs/guide/mermaid.md, docs/guide/troubleshooting.md
  • 源码:src/components/MermaidBlockNode/mermaid.ts

KaTeX 不显示 ​

  • 表述: “公式不渲染”
  • 步骤:
    • 安装 katex peer
    • 导入 katex/dist/katex.min.css
    • 若手动关闭/覆盖过 loader,客户端调用 enableKatex()(或设置自定义 loader)
  • 最小追问: “是否导入 KaTeX CSS?$...$ 还是 $$...$$?是否 SSR?是否关闭过 loader?”
  • 文档:docs/guide/math.md, docs/guide/installation.md
  • 源码:src/components/MathInlineNode/katex.ts

代码块 runtime 不工作/空白 ​

  • 表述: “工具栏没了”, “代码块空白”
  • 步骤:
    • CodeBlockNode 是唯一的代码块渲染器,通过 stream-diffs 增强(diff 追踪、code/render 选项)
    • 如果应用层要提前预热,调用 markstream-vue 的 preloadCodeBlockRuntime()
    • 安装 stream-diffs 获得增强 surface;未安装时内置 renderer 会回退 <pre><code>
    • 受支持选项通过顶层或直接 codeBlockOptions 传入;header/toolbar 设置留在 codeBlockProps
    • maxHeight 与单个上下对称 padding 都使用 number 类型的 px 数值
    • 设置 render-code-blocks-as-pre 强制普通路径,或通过带作用域的 setCustomComponents(...) 替换 code_block
  • 最小追问: “控制台是否有报错?是否安装 stream-diffs?是否强制普通路径或使用了自定义 code_block?”
  • 文档:docs/guide/code-block-runtime.md, docs/guide/components.md

想要轻量代码块(不装 diff) ​

  • 表述: “SSR 友好”, “减包体”
  • 步骤:
    • 用 render-code-blocks-as-pre 输出纯 <pre> 代码块(无 diff 追踪)
    • 需要内置 CodeBlockNode 提供 diff 追踪时安装 stream-diffs
  • 最小追问: “需要 diff 追踪还是纯文本就行?”
  • 文档:docs/guide/code-blocks.md, docs/guide/components.md

Markdown 里嵌自定义组件(&lt;thinking&gt;) ​

  • 表述: “自定义 tag”, “嵌组件”
  • 步骤:
    • 通过 customHtmlTags / custom-html-tags 声明自定义标签(未知标签闭合后按原生 HTML 渲染;未闭合或格式不完整的片段按纯文本)
    • 用 setCustomComponents(customId, mapping) 映射渲染
  • 最小追问: “tag 名称有哪些?希望按 HTML 透传还是自定义 node type?”
  • 文档:docs/guide/advanced.md, docs/guide/parser-api.md

Nuxt SSR 报错 ​

  • 表述: “window is not defined”, “SSR crash”
  • 步骤:
    • 普通 Markdown 保留在 SSR 路径
    • 只有浏览器专属 peer/worker 的初始化放到 onMounted 或 &lt;ClientOnly&gt; 边界后
  • 最小追问: “Nuxt 版本?报错发生在 build 还是 runtime?安装/启用了哪些 peers?”
  • 文档:docs/nuxt-ssr.md

想确认导出/怎么 import ​

  • 表述: “是否导出 X”, “import 路径”
  • 步骤:
    • 查 src/exports.ts 和 package.json#exports
  • 最小追问: “要 import 的符号名是什么?现在用的 import 路径是什么?”
  • 文档:docs/guide/components.md, docs/guide/api.md