Как сохранить СУХОЙ при загрузке большого количества изображений с помощью GraphQL в Gatsby

Допустим, я хочу включить 50 изображений в одну статью в блоге о Гэтсби. Изображения загружаются с помощью GraphQL. В итоге я пишу очень повторяющиеся запросы для каждого из 50 изображений, например:

export const query = graphql`
  query ArticleImageQuery {
    coverImage: imageSharp(id: {regex: "/cover-image/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    artisan1: imageSharp(id: {regex: "/artisan1/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    artisan2: imageSharp(id: {regex: "/artisan2/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    artisan3: imageSharp(id: {regex: "/artisan3/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    johannystrom1: imageSharp(id: {regex: "/johan-nystrom1/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    johannystrom2: imageSharp(id: {regex: "/johan-nystrom2/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    johannystrom3: imageSharp(id: {regex: "/johan-nystrom3/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    johannystrom4: imageSharp(id: {regex: "/johan-nystrom4/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    fratello1: imageSharp(id: {regex: "/fratello/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    booksAntiques1: imageSharp(id: {regex: "/books-antiques1/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    booksAntiques2: imageSharp(id: {regex: "/books-antiques2/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    pastor1: imageSharp(id: {regex: "/pastor1/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    pastor2: imageSharp(id: {regex: "/pastor2/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    pastor3: imageSharp(id: {regex: "/pastor3/" }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
    libertyOrDeath1: imageSharp(id: {regex: "/liberty-death1/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    libertyOrDeath2: imageSharp(id: {regex: "/liberty-death2/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    kaisla1: imageSharp(id: {regex: "/kaisla1/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    blockDylan1: imageSharp(id: {regex: "/block-dylan1/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    blockDylan2: imageSharp(id: {regex: "/block-dylan2/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    blockDylan3: imageSharp(id: {regex: "/block-dylan3/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    blockDylan4: imageSharp(id: {regex: "/block-dylan4/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },
    blockDylan5: imageSharp(id: {regex: "/block-dylan5/" }) {
      sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER) {
        ...GatsbyImageSharpSizes
      }
    },

    /* The list goes on, you get the idea... */
  }
`;

Это сильно противоречит принципу DRY (Don't Repeat Yourself). Я пытался возиться с фрагментами, но, будучи новичком в GraphQL, я просто не могу понять, как я могу повторно использовать этот повторяющийся код и написать его только один раз, а не 50 раз?

Что я могу сделать, чтобы это улучшить?

В идеале я бы хотел иметь код, в котором я мог бы написать повторяющуюся часть один раз, а затем повторно использовать ее для каждого изображения, которое я получаю. Например:

/* NOTE: FICTIONAL PSEUDOCODE */

const imageQuery = graphql`
  query ImageQuery($path: String!) {
    imageSharp(id: {regex: $path }) {
      sizes(maxWidth: 700, maxHeight: 525) {
        ...GatsbyImageSharpSizes
      }
    },
  }
`;

export const query = graphql`
  query ArticleImageQuery {
    coverImage: ImageQuery("/cover-image/"),
    artisan1: ImageQuery("/artisan1/"),
    artisan2: ImageQuery("/artisan2/"),
    artisan3: ImageQuery("/artisan3/"),
    johannystrom1: ImageQuery("/johan-nystrom1/"),'
    /* ... AND SO ON */
  }
`;

person Alex    schedule 24.03.2018    source источник


Ответы (1)


У фрагментов GraphQL нет параметров. Дополнительную информацию см. В этом выпуске github.

Когда у меня возникает проблема, похожая на вашу, я выбираю все изображения, которые мне нужны, с помощью одного запроса, а затем обрабатываю их в представлении. Например с таким запросом:

export const query = graphql`
{
  allFile(filter: {absolutePath: {regex: "/img/o-meni/im/"}}) {
    edges {
      node {
        id
        name
        publicURL
        childImageSharp {
          sizes(maxWidth: 700, maxHeight: 525) {
              ...GatsbyImageSharpSizes
          }
        }
      }
    }
  }
}
`

А затем вы можете отфильтровать конкретное изображение, например artisan1 или что-то еще в компоненте React. Чтобы отобразить их все, вы можете использовать такой код:

{
  this.props.data.allFile.edges.map(({ node }) =>
    <a href={node.publicURL} key={node.id}>
      <Img sizes={node.childImageSharp.sizes} alt={node.name} title={node.name} />
    </a>
  )
}
person Saša Šijak    schedule 08.02.2019