如何获取站点地图 Gatsby 的静态文件的更新/lastmod 值

Posted

技术标签:

【中文标题】如何获取站点地图 Gatsby 的静态文件的更新/lastmod 值【英文标题】:How to get updated / lastmod value for static files for sitemap Gatsby 【发布时间】:2022-01-06 08:42:09 【问题描述】:

我一直在使用 Gatsby,并一直在尝试为静态页面 (src/pages) 创建一个带有 lastmod 值的 sitemap。我看到了一个随机代码 sn-p,其中有人在他的 gatsby-config.js 中运行了下面的查询,并且能够得到他上次修改它们的日期。

allSitePage 
  nodes 
    path
    context 
      updated
    
  

我没能达到同样的成就。

这是我迄今为止尝试过的。我假设他正在使用上下文管理器并在他的 js 文件中设置上下文,并在每次编辑文件时手动更新上下文的值。

const Updated = React.createContext('2021-11-29')

class IndexPage extends React.Component 
  render() 
    return (
      <div>
        /* Example */
      </div>
    )
  


/* Also tried IndexPage.contextType = Updated */
IndexPage.useContext = Updated

export default IndexPage

我再次运行了查询,但无法传递要在graphql 查询中看到的值。这是我在 Graphql 操场上运行的查询。

query MyQuery 
  allSitePage 
    nodes 
      id
      context 
        updated
      
    
  

这就是我的整个数据结构在 Graphql 游乐场中的样子。

在创建站点地图时如何获取/设置要在gatsby-config.js 中使用的updated 值?

【问题讨论】:

【参考方案1】:
"allSitePage": 
      "nodes": [
        
          "path": "/signup/united-states/new-york/"
        ,
        
          "path": "/signup/united-kingdom/london/"
        
      ]

如果您的项目具有嵌套页面结构,请使用以下代码。


  resolve: "gatsby-source-filesystem",
  options: 
    name: "pages",
    path: "./src/pages/",
  ,
,
`gatsby-transformer-gitinfo`, 
  resolve: "gatsby-plugin-sitemap",
  options: 
    query: `
      site 
        siteMetadata 
          siteUrl
        
      
      allSitePage 
        nodes 
          path
        
      
      allFile(filter: sourceInstanceName: eq: "pages") 
        edges 
          node 
            fields 
              gitLogLatestDate
            
            relativePath
          
        
      
    `,
    resolvePages: (
      allSitePage: 
        nodes: sitePages
      ,
      allFile: 
        edges: pageFiles
      
    ) => 
      return sitePages.map(page => 
        const pageFile = pageFiles.find((
          node
        ) => 
          let fileName = node.relativePath.split('.').slice(0, -1).join('.')
          fileName = fileName === 'index' ? '/' : `/$fileName.replace('/index','')/`
          return page.path === fileName;
        );

        return  ...page, ...pageFile?.node?.fields 
      )
    ,
    serialize: (
      path,
      gitLogLatestDate
    ) => 
      return 
        url: path,
        lastmod: gitLogLatestDate
      
    ,
    createLinkInHead: true,
  ,

【讨论】:

【参考方案2】:

1.使用gatsby-source-filesystem 将静态页面文件添加到您的文件系统,以便您可以查询它们。

gatsby-config.js 中添加以下内容:


  resolve: "gatsby-source-filesystem",
  options: 
    name: "pages",
    path: "./src/pages/",
  ,
,

注意:您在此处用于name 属性的任何内容都将成为您在查询中过滤的内容。

2。将gatsby-transformer-gitinfo 添加到您的项目中,以在最新提交的File 字段上添加一些git 信息。 (plugin docs)

只需像这样在步骤 1 下声明它:


  resolve: "gatsby-source-filesystem",
  options: 
    name: "pages",
    path: "./src/pages/",
  ,
,
`gatsby-transformer-gitinfo`,

我们使用这个插件是因为 Gatsby 的 File 节点中的任何 modifiedTime/mtime/changeTime/ctime 字段在部署时都会被覆盖,因为 git 不会记录或保留文件时间戳元数据。

3.现在我们已将所有必要的数据添加到 GraphQL 中,并且可以对其进行查询以查看其外观:

query MyQuery 
  site 
    siteMetadata 
      siteUrl
    
  
  allSitePage 
    nodes 
      path
    
  
  allFile(filter: sourceInstanceName: eq: "pages") 
    edges 
      node 
        fields 
          gitLogLatestDate
        
        name
      
    
  

注意: sourceInstanceName 应该等于您在第 1 步中为 options.name 设置的任何值。

查询结果应如下所示:


  "data": 
    "site": 
      "siteMetadata": 
        "siteUrl": "https://www.example.com"
      
    ,
    "allSitePage": 
      "nodes": [
        
          "path": "/dev-404-page/"
        ,
        
          "path": "/404/"
        ,
        
          "path": "/404.html"
        ,
        
          "path": "/contact/"
        ,
        
          "path": "/features/"
        ,
        
          "path": "/"
        ,
        
          "path": "/privacy/"
        ,
        
          "path": "/terms/"
        
      ]
    ,
    "allFile": 
      "edges": [
        
          "node": 
            "fields": 
              "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
            ,
            "name": "404"
          
        ,
        
          "node": 
            "fields": 
              "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
            ,
            "name": "contact"
          
        ,
        
          "node": 
            "fields": 
              "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
            ,
            "name": "privacy"
          
        ,
        
          "node": 
            "fields": 
              "gitLogLatestDate": "2021-12-07 19:11:12 -0600"
            ,
            "name": "index"
          
        ,
        
          "node": 
            "fields": 
              "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
            ,
            "name": "terms"
          
        ,
        
          "node": 
            "fields": 
              "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
            ,
            "name": "features"
          
        
      ]
    
  ,
  "extensions": 

4.现在让我们把它们放在一起gatsby-config.js


  resolve: "gatsby-source-filesystem",
  options: 
    name: "pages",
    path: "./src/pages/",
  ,
,
`gatsby-transformer-gitinfo`,

  resolve: "gatsby-plugin-sitemap",
  options: 
    query: `
      site 
        siteMetadata 
          siteUrl
        
      
      allSitePage 
        nodes 
          path
        
      
      allFile(filter: sourceInstanceName: eq: "pages") 
        edges 
          node 
            fields 
              gitLogLatestDate
            
            name
          
        
      
    `,
    resolvePages: (
      allSitePage:  nodes: sitePages ,
      allFile:  edges: pageFiles 
    ) => 
      return sitePages.map(page => 
        const pageFile = pageFiles.find(( node ) => 
          const fileName = node.name === 'index' ? '/' : `/$node.name/`;
          return page.path === fileName;
        );

        return  ...page, ...pageFile?.node?.fields 
      )
    ,
    serialize: ( path, gitLogLatestDate ) => 
      return 
        url: path,
        lastmod: gitLogLatestDate
      
    ,
    createLinkInHead: true,
  ,

gatsby-plugin-sitemap 选项的解释:

query 不言自明

resolvePages

query 中获取结果,因此我们可以使用解构将allSitePageallFile 节点/边分配给变量。 通过sitePages(allSitePage.nodes)映射,使用page.path查找匹配文件name。 如果文件nameindex,则使用/ 进行匹配,因为路径不是/index/,否则只需将文件name 包装在分隔符中。 返回合并后的页面对象和包含 git 信息的匹配文件对象 (来自resolvePages 的对象数组成为插件代码中的allPages 对象)

serialize

这个函数映射到allPages,也就是来自resolvePages的页面对象数组,所以我们可以再次使用解构来获取每个页面的pathgitLogLatestDate。 返回属性:

url:插件将使用查询中的siteMetaData.siteUrl 并附加此处分配的任何值以生成完整的 URL。

lastmod: 期望一个有效的时间值并且总是输出一个完整的 ISO8601 字符串,不管传入的格式是什么。

注意:目前,似乎没有办法将lastmod 格式化为日期,只能通过gatsby-plugin-sitemap。这是因为 gatsby-plugin-sitemap 在底层使用了这个 sitemap 库,而该库的某些组件有一个 lastmodDateOnly 标志,可以切断时间字符串,gatsby-plugin-sitemap 不使用它们。

createLinkInHead: 链接站点地图索引在您网站的头部

5.最后,运行gatsby build,您应该会看到结果显示在public/sitemap/sitemap-0.xml

(好像gatsby-plugin-sitemap 最近切换到了这个位置,所以如果您使用的是旧版本的插件,可能会在其他地方。)

结果应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
        xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
    <url>
        <loc>https://www.example.com/contact/</loc>
        <lastmod>2021-12-10T05:18:29.000Z</lastmod>
    </url>
    <url>
        <loc>https://www.example.com/features/</loc>
        <lastmod>2021-12-10T05:18:29.000Z</lastmod>
    </url>
    <url>
        <loc>https://www.example.com/</loc>
        <lastmod>2021-12-08T01:11:12.000Z</lastmod>
    </url>
    <url>
        <loc>https://www.example.com/privacy/</loc>
        <lastmod>2021-12-10T05:18:29.000Z</lastmod>
    </url>
    <url>
        <loc>https://www.example.com/terms/</loc>
        <lastmod>2021-12-10T05:18:29.000Z</lastmod>
    </url>
</urlset>

额外的,可能有用的细节 - 我正在使用的所有东西的版本:

"gatsby": "^4.0.0",
"gatsby-plugin-sitemap": "^5.3.0",
"gatsby-source-filesystem": "^4.3.0",
"gatsby-transformer-gitinfo": "^1.1.0",

【讨论】:

以上是关于如何获取站点地图 Gatsby 的静态文件的更新/lastmod 值的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS静态站点生成器Gatsby

部署在 Netlify 上的 Gatsby 站点未更新来自 graphcms 的数据

React Gatsby Graph QL - 过滤站点地图的文章

gatsby-starter-blog 的站点地图

如何将 Gatsby 混合站点连接到 Apollo/Graphcool(或 Redux)?

Gatsby 站点地图:GraphQLError:语法错误:预期名称,找到 <EOF>