lovchun.com
love
缺省字母e
;
站点由哪些所构建
我曾使用过的技术栈
客户端
Gulp
Webpack
Nodejs
Vuejs
Reactjs
Nextjs
Typescript
Miniprogram
服务端
PHP
: Codeigniter、Laravel、ThinkPHP、PhalconPython
: Flask、DjangoNestjs
Docker
Nginx
Mysql
Memcache
Supervisor
我这几年的工作
涉及过金融、邮箱、网站、新零售等业务。
早先 PHP
+ Require.js
+ jQuery
+ Bootstrap
全栈工作了三年,后面 Angular
横空出世,再到 Reactjs
和 Vuejs
,前后端分离趋势流行后,便一直在前端领域摸爬滚打,精通基于 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,它的运行原理大概如下:
这个库还是 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
代码标题
export async function getStaticPaths() {
return {
// dynamic paths
paths: allPosts.map(() => ({
params: { slug: post.slug.split('/') }
}))
// fallback set false
fallback: false,
}
}
高亮行
export async function getStaticPaths() {
return {
// dynamic paths
paths: allPosts.map(() => ({
params: { slug: post.slug.split('/') }
}))
// fallback set false
fallback: false,
}
}
显示行号
export async function getStaticPaths() {
return {
// dynamic paths
paths: allPosts.map(() => ({
params: { slug: post.slug.split('/') }
}))
// fallback set false
fallback: false,
}
}
显示差异
+ 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,
],
},
})
感谢访问我的站点!