Gatsby 使用 Markdown 文件创建页面:从文件系统采集到 File System Route API 的完整实战指南

发布时间:2026/9/20 1:04:51

Gatsby 使用 Markdown 文件创建页面:从文件系统采集到 File System Route API 的完整实战指南 Gatsby 使用 Markdown 文件创建页面从文件系统采集到 File System Route API 的完整实战指南【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby本指南以 Gatsby 官方 How-to 文档《Adding Markdown Pages》为骨架完整讲解如何让 Gatsby 用 Markdown 文件自动生成页面从安装gatsby-source-filesystem将文件读入 GraphQL 数据层到用gatsby-transformer-remark把 Markdown 转成 HTML、把 YAML frontmatter 转成可查询的数据再到用 File System Route API 的集合路由一键生成每篇博客的独立页面。读完本文你将掌握文件采集 → 数据转换 → 路由生成的完整链路并能在自己的 Gatsby 站点中复现localhost:8000/blog/my-first-blog-post这样的动态博客页面。整体流程Gatsby 是如何用 Markdown 生成页面的Gatsby 生成 Markdown 页面遵循四个固定步骤每一步都由一个明确的技术环节承接读取文件到 Gatsby通过gatsby-source-filesystem把文件系统中的 Markdown 文件读入 Gatsby 的 GraphQL 数据层形成File节点。转换 Markdown 与 frontmatter通过gatsby-transformer-remark识别 Markdown 文件把正文转换为 HTML、把 YAML frontmatter 转换为结构化数据。添加 Markdown 文件在内容目录中新建带 frontmatter 的.md文件其中slug字段决定最终 URL。创建集合路由组件利用 File System Route API 在src/pages下创建一个以花括号标注动态段的组件文件Gatsby 就会为每个 Markdown 节点自动生成页面。从源码结构看采集source→ 转换transform→ 路由route正是 Gatsby 插件架构的三层职责划分源插件负责产生节点转换器插件负责把节点升级为业务类型而文件路由负责把节点映射为 URL。前置条件开始之前你需要一个已经初始化好的 Gatsby 项目。如果还没有项目可以按照 Quick Start 创建。本教程假定你在这个项目的src目录下操作。第一步用gatsby-source-filesystem把 Markdown 文件读进 Gatsby安装插件npm install gatsby-source-filesystem在gatsby-config.js中注册插件gatsby-source-filesystem通过path选项指定要扫描的目录module.exports { plugins: [ { resolve: gatsby-source-filesystem, options: { name: content, path: ${__dirname}/src/content, }, }, ], }关于这两个选项结合 插件源码 可以补充以下几点path必须是绝对路径。源码在 sourceNodes 中会先校验目录是否存在不存在会直接panic并给出明确报错信息如果传入相对路径则自动用path.resolve(process.cwd(), path)解析为绝对路径——但官方推荐直接使用__dirname拼接避免工作目录变化导致路径漂移。name给这个数据源起个名字如content便于在多数据源场景下区分它是可选的。除此之外pluginOptionsSchema 还定义了fastHash默认false和ignore接受字符串 / 正则对象 / 函数的数组等选项。其中ignore会与源码内置的默认忽略列表合并——例如**/node_modules、**/.DS_Store、**/.gitignore等都会被自动跳过见 watcher 配置。创建内容目录与 Markdown 文件在src下新建content目录并在其中创建post-1.md--- slug: /my-first-blog-post date: 2022-11-24 title: My first blog post ---Markdown 文件开头的这段被三条短横线---包裹的键值对区域叫frontmatter它以 YAML 语法书写用于为页面提供额外元数据如日期、标题、slug。gatsby-transformer-remark会把它解析为结构化数据存入 GraphQL 数据层之后你可以从 React 组件中通过 GraphQL 查询这些字段。实时文件监听机制完成上述步骤后你的 Markdown 文件就已被采集进数据层。值得了解的是gatsby-source-filesystem在开发模式下并不仅仅做一次性读取——它的 sourceNodes 基于chokidar建立了一个由 xstate 状态机管理的文件监听器add、change、unlink事件分别触发节点的创建、更新与删除新增或删除 Markdown 文件后开发服务器会即时反映到页面与 GraphQL 查询结果中。这是添加/移除 Markdown 文件即自动添加/移除页面能力的底层来源。第二步用gatsby-transformer-remark把 Markdown 转成 HTML 与数据安装并注册插件npm install gatsby-transformer-remark在gatsby-config.js中把它加在gatsby-source-filesystem之后module.exports { plugins: [ { resolve: gatsby-source-filesystem, options: { name: content, path: ${__dirname}/src/content, }, }, // highlight-next-line gatsby-transformer-remark, ], }转换器的工作原理gatsby-transformer-remark并不是对所有节点都生效它通过shouldOnCreateNode判断节点媒体类型是否为text/markdown或text/x-markdown见 on-node-create.js只有满足条件的File节点才会被处理。在 onCreateNode 中插件做了这些事使用gray-matter解析 Markdown 文件分离出正文content与 frontmatter 数据data。创建新的MarkdownRemark节点正文存为html构建时渲染与rawMarkdownBody原始 Markdownfrontmatter 存入frontmatter字段并自动补一个空字符串title保证该字段恒存在。通过createParentChildLink建立File父→MarkdownRemark子的父子关系这正是 File System Route API 中parent__(File)语法能访问文件名的原因。若 Markdown 文件解析失败如 frontmatter 语法错误会调用reporter.panicOnBuild中止构建并给出包含文件绝对路径的错误信息。转换器的可用选项从 pluginOptionsSchema 可以看到gatsby-transformer-remark支持以下常用选项选项默认值说明footnotestrue是否启用脚注Footnotes模式gfmtrue是否启用 GitHub Flavored Markdown 模式excerpt_separator—指定摘要分隔符如 HTML 标签plugins—附加的 remark 插件列表jsFrontmatterEnginefalse是否允许用 JS 引擎解析---js/---javascript形式的 frontmatter其中jsFrontmatterEngine默认关闭且与安全公告相关源码在检测到---jsfrontmatter 但未开启该选项时会打印安全警告并返回空对象见 gatsby-node.js建议除非确实依赖该特性否则保持关闭。第三步创建集合路由组件File System Route API路由文件命名在src/pages下新建目录blog并创建集合路由文件src/pages/blog/{markdownRemark.frontmatter__slug}.jsx花括号{ }内是类型 字段的动态段markdownRemark是节点类型frontmatter__slug用双下划线表示嵌套字段访问即frontmatter.slug。Gatsby 会为每一个MarkdownRemark节点生成一个页面最终 URL 由该字段的值决定——本例中slug为/my-first-blog-post对应页面即localhost:8000/blog/my-first-blog-post。关于集合路由语法File System Route API 中还有以下要点动态段必须用{ }包裹且类型区分大小写如MarkdownRemark、contentfulMyContentType类型名以 GraphiQL 中实际显示为准。字段访问支持三种写法点号{Product.name}、双下划线嵌套{Product.fields__sku}、括号联合类型{MarkdownRemark.parent__(File)__name}且可多层嵌套。动态段可以在一个路径中出现多次例如src/pages/products/{Product.category}/{Product.name}.js会生成/products/toys/fidget-spinner这样的嵌套路由。每个集合路由都会自动查询id并以$id作为查询变量传给页面组件的 GraphQL 查询URL 中的参数则通过props.params注入组件。路由的最终 URL 会被自动 slug 化内部使用sindresorhus/slugify例如I ♥ Dogs会变成i-love-dogs。当你需要在前端构造指向集合路由的链接时可以查询类型上的gatsbyPath(filePath: /blog/{markdownRemark.frontmatter__slug})字段自动获得 URL。页面组件与 GraphQL 查询把下面的代码写入src/pages/blog/{markdownRemark.frontmatter__slug}.jsximport * as React from react import { graphql } from gatsby export default function BlogPostTemplate({ data, // this prop will be injected by the GraphQL query below. }) { const { markdownRemark } data // data.markdownRemark holds your post data const { frontmatter, html } markdownRemark return ( div div h1{frontmatter.title}/h1 h2{frontmatter.date}/h2 div dangerouslySetInnerHTML{{ __html: html }} / /div /div ) } export const pageQuery graphql query($id: String!) { markdownRemark(id: { eq: $id }) { html frontmatter { date(formatString: MMMM DD, YYYY) slug title } } } 启动gatsby develop后访问localhost:8000/blog/my-first-blog-post即可看到渲染出的博客页。这段代码中有两个关键机制值得注意页面查询Page Query文件后半段的graphql模板字符串就是一个页面查询它在构建时执行把查询结果注入组件。markdownRemark单条查询配合$id变量精确定位当前节点的数据——$id正是集合路由自动注入的节点 ID。关于页面查询的更多细节参见 页面查询指南。dataprop 注入查询结果由 Gatsby 自动注入组件的datapropprops.data.markdownRemark即当前 Markdown 文件全部数据html与frontmatter。其中frontmatter.date支持formatString参数如MMMM DD, YYYYGatsby 会按该格式把日期字段格式化为 November 24, 2022 这样的展示文本。做一个博客列表页接着可以在src/pages/blog/index.jsx创建列表页通过allMarkdownRemark查询所有文章并渲染链接import * as React from react import { Link, graphql } from gatsby export default function BlogIndex({ data }) { return ( ul {data.allMarkdownRemark.nodes.map(node ( li key{node.id} Link to{node.frontmatter.slug}{node.frontmatter.title}/Link /li ))} /ul ) } export const pageQuery graphql query { allMarkdownRemark(sort: { frontmatter: { date: DESC } }) { nodes { id frontmatter { title slug } } } } 对照参考仓库中的真实示例本仓库提供了多个可直接对照的示例项目examples/using-markdown-pages最贴近本文场景的最小示例。它的 gatsby-config.js 里注册了gatsby-source-filesystempath: ${__dirname}/src/markdown-pages与gatsby-transformer-remark内容文件 post-1.md 的 frontmatter 与本文完全同构页面模板 blogTemplate.js 展示了另一种等价做法——通过createPagesAPI 编程式创建页面见 gatsby-node.js页面查询用$slug变量按frontmatter.slug过滤。这可以作为File System Route API 与 createPages 二选一的对照案例。examples/route-apiFile System Route API 的完整示例覆盖集合路由、客户端路由[ ]语法、splat 路由[...]语法、gatsbyPath链接字段与config导出函数等全部能力。benchmarks 目录下的md、mdx等基准项目也大量使用gatsby-source-filesystemgatsby-transformer-remark/gatsby-plugin-mdx的组合可用于观察大规模 Markdown 站点的组织方式。进阶路由生成方式的选择与扩展方向File System Route API 与createPages如何取舍本教程采用的集合路由适合一个节点生成一个页面的常规场景。当出现以下需求时应改用 createPages API编程式创建页面只想为部分节点生成页面例如过滤掉type: Food的产品需要自定义传给页面查询的变量需要同时为多个字段生成路由或需要更精细的路径控制。File System Route API 的优势在于零gatsby-node.js代码文件名即路由声明createPages则拥有完全的程序控制力。两者可以共存于一个项目。在 Markdown 中使用图片如果你希望在 Markdown 正文或 frontmatter 中引用图片通常需要结合gatsby-plugin-sharp、gatsby-transformer-sharp与gatsby-plugin-image配合gatsby-remark-images或 MDX 下的对应方案进行图片处理与优化。详细做法参见 在 Markdown 与 MDX 中使用图片。从 Remark 迁移到 MDX如果你的内容需要嵌入 React 组件、交互式元素或希望使用组件驱动的内容模型可以考虑迁移到 MDX。仓库提供了完整的迁移指南 从 Remark 迁移到 MDX同时gatsby-plugin-mdx源码是官方推荐的 MDX 实现其工作方式与gatsby-transformer-remark类似读取文件 → 创建节点 → 通过集合路由生成页面。总结至此你已经掌握了 Gatsby 中用 Markdown 文件驱动页面的完整链路gatsby-source-filesystem负责把磁盘上的.md文件变成 GraphQL 数据层中的File节点并实时监听文件变化gatsby-transformer-remark负责把 Markdown 正文转换为html、把 YAML frontmatter 转换为可查询的结构化数据并建立File → MarkdownRemark的父子关系File System Route API 的集合路由{Type.field}命名让每篇 Markdown 自动生成一个页面变成纯声明式配置页面查询graphql模板与dataprop 注入让组件与数据无缝衔接。在此基础上你可以自由扩展 frontmatter 字段如tags、author、自定义组件样式甚至组合gatsbyPath生成站内链接、用config导出函数控制页面延迟静态生成。完整的 Markdown 语法规范可参考 Markdown 语法参考。下一步试着在src/content里添加第二篇 Markdown 文件然后刷新localhost:8000/blog——你会看到页面与列表自动更新这正是 Gatsby 数据层与文件路由配合带来的开箱体验。【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/20 0:59:51

Flutter流式CSV处理库serial_csv鸿蒙适配实战

1. Flutter 三方库 serial_csv 的鸿蒙化适配实战指南在移动应用开发领域,数据交换格式的选择往往直接影响着应用性能和用户体验。CSV(Comma-Separated Values)作为一种轻量级、通用性强的文本格式,在金融报表、工业数据采集等场景…

2026/9/20 0:59:51

数据要素价值释放的技术架构与实践路径

1. 数据要素价值释放的底层逻辑数据作为新型生产要素,其价值实现路径与传统要素存在本质差异。在传统工业经济中,土地、劳动力、资本等要素的价值呈现线性叠加特征,而数据要素的价值实现则表现出明显的网络效应和乘数效应——单一数据经过清洗…

2026/9/20 1:59:53

Page Assist 上手指南:三步用本地 AI 模型辅助网页浏览

Page Assist 上手指南:三步用本地 AI 模型辅助网页浏览 【免费下载链接】page-assist Use your locally running AI models to assist you in your web browsing 项目地址: https://gitcode.com/GitHub_Trending/pa/page-assist 想总结一篇长网页&#xff0c…

2026/9/20 1:59:53

VC++与DirectX运行库原理与精准安装指南

1. 这不是“装个补丁”那么简单:为什么90%的玩家和办公用户反复踩坑在VC与DirectX运行库上 你有没有遇到过这样的场景:刚下载完一款期待已久的游戏,双击启动,弹出一行红色错误提示——“MSVCP140.dll 丢失”;或者打开…

2026/9/20 1:59:53

BrewUI 使用指南:给 Homebrew 套上图形界面,告别命令行门槛

最近在折腾开发环境的时候,发现身边不少朋友开始用起了 BrewUI 这个工具。先简单交代一下背景,BrewUI 是一款专门给 Homebrew 做图形化包装的开源软件,目前主要在 macOS 上用,也有针对 Linux 的版本在推进。简单说,它是…

2026/9/20 1:59:53

功能测试实战手册:等价类、边界值与Test Director应用

简介:本资源是一篇面向软件测试初学者与课程设计学生的实践型论文,聚焦网店管理系统的功能测试全流程,覆盖商品、销售、采购、库存、财务及客户六大核心模块的测试设计与执行。论文以黑盒测试为主线,结合等价类划分、边界值分析等…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码