Gatsby 站点地图插件 gatsby-plugin-sitemap 完整配置指南从默认生成到自定义 lastmod 的实战方案【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby本指南以 Gatsby 官方仓库中的 gatsby-plugin-sitemap 说明文档为主体结合该插件的源码实现系统讲解如何为 Gatsby 站点自动生成 sitemap 索引与分片文件、如何理解每个配置项的真实作用以及如何通过自定义 GraphQL 查询与serialize回调产出包含准确lastmod的搜索引擎友好站点地图。读完本文你将能够独立完成插件安装、最小配置、排除规则、多数据源合并与自定义序列化等全部实战环节。插件是什么为 Gatsby 站点自动创建 sitemapgatsby-plugin-sitemap是一个在构建阶段自动为你的 Gatsby 站点生成 sitemap 文件的插件。你只需要把它加入gatsby-config.js的plugins数组构建完成后站点根目录下就会出现sitemap-index.xml索引文件以及若干分片文件随后即可把索引地址例如https://www.example.com/sitemap-index.xml提交给 Google Search Console 等搜索引擎工具。插件源码位于 packages/gatsby-plugin-sitemap其核心逻辑在 gatsby-node.js 的onPostBuild生命周期钩子中执行整体流程为执行你在配置中提供的 GraphQLquery取得站点 URL 与页面数据调用resolveSiteUrl解析出站点根地址调用resolvePages从查询结果中提取页面数组通过pageFilter应用内置排除规则与自定义excludes过滤逐个调用serialize把页面对象转换为 sitemap 条目url、lastmod、changefreq、priority等字段调用底层sitemap库的simpleSitemapAndIndex把序列化结果按entryLimit分片写入public目录。该插件的依赖信息可参考 package.json核心依赖包括sitemap负责 XML 生成与索引分片、minimatch负责 glob 匹配排除规则、common-tags与babel/runtime。安装npm install gatsby-plugin-sitemap重要提示该插件只在production模式下生成输出本地验证站点地图时需要先构建再以生产模式预览gatsby build gatsby serve最小配置三步接入在gatsby-config.js中完成以下最小配置即可让插件工作module.exports { siteMetadata: { // 如果未使用 resolveSiteUrl 选项则必须设置此项 siteUrl: https://www.example.com, }, plugins: [gatsby-plugin-sitemap] }上述配置之所以必须包含siteMetadata.siteUrl是因为插件的默认查询定义在 options-validation.js 中为{ site { siteMetadata { siteUrl } } allSitePage { nodes { path } } }默认的resolveSiteUrl实现见 internals.js会直接从data.site.siteMetadata.siteUrl取值若该字段缺失会直接抛出错误并提示你补充siteMetadata或提供自定义resolveSiteUrl。默认情况下生成的 sitemap 会包含站点全部页面排除项见下文并在站点根目录生成一个sitemap-index.xml索引文件每 45000 个 URL 会额外生成一个新的sitemap-X.xml分片文件sitemap-index.xml会指向这些分片。45000 这个阈值来自entryLimit选项的默认值源码注释也标明该默认值沿用上游sitemap插件未来可能需要针对性能进一步优化。随后就可以把https://www.example.com/sitemap-index.xml提交给你的服务商如 Google Search Console。为什么不建议直接使用默认输出插件开箱即用的默认序列化逻辑见 internals.js 中的serialize函数会给每个页面输出相同的元数据?xml version1.0 encodingUTF-8? urlset xmlnshttp://www.sitemaps.org/schemas/sitemap/0.9 url lochttps://example.net/blog//loc changefreqdaily/changefreq priority0.7/priority /url url lochttps://example.net//loc changefreqdaily/changefreq priority0.7/priority /url /urlset注意其中的changefreq和priority字段无论页面多重要、更新多频繁它们都是固定值daily与0.7几乎一定是错的。更关键的是Google 在官方站点地图文档中明确指出Google 会忽略priority和changefreq值所以不必费力添加它们。Google 会读取lastmod值但如果你谎报该值Google 将停止读取它。因此强烈建议自定义插件配置为站点地图补充准确的lastmod修改日期。下文「实战示例」一节给出了完整做法。配置选项详解插件的全部选项在 options-validation.js 中通过 Joi schema 定义并逐一校验其中query选项还会被解析验证——若传入的字符串不是合法 GraphQL 查询构建会直接报错。各选项含义如下选项类型 / 默认值说明outputstring /sitemap 文件的存放目录相对于public目录createLinkInHeadboolean true是否在站点head中注入指向 sitemap 的link标签entryLimitnumber 45000每个 sitemap 文件的条目数上限。索引文件sitemap-index.xml始终会生成条目数每超过一个entryLimit就多生成一个分片例如 45000 以内只生成sitemap-0.xmlexcludesstring[] []要从 sitemap 中排除的路径数组支持使用 minimatch 的 glob 匹配。通常为字符串数组但也可以放入其他数据类型以便自定义过滤——此时必须同时自定义filterPages函数queryGraphQL Query生成 sitemap 所需数据的查询语句。站点 URL 必须能从查询结果中取得如果你不是从site.siteMetadata.siteUrl获取就需要设置自定义resolveSiteUrl。覆盖 query 后可能需要配套自定义resolvePagePath、resolvePages如果取页面时没有使用allSitePage.nodes查询结构则必然需要自定义resolvePagesresolveSiteUrlfunction接收数据查询的结果返回站点 URL支持同步或异步函数resolvePagePathfunction接收一个页面对象返回该页面的 URI不含域名与协议resolvePagesfunction接收数据查询的结果返回页面对象数组支持同步或异步函数filterPagesfunction接收当前页面与来自excludes数组的一项字符串或其他对象返回布尔值true排除该路径false保留。注意当excludes数组未定义或为空时该函数不会被调用serializefunction接收filterPages过滤后的页面返回 sitemap 条目对象支持同步或异步函数Joi schema 会为上述所有选项提供默认值测试快照见tests/options-validation.js确认了完整默认集createLinkInHead: true、entryLimit: 45000、excludes: []、output: /以及各函数指向内置实现。同时该测试还验证了错误的output类型会给出output must be a string提示并会对旧版exclude单数选项发出exclude is not allowed的弃用警告。始终被排除的页面以下页面永远会被排除在 sitemap 之外即使自定义filterPages也无法改变见 internals.js 中的defaultExcludes常量与pageFilter实现/dev-404-page/404/404.html/offline-plugin-app-shell-fallbackpageFilter会先用这组默认排除规则逐页匹配命中即跳过后续的自定义excludes判断源码中注释说明默认规则已命中的页面无需再检查自定义排除规则全部过滤结果与 verbose 日志消息会一并返回便于在--verbose模式下排查「某个页面为何没进 sitemap」。实战示例为 WordPress 站点生成带 lastmod 的 sitemap当站点内容来自 WordPress例如使用gatsby-source-wordpress时典型的完整配置如下来自插件 README此处为便于阅读补充了注释const siteUrl process.env.URL || https://fallback.net // In your gatsby-config.js module.exports { plugins: [ { resolve: gatsby-plugin-sitemap, options: { query: { allSitePage { nodes { path } } allWpContentNode(filter: {nodeType: {in: [Post, Page]}}) { nodes { ... on WpPost { uri modifiedGmt } ... on WpPage { uri modifiedGmt } } } } , resolveSiteUrl: () siteUrl, resolvePages: ({ allSitePage: { nodes: allPages }, allWpContentNode: { nodes: allWpNodes }, }) { const wpNodeMap allWpNodes.reduce((acc, node) { const { uri } node acc[uri] node return acc }, {}) return allPages.map(page { return { ...page, ...wpNodeMap[page.path] } }) }, serialize: ({ path, modifiedGmt }) { return { url: path, lastmod: modifiedGmt, } }, }, }, ], }这段配置演示了三个关键技巧从环境变量读取站点地址resolveSiteUrl: () siteUrl让你把站点根地址交给部署环境如 CI 中的URL环境变量决定并提供了回退值合并多数据源默认查询只能拿到allSitePage而 WordPress 的modifiedGmt内容最后修改时间存在allWpContentNode中。这里通过resolvePages把两组节点以path/uri为键合并使每个页面对象同时携带path与modifiedGmt字段输出准确的 lastmod自定义serialize不再输出无意义的changefreq/priority而是输出url与真实的lastmod符合 Google 对站点地图的建议。关于这套回调机制的底层执行方式可以从 gatsby-node.js 的onPostBuild看到resolveSiteUrl、resolvePages、serialize均通过Promise.resolve(...)包裹调用因此同步与异步两种写法都受支持任何一步抛错都会通过reporter.panic中止构建并给出带[gatsby-plugin-sitemap]:前缀的错误信息resolvePages未返回数组时同样会直接 panic。此外序列化得到的url会经过prefixPath处理自动拼接站点域名与 Gatsby 的pathPrefix/basePath对应 gatsby-node.js 中传入的basePath参数。这一点也有对应测试覆盖在tests/gatsby-node.js 中验证了设置basePath后分片内所有 URL 都包含该前缀而 CDN 的assetPrefix不会错误地进入 URL。API 参考五个可自定义函数以下五个函数构成了插件的扩展点README 中给出了完整签名与参数说明resolveSiteUrl ⇒ string同步或异步函数均可。返回站点 URL可以来自 GraphQL 查询结果也可以来自其他作用域如环境变量。参数类型说明dataobjectGraphQL 查询结果resolvePagePath ⇒ string如果你不希望把页面 URI 放在path字段中就需要自定义resolvePagePath。返回不带域名与协议的页面 URI。参数类型说明pageobject从resolvePages返回的数组中的一项resolvePages ⇒ Array用于自定义页面数组的解析方式也是把多个数据源合并为单个数组的天然位置。同步或异步函数均可。返回代表每个页面的对象数组。参数类型说明dataobjectGraphQL 查询结果filterPages ⇒ boolean用于以任意方式过滤数据。该函数通过以下方式执行allPages.filter( page !excludes.some(excludedRoute thisFunc(page, excludedRoute, tools)) )其中allPages是resolvePages的结果。返回true表示排除该路径false表示保留。参数类型说明pageobject包含path键的页面对象{ path }excludedRoutestring插件配置中excludes数组的元素toolsobject过滤工具集{ minimatch, withoutTrailingSlash, resolvePagePath }内置默认实现internals.js 中的defaultFilterPages正是利用这三个工具完成 glob 匹配先通过resolvePagePath(page)取路径再用withoutTrailingSlash去掉尾部斜杠根路径/除外最后交给minimatch与排除模式比对。如果向excludes传入了非字符串类型默认实现会抛出带提示的错误——这印证了 README 的说法非字符串排除项必须搭配自定义filterPages使用。serialize ⇒ object该函数通过以下方式执行allPages.map(page thisFunc(page, tools))其中allPages是filterPages的结果。同步或异步函数均可。返回对象通常至少包含url可选的lastmod、changefreq、priority等字段会原样写入 XML。参数类型说明pageobject来自resolvePages结果的单个元素toolsobject序列化工具集{ resolvePagePath }更多细节createLinkInHead、output 与调试createLinkInHead的底层实现该选项由 gatsby-ssr.js 的onRenderBody处理——当选项为true默认值时会在渲染出的 HTMLhead中注入link relsitemap typeapplication/xml href.../sitemap-index.xml /方便搜索引擎自动发现站点地图设为false则跳过注入。output与entryLimit的落盘细节在 gatsby-node.js 中sitemap 实际写入路径为path.join(public, output)而索引内的公开路径为path.posix.join(pathPrefix, output)。测试tests/gatsby-node.js 验证了默认输出目录为public/、自定义output: custom-folder时写入public/custom-folder、以及entryLimit: 1时会把两个页面拆分为两个分片等行为。调试手段构建时以--verbose模式运行可以看到插件输出的过滤统计信息如「Filtering N pages based on M excludes」「N pages remain after filtering」以及每一条默认/自定义排除的命中记录均带[gatsby-plugin-sitemap]:前缀。小结gatsby-plugin-sitemap用最小的接入成本解决了 Gatsby 站点的 sitemap 生成问题但要让 sitemap 真正对搜索引擎有效关键是绕过默认的changefreq/priority固定值通过自定义queryresolvePagesserialize输出准确的lastmod。插件为这个定制过程提供了完整的回调扩展点其选项校验、内置排除规则与构建期错误提示都在源码中清晰可见值得在接入前通读 options-validation.js 与 internals.js 加深理解。【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考