使用gatsby-transformer-sharp

时间:2019-01-21 14:25:49

标签: gatsby

我正在将Gatsby与Netlify CMS结合使用。我将gatsby-transformer-sharp用于各种图像处理。

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

my-blog-post.md:

---
image: ''
---

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

Error Field "image" must not have a selection since type "String" has no subfields.

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

因此,我创建了一个schema.md文件,因此将始终至少有一个条目具有有效图像:

_schema.md:

---
image: /some-dummy-image.jpg
---

这似乎可以部分解决问题-构建仅偶尔会失败。但是,确实仍然失败。我认为它必须从遇到的第一个markdown文件中推断出其模式-有时它首先找到_schema.md,有时它首先找到my-blog-post.md

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

2 个答案:

答案 0 :(得分:2)

我最终解决了这个问题。我没有意识到,在推断出架构之前,直接从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);

  }
};

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

{
  resolve: 'remove-empty-fields',
  options: {
    fieldsToRemove: [
      'image',
      'bgImage',
    ],
  },
},

答案 1 :(得分:1)

我最近了解到,您甚至可以在Markdown的MarkdownRemark节点创建之前直接对其进行修改,然后返回此处共享。

gatsby-transformer-remark使用graymatter解析前题并允许用户传递自定义解析器。在内部,灰底使用js-yaml

const yaml = require('js-yaml');

const customParser = (str) => {
  const result = yaml.safeLoad(str);

  // remove image (non recursively, as an example)
  const { image, ...withoutImage } = result;

  return withoutImage;
}

并将其传递到gatsby-transformer-remark

{
  resolve: `gatsby-transformer-remark`,
  options: {
    engines: {
      yaml: customParser,
    },
}

从语法上讲,我更喜欢您的方式-当插件处理空字段时,这一点会更清楚。只是想添加另一个选项!