盖茨比 MDX 简介

你们中的大多数人可能在你们的Gatsby.js站点)中使用过Markdown文件,并且你们已经知道这是一种编写内容的惊人方式。但普通的Markdown是面向基于文本的内容的,当您想要跳出该用例时,它可能会受到限制。mdx,是Markdown的超集,允许我们将jsx直接嵌入到Markdown文件中。听起来很棒,不是吗?在本文中,我们将探索使用Gatsby的MDX的基础知识,包括一些帮助您立即开始使用它的入门技术。

在我们开始之前,您需要有一个Gatsby项目,该项目已经设置好,可以编辑了。如果您需要帮助才能做到这一点,请按照您使用Gatsby v2的第一步》中的步骤操作,然后返回此处。

安装

多亏了Gatsby的不可思议的插件库,),安装过程非常简单!在Gatsby中使用mdx只需要一个插件,即gatsby-plugin-mdx,以及mdx对等依赖项。

现在让我们安装它们,如下所示:

1$ yarn add gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react

让我们还安装gatsby-source-filesystem,这样我们就可以利用FrontMatter,从本地文件生成Gatsby节点,并在mdx文件中使用导入/导出功能:

1$ yarn add gatsby-source-filesystem

虽然技术上没有要求,但强烈建议您执行此步骤-因为它真正打开了Gatsby的MDX内容的全部潜力!

配置

与所有Gatsby插件一样,我们需要在gatsby-config.jsplugins部分添加配置详细信息。

让我们将gatsby-plugin-mdxgatsby-source-filesystem都配置如下:

 1[label gatsby-config.js]
 2module.exports = {
 3  //...siteMetadata, etc
 4  plugins: [
 5    {
 6      resolve: `gatsby-source-filesystem`,
 7      options: {
 8        name: `pages`,
 9        path: `${__dirname}/src/pages/`,
10      },
11    },
12    {
13      resolve: `gatsby-plugin-mdx`,
14      options: {
15        defaultLayouts: {
16          default: require.resolve(`./src/components/layout.js`),
17      },
18    },
19    // ... other plugins
20  ],
21}

注意,我们在defaultLayouts选项中设置了一个default键。这将使用我们站点的默认layout.js组件自动包装所有MDX文件。

<$>[警告]Gatsby-config.js文件已被编辑,因此在继续之前不要忘记重新启动开发环境!<$>

配置选项

gatsby-plugin-mdx有几个配置选项:

  • 扩展名:(字符串数组)设置将作为MDX处理的文件扩展名。我通常将其设置为[‘.mdx’,‘.md’],以便也将普通的Markdown文件作为MDX处理。
  • defaultLayout:(Object)当您有多种类型的生成内容,例如博客文章和产品评论时,经常使用该选项。(如上所述,您还可以设置一个default键来自动包装所有MDX文件。)
  • gatsbyRemarkPlugins:(插件对象数组)这允许我们在mdx处理的同时使用各种Gatsby特定的备注plugins。这里经常使用gatsby-remark-Images插件。
  • markPlugins:(插件对象数组)类似于上述选项,但适用于非Gatsby依赖Remmark plugins.
  • rehypePlugins:(插件对象数组)与上面类似,但用于rehype plugins.
  • mediaTypes:(字符串数组)设置要处理的媒体类型。(您可能不需要经常使用它。)

有关这些选项用法的完整详细信息,请参阅插件的documentation.这些文档非常棒,我强烈建议您在阅读本文后再看一遍!🔍

基本使用方法

到目前为止,我们的配置已经可以处理我们站点中的所有.mdx文件。多亏了Gatsby的内置行为,如果我们将它们添加到src/ages/目录中,它们也会自动变成页面!

现在让我们通过在src/pages/mdx-intro/index.mdx中创建一个简单的MDX文件来实现这一点。我们将从一些frontmatter和基本的Markdown文本开始,就像一个典型的Markdown博客页面一样:

 1[label /src/pages/mdx-intro/index.mdx]
 2---
 3title: MDX is Magical!
 4path: /mdx-intro
 5date: 2019-08-25
 6---
 7
 8# Hooray For MDX!
 9
10This will be like turbo-charged Markdown!

您可以在浏览器中访问http://localhost:8000/mdx-intro来查看此新页面。

如果你看过Your First Steps with Gatsby v2这篇文章,你可能会认识到这个页面创建模式,唯一的区别是这是一个MDX文件,而不是Markdown。到目前为止,这并不是什么特别或新的东西。让我们改变这一点!

使用MDX中的组件

MDX的主要功能之一是我们可以直接在Markdown内容中导入和使用JSX组件。

为了演示这一点,让我们在/src/Components/TitleBar.js中创建一个简单的组件,它将让我们显示一个定制的标题栏。

 1[label /src/components/TitleBar.js]
 2import React from 'react';
 3
 4const TitleBar = ({ text, size, bkgdColor }) => (
 5  <div
 6    style={{
 7      margin: '2rem 0',
 8      padding: '2rem',
 9      backgroundColor: bkgdColor || '#fff',
10    }}
11  >
12    <h2
13      style={{
14        fontSize: size || '18px',
15        margin: 0,
16      }}
17    >
18      {text}
19    </h2>
20  </div>
21);
22
23export default TitleBar;

接下来,让我们更新MDX文件,使其如下所示:

 1[label /src/pages/mdx-intro/index.mdx]
 2---
 3title: MDX is Magical!
 4path: /mdx-intro
 5date: 2019-08-25
 6---
 7import TitleBar from "../../components/TitleBar.js";
 8
 9<TitleBar 
10  size={"32px"} 
11  bkgdColor={"#4aae9b"} 
12  text={props.pageContext.frontmatter.title} 
13/>
14
15This will be like turbo-charged Markdown!

这里有两点需要注意:

  • 首先,我们刚刚在Markdown内部直接导入并使用了一个Reaction组件!让我们暂时理解这一点,因为这是一个令人难以置信的强大概念。(想象一下带有动画图表和/或动态加载数据、复杂交互等的博客帖子。)
  • 其次,您可能已经注意到,我们可以从pros.pageConext.Frontmatter访问FrontMatter值。这也是非常有用的!

<$>[警告]重要提示:如果您的MDX文件包含FrontMatter,请始终将任何IMPORT语句放在FrontMatter块之后!

继续在浏览器中查看更新的页面,并尝试编辑sizebkgdColor道具以观看其更新。这是一个非常简单的例子,但再次说明:我们使用的是Markdown内部的Reaction组件!很甜蜜,对吧?!

分配布局

如配置部分所述,MDX为我们提供了一种设置自定义布局的简单方法。这些布局便于在我们的MDX文件周围包装其他样式和/或内容。

配置默认布局

我们可以在gatsby-config.js中设置MDX文件的默认布局,甚至可以设置特定位置的默认布局。看一下这个例子:

 1[label gatsby-config.js]
 2module.exports = {
 3  plugins: [
 4    {
 5      resolve: `gatsby-source-filesystem`,
 6      options: {
 7        name: `pages`,
 8        path: `${__dirname}/src/pages/`,
 9      },
10    },
11    {
12      resolve: `gatsby-source-filesystem`,
13      options: {
14        name: `posts`,
15        path: `${__dirname}/src/blog/`,
16      },
17    },
18    {
19      resolve: `gatsby-plugin-mdx`,
20      options: {
21        defaultLayouts: {
22          posts: require.resolve("./src/components/blog-layout.js"),
23          default: require.resolve("./src/components/layout.js"),
24        },
25      },
26    },
27  ],
28}

在本例中,我们已经配置了我们的站点,以便来自/src/blog目录的所有MDX文件都将使用blog-layout.js作为布局/包装器。我们还在这里设置了一个default配置。

<$>[警告]注意:此行为目前似乎无法正常处理源自ages目录的MDX文件。(但您仍然可以使用default布局设置来包装它们,就像我们目前所做的那样。)<$>

手动分配或删除布局

有时,您需要用唯一的布局或根本没有布局来包装特定的MDX文件。这可以通过在我们的MDX文件中使用JavaScript的exportdefault语法轻松完成,该语法会覆盖任何defaultLayout设置。我们将在下一节中介绍这一点!

导入其他MDX文件

除了导入/使用JSX组件之外,我们还可以导入和使用其他MDX文件,就像它们是组件一样。(Hint:他们实际上是!)

让我们在组件目录中创建一个新的MDX文件,该文件位于/src/Components/postSignature.mdx。我们将在MDX页面的底部使用它作为作者的签名。

 1[label /src/components/postSignature.mdx]
 2##### Thanks for Reading!
 3
 4*🐊 Al E. Gator | alligator.io | [email protected]*
 5
 6export default ({ children }) => (
 7  <>
 8    {children}
 9  </>
10)

请注意文件底部的export default语句。如上一节所述,这就是我们覆盖defaultLayout配置设置的方法。在本例中,我们将在签名周围导出一个空的<>包装器。

接下来,让我们将此MDX签名导入到我们的主MDX文件中,该文件位于/src/ages/mdx-troo/index.mdx

 1[label /src/pages/mdx-intro/index.mdx]
 2---
 3title: MDX is Magical!
 4path: /mdx-intro
 5date: 2019-08-25
 6---
 7import TitleBar from "../../components/TitleBar.js";
 8import PostSignature from "../../components/postSignature.mdx";
 9
10<TitleBar 
11  size={"32px"} 
12  bkgdColor={"#4aae9b"} 
13  text={props.pageContext.frontmatter.title} 
14/>
15
16This is like turbo-charged Markdown!
17
18<PostSignature />

现在,您应该在mdx-Intro页面的底部看到此签名。太棒了!!😎

GraphQL脚本

多亏了gatsby-plugin-mdxgatsby-source-filesystem的插件组合,我们的MDX页面也可以通过GraphQL查询轻松访问。

我们不会在这上面花太多时间,因为这个功能几乎与以相同的方式查询普通Markdown文件相同。(The唯一的区别是MDX节点位于allMdxmdx中,而不是allMarkdownRemarkmarkdownRemark中。)

下面是一个示例查询,它将获取所有可用MDX文件的正面内容:

 1query {
 2  allMdx {
 3    edges {
 4      node {
 5        frontmatter {
 6          title
 7          path
 8          date(formatString: "MMMM DD, YYYY")
 9        }
10      }
11    }
12  }
13}

提供其他数据

我们还可以通过使用JavaScript的)任何导出的变量都会自动添加到GraphQL模式中,这样我们就可以在GraphQL查询和/或渲染过程中需要时使用它。

以下是一些我们可以添加到MDX页面的Food Truck Review数据示例:

 1export const myReviews = [
 2  {
 3    name: "Tim's Tacos",
 4    overall: 9,
 5    variety: 7,
 6    price: 8,
 7    taste: 9
 8  },
 9  {
10    name: "Noodleville",
11    overall: 7,
12    variety: 5,
13    price: 6,
14    taste: 8
15  },
16  {
17    name: "Waffle Shack",
18    overall: 6,
19    variety: 5,
20    price: 4,
21    taste: 6
22  },
23];

在文件中的任意位置添加之后,我们可以通过访问allMdx.nodes.exports来查询GraphQL中的数据,如下所示:

 1query MdxExports {
 2  allMdx {
 3    nodes {
 4      exports {
 5        myReviews {
 6          name
 7          overall
 8          variety
 9          price
10          taste
11        }
12      }
13    }
14  }
15}

这只是一个非常基本的演示,但这个功能可以以令人难以置信的创造性和动态的方式使用。

实战案例

最后,让我们在我们的页面上添加一个有趣而实用的示例。我们将使用上面设置的myReviews数据来显示动画条形图!

首先,让我们将Recharts库添加到我们的站点。这是一个强大但轻量级的图表库,我经常在我的客户项目中使用。

1$ yarn add recharts

接下来,我们将使用重复图表来创建可重复使用的条形图组件。由于本文不是关于重新图表的文章,因此只需在/src/Components/BarChart.js处创建一个新文件,并粘贴以下代码:

 1[label /src/components/BarChart.js]
 2import React, { PureComponent } from 'react';
 3import {
 4  BarChart,
 5  Bar,
 6  XAxis,
 7  YAxis,
 8  CartesianGrid,
 9  Tooltip,
10  Legend,
11  ResponsiveContainer,
12} from 'recharts';
13
14const colorsList = ['#008f68', '#6db65b', '#4aae9b', '#dfa612'];
15
16class ExampleChart extends PureComponent {
17  render() {
18    return (
19      <div style={{ width: '100%', height: 350 }}>
20        <ResponsiveContainer>
21          <BarChart data={this.props.data}>
22            <CartesianGrid strokeDasharray="2 2" />
23            <XAxis dataKey="name" />
24            <YAxis type="number" domain={[0, 10]} />
25            <Tooltip />
26            <Legend />
27
28            {this.props.bars.map((bar, i) => (
29              <Bar 
30                dataKey={bar} 
31                fill={colorsList[i]} 
32                key={`bar_${i}`} 
33              />
34            ))}
35          </BarChart>
36        </ResponsiveContainer>
37      </div>
38    );
39  }
40}
41
42export default ExampleChart;

现在我们已经设置了一个很好的条形图组件,所以我们只需要导入并在MDX页面中使用它。这是我们的最终版本:

 1[label /src/pages/mdx-intro/index.mdx]
 2---
 3title: MDX is Magical!
 4path: /mdx-intro
 5date: 2019-08-25
 6---
 7
 8import TitleBar from '../../components/TitleBar';
 9import PostSignature from '../../components/postSignature.mdx';
10import BarChart from "../../components/BarChart";
11
12export const myReviews = [
13  {
14    name: "Tim's Tacos",
15    overall: 9,
16    variety: 7,
17    price: 8,
18    taste: 9
19  },
20  {
21    name: "Noodleville",
22    overall: 7,
23    variety: 5,
24    price: 6,
25    taste: 8
26  },
27  {
28    name: "Waffle Shack",
29    overall: 6,
30    variety: 5,
31    price: 4,
32    taste: 6
33  },
34];
35
36<TitleBar
37  text={props.pageContext.frontmatter.title}
38  size={'32px'}
39  bkgdColor={'#4aae9b'}
40/>
41
42This page is built with turbo-charged Markdown!
43
44#### My Food Reviews:
45
46<BarChart 
47  data={myReviews} 
48  bars={["overall", "variety", "price", "taste"]} 
49/>
50
51<PostSignature />

现在,您应该会看到一个看起来很甜美的多色条形图,它以动画形式进入视图,甚至在鼠标悬停时具有动画工具提示。📊👈

我要再说一遍:这一切都在一个Markdown(MDX)页面内!只要想想你可以在短时间内创建的所有有趣的博客帖子和页面……

结论

在这篇介绍MDX和Gatsby的文章中,我们确实谈到了很多!希望它不是太压倒性的,你可以看到,这个组合是快速网站开发的总的游戏规则改变者。

然而,我们只触及了可能性的皮毛。从这里,我建议深入研究Gatsby Docs on MDX.这是一个值得冒险的兔子洞,我保证!🕳🐇

Published At
Categories with 技术
Tagged with
comments powered by Disqus