使用 Gatsby 和 MDX 重新设计我的博客

2025-06-07

使用 Gatsby 和 MDX 重新设计我的博客

如果你经常访问我的博客,你就会注意到,我终于有时间彻底重新设计我的网站了。我于 2018 年 3 月 30 日进行了第一次提交,并于 4 月 5 日上线了网站。在一年时间里,我不断扩展使用 React 和 Gatsby 构建的网站,并在设计系统领域进行了更深入的探索,现在我想将我的新经验融入到我的个人内容的新界面中。

而旧站点看上去确实很旧了

重新设计的目的是提升过度设计——作为未来 Gatsby 项目的样板,并为其他希望从头开始设计的人提供范例。

🔗在这里仔细阅读我的源代码(并加星标🌟)我的 Github 仓库。

🎯 目标

我设定了几个目标来设定设计的界限。这能为在情绪板中研究和积累灵感提供更广阔的背景。它还能在设计过程中起到很好的锚定作用,确保设计不会偏离初衷太远。

应该是:

  • 互动性强,但不要过于侵入。应伴随行动,或鼓励参与。
  • 内容第一图片第二。博客和更多基于开发的工作将更多地依赖于基于文本的布局。
  • 高品质的设计给人一种艺术画廊、高端作品集等的印象。
  • 受到日语的影响, 其排版和选择性 RTL(与 LTR)的使用。
  • 从头开始关注设计系统。

✨ 新功能

制定目标后,我还尝试设想网站需要设计和开发哪些新方面。这让我回答了这个问题:

“我需要从网站上得到什么?实际上需要什么?”

我为技术栈制定了清晰的愿景:

  • Gatsby v2作为框架
  • 独立开发的故事书
  • MDX用于创作丰富的、基于 React 和 Markdown 的内容
  • 使用 Styled Components 和 Rebass 的设计系统
  • 设计系统的Typescript
  • 使用 JSON + Gatsby GraphQL 的免费资源

盖茨比 v2

最初的网站设计是使用Gatsby v1创建的。网站运行良好,构建时间也符合其规模要求。

在这种特殊情况下,Gatsby v2 意味着更快的构建时间(得益于优化 + Webpack v4)、修复了依赖项的安全问题以及已修补的任何奇怪的错误。

我在推特上直播了整个迁移过程,这样你就能知道我遇到了哪些问题。说实话,只要读一读Gatsby 迁移指南,就能立即解决 80% 的问题。

故事书

由于我首先想设计组件,所以我想利用Storybook及其生态系统。它是一款非常棒的设计系统或组件库工具,除了简单的热重载设置之外,还提供了许多出色的实用功能。其中,无障碍工具必不可少,可以确保每个组件都符合无障碍标准(从 WCAG 到色盲标准)。

屏幕截图_2019-10-08_at_12-1140c95b-be5b-41cc-a611-eb04fa2ae58b.07.56_AM.png

有些人称之为 Storybook 驱动开发,它对我来说已经成长为一种更加精细的工作流程。

MDX

最近我经常使用MDX,因为我从事设计系统和文档工作,从中受益匪浅。MDX 类似于 Markdown,但允许通过编写 JSX 在文件中使用 React 组件。

我第一次遇到这个功能时,真是大吃一惊,因为我之前用过WordPress,感觉就像WordPress的短代码一样。我非常喜欢在CMS和内容创作中使用短代码,它能让作者使用现成的组件创作更具活力、更引人入胜的文章。而且,它可以直接使用React组件,最大限度地减少了创建特定“短代码”模板的开销。

在阅读了Amelia Wattenberger的几篇博客,了解她如何创建极具互动性和吸引力的组件来展示内容后,我深受启发。这些组件不仅提升了用户的理解力,也提升了用户体验。我想利用我之前为 Wordpress 或 Kirby 等 CMS 编写短代码的技能,尝试为常见的内容模式(例如代码块、并排示例、图表等)设计更好的布局。

FireShot_Capture_210_-_重新设计_开始_-_Ryosuke_-_localhost_copy-8349e736-a899-491a-b703-afcc86f34c31.png

我添加到 MDX 的最早也是最简单的组件之一是实时代码编辑器。我live向 Markdown 代码块添加一个参数,它会渲染一个 React 组件,在实时预览的同时显示高亮显示的代码。这样一来,用户就可以立即参与到代码中,而不必 fork 代码、创建 pen/sandbox 等等。

基于设计系统

整个网站都是以设计系统思维开发的。我首先利用Figma中现有的品牌资源,建立了一个更简洁的样式指南。Figma 可以轻松创建颜色和文本样式,最终组成一个组件库(按钮、卡片,所有我需要的标准组件)。这些组件可以轻松地作为模块插入到页面布局中,并作为首页和博客存档等页面的原型。

屏幕截图_2019-10-21_at_1-79ea7b22-6381-440f-919d-95e34caea7b8.23.49_PM.png

设计标记(颜色、排版、间距、大小等等)已从 Figma 设计文档转换为 Typescript “主题”文件。该文件包含 Figma 样式的 JSON 解释,并且这些标记或变量在整个应用程序中使用。

const colors = {
  text: '#111212',
  background: '#fff',
  primary: '#005CDD',
  secondary: '#6D59F0',
  muted: '#f6f6f9',
  gray: '#D3D7DA',
  highlight: 'hsla(205, 100%, 40%, 0.125)',
  white: '#FFF',
  black: '#111212',
}

const gradients = {
  subtle: `linear-gradient(180deg, ${colors.primary} 0%, ${colors.secondary} 100%)`,
  purple: `linear-gradient(180deg, ${colors.primary} 0%, #A000C4 100%)`,
  blue: `linear-gradient(180deg, #00D2FF 0%, ${colors.secondary} 100%)`
}

const fonts = {
  body: 'Roboto, Helvetiva Neue, Helvetica, Aria, sans-serif',
  heading: 'Poppins, Helvetiva Neue, Helvetica, Aria, sans-serif',
  monospace: 'Menlo, monospace',
}

const theme = {
  animation,
  breakpoints,
  mediaQueries: {
    mobile: `@media screen and (min-width: ${breakpoints[0]})`,
    tablet: `@media screen and (min-width: ${breakpoints[1]})`,
    computer: `@media screen and (min-width: ${breakpoints[2]})`,
    desktop: `@media screen and (min-width: ${breakpoints[3]})`,
    widescreen: `@media screen and (min-width: ${breakpoints[4]})`,
  },
  colors,
  gradients,
  fonts,
  fontSizes: [
    12, 14, 16, 20, 24, 32, 48, 64, 96
  ],
  fontWeights: {
    body: 400,
    heading: 500,
    bold: 700,
  },
    ...
}
Enter fullscreen mode Exit fullscreen mode

我还选择使用 Rebass 组件作为我的 React 组件库的基础。一旦我需要将设计转化为代码,为了加快开发过程,我并不想重新创建所有“基础”组件(例如按钮或表单元素)。Rebass 允许我扩展其相当自由且没有样式的组件,从而创建我自己的组件。

Rebass 还带来了 Styled System,这是一种使用 Emotion 或 Styled Components 来设置组件主题的定制方法。它有点像实用 CSS 与 CSS-in-JSS 的结合,您可以提供任何组件属性,例如width={[1,1/2,1/3]}响应式设置宽度。这将使最小视口的宽度为 100%,最大视口的宽度为 33%。您还可以在主题文件中将这些响应式参数以及其他样式/CSS 参数定义为“变体”。这允许您创建类似 的内容<Box variant="card.basic">,它会根据您在主题文件中定义的内容应用类似卡片的样式。

const theme = {
    ...
  // rebass variants
  text: {
    header: {
      fontFamily: fonts.heading,
      lineHeight: '1.25',
      fontSize: [3, 3, 4, 5],
      marginBottom: 3,
    },
    subheader: {
      fontFamily: fonts.heading,
      lineHeight: '1.25',
      fontSize: [2, 2, 3, 3],
      marginBottom: 3,
    },
  },
  variants: {
    card: {
      p: 2,
      bg: 'background',
      boxShadow: 'card',
      avatar: {
        width: 'avatar',
        height: 'avatar',
        backgroundSize: 'cover',
        backgroundPosition:'center',
        marginBottom: "3rem"
      }
    },
    },
    ...
}
Enter fullscreen mode Exit fullscreen mode

这让使用 Styled Components 变得更容易一些,因为由于框架本身过于简单,重新组合或扩展样式可能会有些不方便。通常,你会创建一个包含 CSS 字面块的文件,其中包含可跨组件复用的样式,或者创建一个充当 SASS 风格“mixin”的函数,返回 CSS 字面块。但是,一旦你了解了 Styled Components 的工作原理,你会发现它基本上通过Styled System为你完成了所有这些工作,并将你的主题文件作为可复用样式的真实来源(而不是分散的 JS 文件)。

打字稿

随着 Typescript 的流行和使用日益增长,我参与了越来越多的项目,而我的博客正是我继续实践的最佳平台。我还想借此机会尝试如何将 Typescript 与设计系统集成,以及它能为开发者带来哪些体验。

Isha Kasliwal 在最近的一次演讲中探讨了在设计系统中使用 TS 的好处。我之前就对这个话题很感兴趣,看到这样的演讲更让我明白了进行更多尝试的必要性。

免费资源

作为一个经常受益于免费资源的人,我喜欢创建免费资源和素材,尽可能地回馈社区。多年来,我一直在各种不同的平台上(图片库网站、Github、Uplabs/Dribbble)进行创作,但一直没有一个地方在我的个人网站上整合它们。

我必须决定是要策划还是聚合内容。Gatsby 的内容网格和各种源插件让这两种方式都变得简单,但我希望确保无论选择哪种方式,都简单、有效且面向未来。

FireShot_Capture_211_-_Ryosuke__Change_the_world_one_app_at_a_time_-_localhost_copy-2c5ad9aa-dc77-4f0b-8121-94a7e89cfdf2.png

一开始你可能会说:“嘿,你需要 Github 仓库,为什么不从 API 中拉取呢?” 由于我的资源分散在多个不同的平台(比如 GitLab),而且我不想列出所有仓库,这样就得过滤——所以我选择在网站仓库中创建 JSON 文件,作为这些数据的内容中心。我之前用过 Gatsby 的 JSON 转换器插件,它可以接收 JSON 文件并将其转换为 GraphQL 端点(几乎是一对一的,这使得模拟和数据结构相当容易)。

🎨设计过程

从我的目标出发,我开始浏览设计灵感资源,如 Behance、Dribbble 和我的 Instagram 书签——以及 Awwwards、Gatsby Showcase 部分,基本上任何包含优质网站的目录。

我在 Trello 卡片中收集了各种链接,并记录了网站中我特别喜欢的部分,以及哪些部分我可以自己复制。我拍摄了大量符合我期望美感的网站截图,并将它们精炼到最接近的版本,然后导入 Figma 文件,以便在设计过程中轻松访问。

最终,我希望创造一些东西,利用我在编辑设计方面的背景来创作印刷品,例如杂志、报纸以及最终的数字博客。

强大的排版,使用或强调网格设计系统,但为打破系统独特设计保留了一致的空间(即:杂志跨页与更简单的文章)。

屏幕截图_2019-10-04_at_5-afddcd82-03c0-44b2-b9b3-665c3a967532.21.41_PM.png

我的灵感主要来自:

  • DesignSystems.com(讽刺的是,它是由 Figma 开发的)。你会在这里看到该网站的一些核心设计元素,例如简洁的极简主义美学、1px 边框和渐变形状。
  • Kwok Yin Mak的作品集正是我处理竖排或日文文本的完美范例。它展现了我喜欢的那种强劲的排版、额外的填充和 1px 的边框。我不想完全水平滚动,但每个包含图片的网站组件都为我后来在项目页面中使用 MDX 组件提供了很大的灵感。
  • Nicolas LoureiroYann Kubacki,甚至Brent Jackson (Rebass 和 Styled System 的创始人)等艺术家的极简主义作品集。他们都注重简洁的美感,采用白色背景、纯色字体以及充足的填充,为所有内容提供自由空间。卡片或版块上几乎没有使用背景色来区分,而是通过充足的空间凸显背景。亮色的主要用途是突出元素,并立即强调元素。
  • Notion 的网站和应用程序都将极简主义、白色和表情符号🏔运用到了极致——而且效果显著。Bear是一款类似的 iOS 应用。它们通过消除界面上的杂乱,让阅读和写作更加愉悦,同时又通过直观的用户界面提供所有关键功能。

⛓ 应用程序如何运作

🧐 希卡普斯

每一个雄心勃勃的新项目或变革通常都会引发一系列新问题,考验开发人员的耐心,并最终将他们提升到更高的水平(经验是由你留下的大量已解决的错误来定义的)。

这个项目也不例外——我遇到的大多数问题都源于我迫切需要用Typescript重写所有内容,这使得任何使用其自带 Webpack 配置的库都变得复杂。以下是我遇到的一些主要问题及其原因:

  • 更改 Gatsby 的 Webpack 配置也需要更改 Storybook 的配置。您可以使用自己的项目扩展 Storybook 的 Webpack 配置,但由于 Gatsby 的扩展是在配置中实现的(而不是传统的webpack.config.js),因此您无法轻松地重用配置。
  • Netlify CMS + Typescript。我尝试让它在本地或云端编辑内容(我已经使用 Netlify 作为主机)。我尝试使用 MDX 让它工作(这需要一些调整),但 CMS 无法使用任何 Typescript 组件运行。Netlify CMS 的 Webpack 不包含 Typescript 的加载器。我尝试创建一个单独的 MDX 组件范围而不导入任何 TS 文件,但我的大多数主要组件都是 TS,这意味着大多数内容预览都无法使用。我仍在研究如何扩展 Netlify CMS 的 Webpack 以使 TS 能够工作,或者找到一个在开发和生产环境中都有效的编译流程。
  • Netlify CMS + 子目录。这是最令人失望的一点,Netlify CMS 不支持嵌套在子目录中的内容(例如/content/blog/your-article/index.md)。所有内容都必须放在同一个文件夹中,并以 slug 命名。我的内容结构与此不同,因为我将图片与内容放在一起,以便更容易删除帖子,而不会在仓库中留下媒体文件(除非媒体是共享的,它会被放在公共文件夹中)。当我查看 Github 上关于这个问题的 issue 时,似乎这个问题已经被请求了好几个月,并且计划在 2.0 版本中实现。
  • Gatsby + Storybook。如果你在自己的组件中使用任何 Gatsby 的<Link />组件,Storybook 将会返回错误,直到你调整其 Gatsby 的配置
  • Gatsby + Remark Images + MDX。不知何故,我的 MDX 帖子在页面上每张图片都显示双倍图像,一张模糊,一张全尺寸。这是使用过程中的一个小问题gatsby-plugin-mdxgatsby-remark-images在这里找到了解决办法。
  • Gatsby + MDX + 图片。我非常兴奋能用<Flex><Box>组件创建复杂的布局,这些组件与文本配合得很好,可以在 Markdown 中创建两列以上的布局。但是,一旦你放置了一张图片,Gatsby 就会对其施展魔法(使其滚动加载、跟踪 SVG 效果等),这会导致图片变成全宽并破坏布局。我不确定需要什么来解决这个问题,而且这严重限制了我对 MDX 的一些想法。我打算尝试用更适合我主题的组件替换 Gatsby 图片包装器,尝试移除 Gatsby 的 MDX 备注插件,或者将图片上传到文件/static夹并直接链接到链接,以避免任何 Webpack 加载。

🤩 下一步

由于项目的规模(以及我有多少潜在的博客素材),我将一些功能分解为里程碑,并随文章发布,同时深入描述该过程。

  • 可访问性(Aria 标签、颜色对比度、移动、用户体验等)
  • 使用样式化组件实现暗黑模式 + 为 Storybook 添加主题
  • 使用 Jest 向组件添加测试(以及对测试库和酶的反应)
  • 用于组件测试的 Jest Storyshots
  • Gatsby 页面转换 + 动画(page-transitions git 分支)
  • 动画 SVG 形状(Greensock 与 React-Spring)
  • 使用 Storybook 进行集成测试
  • 使用 Storybook 的组件文档(使用注释或新的 Storybook 文档)
  • 用于编辑和预览内容的本地或基于云的 CMS(Netlify CMS、Sanity 等)

还有很多工作要做(比如给anyprops 添加类型),但我对网站目前的状况感到欣喜,这能让我感到耳目一新。如果您有任何反馈或问题,请随时在 Twitter 上(或在 Hashnode/The Practical Dev 的评论区)联系我。

干杯
Ryo

参考:

文章来源:https://dev.to/whoisryosuke/redesigning-my-blog-using-gatsby-and-mdx-254c
PREV
在 Laravel 中轻松使用 UUID
NEXT
React Hooks、Suspense 和 Memo