Thứ năm, 15/08/2019 | 00:00 GMT+7

Giới thiệu về MDX trong Gatsby


Hầu hết các bạn có thể đã sử dụng file Markdown trong các trang web Gatsby.js của bạn và bạn đã biết đó là một cách tốt để viết nội dung. Nhưng Markdown thuần túy hướng đến nội dung dựa trên văn bản và nó có thể hạn chế khi bạn muốn bước ra ngoài trường hợp sử dụng đó. Tất cả đều thay đổi với MDX , một tập hợp Markdown cho phép ta nhúng JSX trực tiếp vào các file Markdown. Nghe có vẻ tuyệt vời, phải không? Trong bài viết này, ta sẽ khám phá những điều cơ bản về MDX với Gatsby, bao gồm một số kỹ thuật giới thiệu để giúp bạn bắt đầu sử dụng nó ngay lập tức.

Trước khi ta đi sâu vào, bạn cần có một dự án Gatsby đã được cài đặt và sẵn sàng chỉnh sửa. Nếu bạn cần trợ giúp để đạt được điểm đó, vui lòng làm theo các bước trong Các bước đầu tiên của bạn với Gatsby v2 rồi quay lại đây sau đó.

Cài đặt

Nhờ có thư viện plugin đáng kinh ngạc của Gatsby, quá trình cài đặt rất dễ dàng! Sử dụng MDX với Gatsby chỉ yêu cầu một plugin duy nhất, gatsby-plugin-mdx , cùng với các phụ thuộc ngang hàng MDX.

Hãy cài đặt chúng ngay bây giờ, như thế này:

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

Cũng hãy cài đặt gatsby-source-filesystem để ta có thể sử dụng frontmatter, tạo các node Gatsby từ các file local và sử dụng chức năng nhập / xuất trong các file MDX của ta :

$ yarn add gatsby-source-filesystem 

Mặc dù không bắt buộc về mặt kỹ thuật, nhưng bước này rất được khuyến khích - vì nó thực sự mở ra toàn bộ tiềm năng của nội dung MDX với Gatsby!

Cấu hình

Giống như với tất cả các plugin Gatsby, ta cần thêm chi tiết cấu hình vào phần plugins của gatsby-config.js .

Hãy cấu hình cả gatsby-plugin-mdxgatsby-source-filesystem như sau:

gatsby-config.js
module.exports = {
  //...siteMetadata, etc
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages/`,
      },
    },
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        defaultLayouts: {
          default: require.resolve(`./src/components/layout.js`),
      },
    },
    // ... other plugins
  ],
}

Lưu ý ta đang đặt khóa default trong tùy chọn defaultLayouts . Điều này sẽ tự động bao bọc tất cả các file MDX với thành phần layout.js mặc định của trang web của ta .

Tệp gatsby-config.js đã được chỉnh sửa, vì vậy đừng quên khởi động lại môi trường phát triển trước khi tiếp tục!

Tùy chọn cấu hình

Có một số tùy chọn cấu hình có sẵn cho gatsby-plugin-mdx :

  • extension: (Mảng chuỗi) Đặt phần mở rộng file sẽ được xử lý dưới dạng MDX. Tôi thường đặt giá trị này thành ['.mdx', '.md'] để xử lý các file Markdown bình thường dưới dạng MDX.
  • defaultLayouts: (Đối tượng) Điều này thường được sử dụng khi bạn có nhiều loại nội dung được tạo, chẳng hạn như các bài đăng trên blog và đánh giá sản phẩm. (Và như đã thấy ở trên, bạn cũng có thể đặt khóa default để tự động gói tất cả các file MDX.)
  • gatsbyRemarkPlugins: (Mảng các đối tượng plugin) Điều này cho phép ta sử dụng các plugin comment cụ thể của Gatsby cùng với quá trình xử lý MDX. Ở đây thường sử dụng plugin gatsby-remark-images .
  • commentPlugins: (Mảng các đối tượng plugin) Tương tự như tùy chọn trên, nhưng dành cho các plugin comment không phụ thuộc Gatsby.
  • rehypePlugins: (Mảng các đối tượng plugin) Tương tự như trên, nhưng đối với các plugin rehype .
  • mediaTypes: (Mảng chuỗi) Đặt loại phương tiện nào được xử lý. (Bạn có thể sẽ không cần sử dụng nó thường xuyên.)

Chi tiết đầy đủ về việc sử dụng các tùy chọn này có thể được tìm thấy trong tài liệu của plugin . Những tài liệu này rất xuất sắc và tôi thực sự khuyên bạn nên xem qua chúng sau khi đọc bài viết này! 🔍

Cách sử dụng cơ bản

Cấu hình ta có cho đến nay đã có thể xử lý tất cả các file .mdx trong trang web của ta . Và nhờ hành vi tích hợp của Gatsby, nếu ta thêm chúng vào folder src/pages/ thì chúng cũng sẽ tự động trở thành các trang!

Hãy làm điều đó ngay bây giờ bằng cách tạo một file MDX đơn giản tại src/pages/mdx-intro/index.mdx . Ta sẽ bắt đầu với một số văn bản Markdown cơ bản và frontmatter, giống như một trang blog Markdown điển hình sẽ có:

/src/pages/mdx-intro/index.mdx
---
title: MDX is Magical!
path: /mdx-intro
date: 2019-08-25
---

# Hooray For MDX!

This will be like turbo-charged Markdown!
import React from 'react';

const TitleBar = ({ text, size, bkgdColor }) => (
  <div
    style={{
      margin: '2rem 0',
      padding: '2rem',
      backgroundColor: bkgdColor || '#fff',
    }}
  >
    <h2
      style={{
        fontSize: size || '18px',
        margin: 0,
      }}
    >
      {text}
    </h2>
  </div>
);

export default TitleBar;

Tiếp theo, hãy cập nhật file MDX của ta để trông giống như sau:

/src/pages/mdx-intro/index.mdx
---
title: MDX is Magical!
path: /mdx-intro
date: 2019-08-25
---
import TitleBar from "../../components/TitleBar.js";

<TitleBar 
  size={"32px"} 
  bkgdColor={"#4aae9b"} 
  text={props.pageContext.frontmatter.title} 
/>

This will be like turbo-charged Markdown!

Có hai điều cần lưu ý ở đây:

  • Đầu tiên, ta vừa nhập và sử dụng một thành phần React trực tiếp bên trong Markdown! Hãy để điều đó chìm trong giây lát, bởi vì đây là một khái niệm vô cùng mạnh mẽ . (Hãy tưởng tượng các bài đăng trên blog có biểu đồ động và / hoặc dữ liệu được tải động, khả năng tương tác phức tạp, v.v.)
  • Thứ hai, bạn có thể nhận thấy rằng ta có thể truy cập các giá trị props.pageContext.frontmatter từ props.pageContext.frontmatter . Điều này cũng có thể khá hữu ích!

Quan trọng: Nếu các file MDX của bạn chứa frontmatter, hãy luôn đặt mọi câu lệnh nhập sau khối frontmatter!

Hãy tiếp tục và xem trang đã cập nhật trong trình duyệt của bạn và thử chỉnh sửa size và đạo cụ bkgdColor để xem nó cập nhật. Đó là một ví dụ thực sự đơn giản, nhưng : ta đang sử dụng một thành phần React bên trong Markdown! Khá ngọt ngào, phải không ?!

Chỉ định bố cục

Như đã đề cập trong phần cấu hình, MDX cung cấp cho ta một cách dễ dàng để cài đặt bố cục tùy chỉnh. Các bố cục này thuận tiện cho việc gói các kiểu và / hoặc nội dung bổ sung xung quanh các file MDX của ta .

Cấu hình bố cục mặc định

Ta có thể cài đặt bố cục mặc định cho các file MDX của bạn trong gatsby-config.js , ngay cả cho các vị trí cụ thể. Hãy xem ví dụ này:

gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages/`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `posts`,
        path: `${__dirname}/src/blog/`,
      },
    },
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        defaultLayouts: {
          posts: require.resolve("./src/components/blog-layout.js"),
          default: require.resolve("./src/components/layout.js"),
        },
      },
    },
  ],
}

Trong ví dụ này, ta đã cấu hình trang web của bạn để tất cả các file MDX có nguồn từ folder /src/blog sẽ sử dụng blog-layout.js làm bố cục / shell bọc. Ta cũng cài đặt một cấu hình default ở đây.

Lưu ý: Hành vi này hiện không hoạt động như mong đợi với các file MDX có nguồn từ folder pages . (Nhưng bạn vẫn có thể bọc chúng bằng cài đặt bố cục default , giống như ta hiện đã làm.)

Chỉ định hoặc xóa bố cục theo cách thủ công

Đôi khi bạn cần phải bọc một file MDX cụ thể với một bố cục duy nhất hoặc không có bố cục nào cả. Điều này có thể dễ dàng thực hiện bằng cách sử dụng cú pháp export default của JavaScript bên trong các file MDX của ta , cú pháp này sẽ overrides cài đặt defaultLayout nào. Ta sẽ đề cập đến vấn đề đó trong phần tiếp theo!

Nhập các file MDX khác

Ngoài việc nhập / sử dụng các thành phần JSX, ta cũng có thể nhập và sử dụng các file MDX khác như thể chúng là các thành phần. (Gợi ý: chúng thực sự là như vậy!)

Hãy tạo một file MDX mới trong folder thành phần của ta , tại /src/components/postSignature.mdx . Ta sẽ sử dụng điều này ở cuối trang MDX của ta làm chữ ký của tác giả.

/src/components/postSignature.mdx
##### Thanks for Reading!

*🐊 Al E. Gator | alligator.io | al@example.com*

export default ({ children }) => (
  <>
    {children}
  </>
)

Lưu ý câu lệnh export default ở cuối file . Như đã đề cập trong phần trước, đây là cách ta có thể overrides cài đặt cấu hình defaultLayout của defaultLayout . Trong trường hợp này, ta đang xuất một shell bọc <> trống xung quanh chữ ký của ta .

Tiếp theo, hãy nhập chữ ký MDX này vào file MDX chính của ta , tại /src/pages/mdx-intro/index.mdx :

/src/pages/mdx-intro/index.mdx
---
title: MDX is Magical!
path: /mdx-intro
date: 2019-08-25
---
import TitleBar from "../../components/TitleBar.js";
import PostSignature from "../../components/postSignature.mdx";

<TitleBar 
  size={"32px"} 
  bkgdColor={"#4aae9b"} 
  text={props.pageContext.frontmatter.title} 
/>

This is like turbo-charged Markdown!

<PostSignature />

Đến đây bạn sẽ thấy chữ ký này ở cuối trang mdx-intro . Tuyệt vời!! 😎

Truy vấn GraphQL

Nhờ tổ hợp plugin của gatsby-plugin-mdxgatsby-source-filesystem , các trang MDX của ta cũng có sẵn cho ta thông qua các truy vấn GraphQL.

Ta sẽ không dành nhiều thời gian cho việc này, vì chức năng này gần giống với việc truy vấn các file Markdown thuần túy theo cách tương tự. (Sự khác biệt duy nhất là các node MDX nằm trong allMdxmdx thay vì allMarkdownRemarkmarkdownRemark .)

Đây là một truy vấn ví dụ sẽ tìm nạp vật chất phía trước của tất cả các file MDX có sẵn:

query {
  allMdx {
    edges {
      node {
        frontmatter {
          title
          path
          date(formatString: "MMMM DD, YYYY")
        }
      }
    }
  }
}

Cung cấp dữ liệu khác

Ta cũng có thể cung cấp dữ liệu bổ sung thông qua các file MDX của bạn bằng cách sử dụng cú pháp export của JavaScript, (không nên nhầm lẫn với export default như được sử dụng ở trên!) Bất kỳ biến đã xuất nào đều được tự động thêm vào schemas GraphQL để ta có thể sử dụng nó khi cần trong GraphQL truy vấn và / hoặc trong khi kết xuất.

Dưới đây là một số dữ liệu ví dụ về "Đánh giá xe tải thực phẩm" mà ta có thể thêm vào trang MDX của bạn :

export const myReviews = [
  {
    name: "Tim's Tacos",
    overall: 9,
    variety: 7,
    price: 8,
    taste: 9
  },
  {
    name: "Noodleville",
    overall: 7,
    variety: 5,
    price: 6,
    taste: 8
  },
  {
    name: "Waffle Shack",
    overall: 6,
    variety: 5,
    price: 4,
    taste: 6
  },
];

Sau khi thêm dữ liệu đó vào bất kỳ đâu trong file , ta có thể truy vấn dữ liệu trong GraphQL bằng cách truy cập allMdx.nodes.exports , như sau:

query MdxExports {
  allMdx {
    nodes {
      exports {
        myReviews {
          name
          overall
          variety
          price
          taste
        }
      }
    }
  }
}

Đây chỉ là một bản demo thực sự cơ bản, nhưng chức năng này được dùng theo những cách cực kỳ sáng tạo và năng động.

Một ví dụ thực tế

Hãy kết thúc bằng cách thêm một ví dụ thú vị và thực tế vào trang của ta . Ta sẽ sử dụng dữ liệu myReviews mà ta đã cài đặt ở trên để hiển thị biểu đồ thanh động!

Đầu tiên, hãy thêm thư viện Recharts vào trang web của ta . Đây là một thư viện biểu đồ mạnh mẽ nhưng nhẹ mà tôi thường xuyên sử dụng trong các dự án khách hàng của bạn .

$ yarn add recharts

Tiếp theo, ta sẽ sử dụng Recharts để tạo một thành phần biểu đồ thanh có thể sử dụng lại. Vì đây không phải là bài viết về Recharts, hãy tiếp tục và tạo một file mới tại /src/components/BarChart.js và paste vào đoạn mã sau:

/src/components/BarChart.js
import React, { PureComponent } from 'react';
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from 'recharts';

const colorsList = ['#008f68', '#6db65b', '#4aae9b', '#dfa612'];

class ExampleChart extends PureComponent {
  render() {
    return (
      <div style={{ width: '100%', height: 350 }}>
        <ResponsiveContainer>
          <BarChart data={this.props.data}>
            <CartesianGrid strokeDasharray="2 2" />
            <XAxis dataKey="name" />
            <YAxis type="number" domain={[0, 10]} />
            <Tooltip />
            <Legend />

            {this.props.bars.map((bar, i) => (
              <Bar 
                dataKey={bar} 
                fill={colorsList[i]} 
                key={`bar_${i}`} 
              />
            ))}
          </BarChart>
        </ResponsiveContainer>
      </div>
    );
  }
}

export default ExampleChart;

Bây giờ ta đã cài đặt một thành phần biểu đồ thanh đẹp mắt, vì vậy ta chỉ cần nhập và sử dụng nó trong trang MDX. Đây là version cuối cùng của ta :

/src/pages/mdx-intro/index.mdx
---
title: MDX is Magical!
path: /mdx-intro
date: 2019-08-25
---

import TitleBar from '../../components/TitleBar';
import PostSignature from '../../components/postSignature.mdx';
import BarChart from "../../components/BarChart";

export const myReviews = [
  {
    name: "Tim's Tacos",
    overall: 9,
    variety: 7,
    price: 8,
    taste: 9
  },
  {
    name: "Noodleville",
    overall: 7,
    variety: 5,
    price: 6,
    taste: 8
  },
  {
    name: "Waffle Shack",
    overall: 6,
    variety: 5,
    price: 4,
    taste: 6
  },
];

<TitleBar
  text={props.pageContext.frontmatter.title}
  size={'32px'}
  bkgdColor={'#4aae9b'}
/>


This page is built with turbo-charged Markdown!

#### My Food Reviews:

<BarChart 
  data={myReviews} 
  bars={["overall", "variety", "price", "taste"]} 
/>

<PostSignature />

Đến đây bạn sẽ thấy một biểu đồ thanh nhiều màu trông đẹp mắt, hoạt ảnh khi xem và thậm chí có các chú giải công cụ động khi cuộn qua. 📊👈

Và tôi sẽ nói lại lần nữa: Đây là tất cả bên trong trang Markdown (MDX)! Chỉ cần nghĩ về tất cả các bài đăng và trang blog thú vị mà bạn có thể tạo ngay lập tức…

Kết luận

Ta thực sự đã trình bày rất nhiều trong phần giới thiệu MDX với Gatsby này! Hy vọng rằng nó không quá áp đảo và bạn có thể thấy rằng sự kết hợp này là một sự thay đổi hoàn toàn trò chơi để phát triển trang web nhanh chóng.

Tuy nhiên, ta chỉ làm xước bề mặt của những gì có thể. Từ đây, tôi khuyên bạn nên đi sâu vào phần tài liệu Gatsby trên MDX . Đó là một lỗ thỏ đáng để mạo hiểm, tôi hứa! 🕳🐇


Tags:

Các tin liên quan