Lei Zhang

Lei Zhang

2022,三餐四季温素有趣。

lovchun.com

  • love 缺省字母 e

站点由哪些所构建

我曾使用过的技术栈

客户端

  • Gulp
  • Webpack
  • Nodejs
  • Vuejs
  • Reactjs
  • Nextjs
  • Typescript
  • Miniprogram

服务端

  • PHP : Codeigniter、Laravel、ThinkPHP、Phalcon
  • Python : Flask、Django
  • Nestjs
  • Docker
  • Nginx
  • Mysql
  • Memcache
  • Supervisor

我这几年的工作

涉及过金融、邮箱、网站、新零售等业务。

早先 PHP + Require.js + jQuery + Bootstrap 全栈工作了三年,后面 Angular 横空出世,再到 ReactjsVuejs,前后端分离趋势流行后,便一直在前端领域摸爬滚打,精通基于 Json Web Token 的前后端分离。

最近两年主要工作从 B 端 转换到了 C 端, 擅长微信/企业微信小程序的相关开发和一些营促销 H5 的开发。

新特性

Vercel

现在网站部署于Vercel,只需要每年续费域名(¥68),即可拥有一个独立域名的静态网站,此外还能免费构建,免费的 PV/UV 统计等等。

不用再续费阿里云 ECS,一年省下 ¥700+ 倒是可以加几箱油 🎉

Tailwind CSS

最近几年,原子样式的趋势越来越好,这次整站CSS都是基于 Tailwind CSS,例如主题切换,试试点击 👉

MDX

这次站点的重构,基于 mdx,手动把 Mysql 中富文本录入的旧文章转换为 mdx 是个很费劲的工作,再加上以前的文章质量没那么高,所以几乎删除了大部分旧数据。

Contentlayer

最开始使用 mdx-loader+fs 读取文件,转换 modules, 创建 async router path,但是有个弊端,整个 hotreload 又卡又慢,这个完全无法忍受。

无意中看到了 Contentlayer,它的运行原理大概如下:

image

这个库还是 ALPHA,能很好的处理 fiels => modules,编译和转换都非常非常的快,完美解决上面的弊端。

FrontMatter

fields in *.mdx file

const CommonFields = {
  title: {
    type: 'string',
    description: '标题',
    required: true,
  },

  createdAt: {
    type: 'date',
    description: '创建时间',
    required: true,
  },

  publishedAt: {
    type: 'date',
    description: '发布时间',
    default: null,
  },

  updatedAt: {
    type: 'date',
    description: '最后更新时间',
    default: null,
  },

  draft: {
    type: 'boolean',
    description: '是否为草稿, 草稿不会被展示',
    default: true,
  },

  summary: {
    type: 'string',
    description: '概括',
    default: null,
  },

  tags: {
    type: 'list',
    of: { type: 'string' },
    description: '标签',
    required: true,
  },
}

frontmatter

---
title: '文章标题'
createdAt: '2022-03-01'
publishedAt: '2022-03-07'
updatedAt: '2022-03-10'
draft: false
summary: '文章概况'
tags: ['next-js', 'tailwind', 'guide']
---

PrismPlus

静态的 Markdown 当然少不了代码块的支持,这次引入了 PrismPlus 来实现代码块相关的高亮等功能,效果如下:

代码块

MDX ----> remark AST ------> rehype AST --------> HTML
    parse            convert            stringify

代码标题

pages/posts/[...slug.js]
export async function getStaticPaths() {
  return {
    // dynamic paths
    paths: allPosts.map(() => ({
      params: { slug: post.slug.split('/') }
    }))
    // fallback set false
    fallback: false,
  }
}

高亮行

pages/posts/[...slug.js]
export async function getStaticPaths() {
  return {
    // dynamic paths
    paths: allPosts.map(() => ({
      params: { slug: post.slug.split('/') }
    }))
    // fallback set false
    fallback: false,
  }
}

显示行号

pages/posts/[...slug.js]
export async function getStaticPaths() {
  return {
    // dynamic paths
    paths: allPosts.map(() => ({
      params: { slug: post.slug.split('/') }
    }))
    // fallback set false
    fallback: false,
  }
}

显示差异

contentlayer.config.js
+ import remarkGfm from 'remark-gfm'
+ import rehypeSlug from 'rehype-slug'
+ import rehypeAutolinkHeadings from 'rehype-autolink-headings'
+ import rehypeCodeTitles from 'rehype-code-titles'
+ import rehypePrism from 'rehype-prism-plus'
+ import { rehypeAccessibleEmojis } from 'rehype-accessible-emojis'

// ...

export default makeSource({
  mdx: {
-    remarkPlugins: [],
+    remarkPlugins: [remarkGfm],
-    rehypePlugins: [],
+    rehypePlugins: [
+      rehypeSlug,
+      rehypeCodeTitles,
+      rehypePrism,
+      rehypeAutolinkHeadings,
+      rehypeAccessibleEmojis,
    ],
  },
})

感谢访问我的站点!

编辑此页
最后更新于144 天之前
icon©2022