使用 gatsby-transformer-sharp 时将空字符串作为图像路径处理

Ric*_*ich 5 gatsby

我正在将 Gatsby 与 Netlify CMS 一起使用。我使用 gatsby-transformer-sharp 进行各种图像处理。

在 Netlify CMS 中,如果用户删除图像,则 frontmatter 值变为空字符串,例如:

我的博客post.md:

---
image: ''
---
Run Code Online (Sandbox Code Playgroud)

当我查询 Graphql 时,这会导致 gatsby-transformer-sharp 出错:

Error Field "image" must not have a selection since type "String" has no subfields.
Run Code Online (Sandbox Code Playgroud)

这似乎是因为 Gatsby/Graphql 已将图像字段推断为字符串。

所以我创建了一个schema.md文件,所以总是至少有一个带有有效图像的条目:

_schema.md:

---
image: /some-dummy-image.jpg
---
Run Code Online (Sandbox Code Playgroud)

这似乎部分解决了这个问题——构建只是偶尔失败。但它确实还是失败。我认为它必须从它遇到的第一个 markdown 文件中推断出它的架构 - 有时它_schema.md首先找到,有时它my-blog-post.md首先找到。

有没有人设法找到解决方案?

Ric*_*ich 4

我最终设法解决了这个问题。我没有意识到,在推断模式之前,直接从 frontmatter 中删除这些空字段实际上很容易。

我制作了一个小的自定义插件,它将递归地遍历 frontmatter 字段,并且任何具有空字符串的字段都会被删除。我还只允许它删除具有特定名称的字段(例如:),image因此它不会在其他地方导致意外的更改。

src/plugins/remove-empty-fields/gatsby-node.js:

let fieldsToRemove = [];

const deleteFieldsRecursive = (node) => {
  fieldsToRemove.forEach(fieldToRemove => {
    if (node[fieldToRemove] === '') {
      delete node[fieldToRemove];
    }
  });

  if (typeof node === 'object') {
    Object.values(node).forEach(subNode => {
      deleteFieldsRecursive(subNode);
    })
  }
};

exports.onCreateNode = ({ node }, configOptions) => {
  fieldsToRemove = configOptions.fieldsToRemove;

  if (node.internal.type === 'MarkdownRemark') {
    if (!node.frontmatter) {
      return;
    }

    deleteFieldsRecursive(node);

  }
};
Run Code Online (Sandbox Code Playgroud)

然后将其添加到插件列表中gatsby-config.js

{
  resolve: 'remove-empty-fields',
  options: {
    fieldsToRemove: [
      'image',
      'bgImage',
    ],
  },
},
Run Code Online (Sandbox Code Playgroud)