Published on

这个博客是怎么搭起来的

EN中文

网站简介

这个网站使用 Next.js + Tailwind CSS + MDX 搭建,项目基于 tailwind-nextjs-starter-blog 改造而来。

MDX 简介与用法

什么是 MDX?

MDX 是一种把 Markdown 和 JSX 结合在一起的语法,因此你可以在 Markdown 中直接使用 JSX 组件。这样一来,Markdown 不再只是静态文本,也可以承载 React 组件,从而让内容呈现更灵活。

把 JSX 嵌进 Markdown 的想法本身就很有意思,因为这意味着我们可以在文章里放交互式组件,而不只是插入静态图片或代码片段。信息展示的方式会因此更动态,也更适合技术内容。

N = 50 QUICK SORT
NlogN:282 <=
比较次数: 0 + 交换次数: 0 = 0
<= N*N 2500

例如,上面的 <QuickSortAnimation /> 就是一个可以直接在 Markdown 中使用的 React 组件。它通过交互动画展示了快速排序的过程。

同样,MDX 也允许你直接写 HTML,例如下面这段视频标签:

<video controls>
  <source
    src="https://github-production-user-asset-6210df.s3.amazonaws.com/28362229/258559849-2124c81f-b99d-4431-839c-347e01a2616c.webm"
    type="video/webm"
  />
</video>

网站配色设置

网站的配色配置放在 tailwind.config.js 里,可以按照自己的偏好修改:

tailwind.config.js
theme: {
    colors: {
      primary: colors.sky,
      gray: colors.neutral,
      ...
    }
  ...
}

目录组件

文档中所有一级标题会被收集进 toc 变量,再传入 MDX 文件中,因此你可以基于它做自定义样式。如果只是想快速生成目录,也可以直接使用现成的 TOCInline 组件。

博客布局

设置模板

MDX 博客内容可以通过 frontmatter 字段映射到不同的 layout 组件。layout 字段用来指定文章应该使用哪一个模板,所有 layout 模板都放在 ./layouts 目录下。

一个最简单的自定义 layout 可以写成这样:

export default function ExampleLayout({ frontMatter, children }) {
  const { date, title } = frontMatter

  return (
    <SectionContainer>
      <div>{date}</div>
      <h1>{title}</h1>
      <div>{children}</div>
    </SectionContainer>
  )
}

配置博客的 Frontmatter

使用 layout 这个 frontmatter 字段,就可以指定一篇 Markdown 文章应该映射到哪个模板:

---
title: 如何使用该BLOG
date: 2024-07-01T15:32:14Z
lastmod: '2021-02-01'
tags: ['mdx', 'guide']
draft: false
summary: Nextjs + Tailwindcss + MDX 使用记录
layout: PostSimple
---

流量分析

可以在 siteMetadata.js 里配置你想使用的 analytics provider。[TODO]

评论系统

这里使用的是 giscus 评论系统。它可以在 giscus 网站上完成配置,之后再把相关配置写入 siteMetadata.js 即可。

代码高亮

这里使用的是 rehype-prism-plus 插件,它支持代码块的行高亮和行号显示。

python {1,3-4} showLineNumbers

def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

如果想改代码高亮的样式,可以直接编辑 prism.css

prism.css
.code-highlight {
  @apply float-left min-w-full;
}
.code-line {
  @apply -mx-4 block border-l-4 border-opacity-0 pl-4 pr-4;
}
.code-line.inserted {
  @apply bg-green-500 bg-opacity-20;
}
.code-line.deleted {
  @apply bg-red-500 bg-opacity-20;
}
.highlight-line {
  @apply -mx-4 border-l-4 border-primary-500 bg-gray-700 bg-opacity-50;
}
.line-number::before {
  @apply -ml-2 mr-4 inline-block w-4 text-right text-gray-400;
  content: attr(line);
}

References 系统

标准引用格式 (Nash, 1950)

行内引用例如 Nash (1951)

多个引用 (see Nash, 1950, 1951, p. 50)

References:


Nash, J. (1950). Equilibrium points in n-person games. Proceedings of the National Academy of Sciences, 36(1), 48–49.
Nash, J. (1951). Non-cooperative games. Annals of Mathematics, 286–295.

LaTeX 渲染

数学公式由 remark-mathrehype-katex 负责解析。1

Definition:

yi=xiβ+uiy_i = \mathbf{x}'_i \beta + u_i

Assumptions:

  1. The definition above is linear.
  2. E(UX)=0E(\mathbf{U}|\mathbf{X}) = 0 (conditional independence)
  3. rank(X\mathbf{X}) = kk (full rank)
  4. Var(UX)=σ2InVar(\mathbf{U}|\mathbf{X}) = \sigma^2 I_n (homoscedasticity)

Objective: Find a method to minimize the sum of squared errors for β\beta:

Q=i=1nui2=i=1n(yixiβ)2=(YXβ)(YXβ)Q = \sum_{i=1}^{n}{u_i^2} = \sum_{i=1}^{n}{(y_i - \mathbf{x}'_i\beta)^2} = (Y-X\beta)'(Y-X\beta)

Solution: Notice that QQ is a 1×11 \times 1 scalar with symmetry bAbb=2Ab\frac{\partial b'Ab}{\partial b} = 2Ab.

Take the matrix derivative w.r.t β\beta:

minQ=minβYY2βXY+βXXβ=minβ2βXY+βXXβ[FOC]   0=2XY+2XXβ^β^=(XX)1XY=(nxixi)1nxiyi\begin{aligned} \min Q & = \min_{\beta} \mathbf{Y}'\mathbf{Y} - 2\beta'\mathbf{X}'\mathbf{Y} + \beta'\mathbf{X}'\mathbf{X}\beta \\ & = \min_{\beta} - 2\beta'\mathbf{X}'\mathbf{Y} + \beta'\mathbf{X}'\mathbf{X}\beta \\ \text{[FOC]}~~~0 & = - 2\mathbf{X}'\mathbf{Y} + 2\mathbf{X}'\mathbf{X}\hat{\beta} \\ \hat{\beta} & = (\mathbf{X}'\mathbf{X})^{-1}\mathbf{X}'\mathbf{Y} \\ & = (\sum^{n} \mathbf{x}_i \mathbf{x}'_i)^{-1} \sum^{n} \mathbf{x}_i y_i \end{aligned}

插入图片

可以直接使用 Markdown 语法插图,也可以直接调用 Next.js 的 Image 组件。

![ocean](/static/images/ocean.jpeg)
<Image alt="ocean" src="/static/images/ocean.jpg" width={256} height={128} />
ocean

Footnotes

  1. 完整支持的 TeX 函数列表可参考 KaTeX documentation