Как импортировать изображения в Mdx-файл блога Gatsby (для красивой карусели)
В настоящее время я пытаюсь создать блог Гэтсби.
При просмотре документа я наткнулся на Mdx, способ использовать компонент React в файле Markdown (кстати, это потрясающая концепция!).
Однако я быстро столкнулся с ограничением: похоже, что на данный момент mdx поддерживает только "образы Gatsby". Например, если я помещу это в файл.mdx...
![Chinese Salty Egg](./salty_egg.jpg)
... этот код сгенерирует изображение Гэтсби. Это здорово, но что, если я хочу создавать "классические" изображения? Некоторым библиотекам, таким как React Slick Carousel, нужен простой<img>
тег.
Например, следующий код.mdx не будет работать:
# Introduction
import Slider from "react-slick";
export const settings = {
focusOnSelect: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
speed: 500
};
<Slider {...settings}>
<div>
<img src={"./salty_egg.jpg"}/>
</div>
<div>
<img src={"./salty_egg_2.jpg"}/>
</div>
</Slider>
(См. Соответствующую проблему GH здесь)
Единственный способ заставить его работать - использовать шорткоды и импорт:
index.mdx
---
title: Hello World
date: "2015-05-01T22:12:03.284Z"
path: "/first-post"
---
import image1 from "./assets/slick/salty_egg.jpg";
import image2 from "./assets/slick/salty_egg_2.jpg";
<SlickCarousel
settings={{
infinite: true,
slidesToShow: 1,
slidesToScroll: 1,
speed: 500,
}}
images={[
{
src: image1,
alt: "hip",
},
{
src: image2,
alt: "hop",
},
]}
/>
layout.js
import { MDXProvider } from "@mdx-js/react";
import { Message } from "theme-ui";
import SlickCarousel from "./post/slick-carousel";
const shortcodes = {SlickCarousel };
const layoutContent = data => (
<React.Fragment>
<GlobalStyle />
<main
style={{
background: `white`,
}}
>
<MDXProvider components={shortcodes}>{children}</MDXProvider>
</main>
</React.Fragment>
post/slick-carousel.js
import React from "react";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
const SlickCarousel = ({ settings, images }) => (
<Slider {...settings}>
{images.map((image, i) => (
<div key={i}>
<img width="350" src={`${image.src}`} alt={`${image.alt}`}></img>
</div>
))}
</Slider>
);
export default SlickCarousel;
Мои вопросы:
- Эта реализация как бы опровергает обещание MDX: наличие всего кода компонента в уценке. Как я могу улучшить свой код?
- В post/slick-carousel.js вы видите, как я могу сгенерировать изображение Гэтсби, а не просто тег изображения?
Большое спасибо!
1 ответ
Я действительно нашел ответ на второй вопрос благодаря этой замечательной публикации Весбоса.
=> Короче говоря: чтобы использовать изображение Гэтсби в пользовательском компоненте, вам необходимо создать дополнительный компонент Custom Image. Как это:
utils / CustomImage.js
import React from "react";
import { useStaticQuery, graphql } from "gatsby";
import Img from "gatsby-image";
export default function Image({ src, alt }) {
const { allImageSharp } = useStaticQuery(graphql`
query {
allImageSharp {
edges {
node {
fluid(maxWidth: 500) {
...GatsbyImageSharpFluid
originalName
}
}
}
}
}
`);
const image = allImageSharp.edges.find(
edge => edge.node.fluid.originalName === src
);
if (!image) {
return null;
}
return <Img fluid={image.node.fluid} alt={alt} />;
}
Применение:
post / slick-carousel.js
import CustImg from "../utils/CustomImage";
import React from "react";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
const SlickCarousel = ({ settings, images }) => (
<Slider {...settings}>
{images.map((image, i) => (
<div key={i}>
<CustImg src={`${image.src}`} alt={`${image.alt}`} />
</div>
))}
</Slider>
);
export default SlickCarousel;
=> Длинная история: под капотом Гэтсби использует статические запросы GraphQL для получения изображений. Если статический запрос является статическим, вы не можете передать имя изображения, которое хотите получить (команда Gatsby в настоящее время работает над исправлением). Итак, обходной путь на данный момент заключается в создании дополнительного компонента, который получает все активы и возвращает только тот, который вы вызываете.