-
Material UI
主要是为了移动端适配,Material UI 提供的一些 React Component 对于页面的实现会方便很多,并且我也需要使用一些 Material UI 的 icon
-
react-markdown
下载量最高的 markdown 第三方库是 marked,不过我简单查了一下,我觉得对我的需求来说,marked 有这么几个问题:
-
无法完全发挥 Next 的优势
Next 提供了一个名为 Image
的组件,可以根据浏览器对图片进行压缩和优化,如原本使用的样例图片的大小为 320kb,并且格式是 jepg
:
但是将图片转化为 Image
的组件之后,Next.js 对图片进行了优化,将原本的 jpeg 转换成了 webp,格式也从原来的 320 减少到了 191kb:
在响应式(移动端)上,图片格式更是减少到了 134kb:
这种优化就能够极大地提高用户体验。可惜 marked 是一个通用库,没有专门提供对 Next.js 的接口。
-
需要使用 refs
如果非得做优化,那么使用 refs 应该也可以……不过如非必要,我就不适用 refs。
-
code style 的优化比较难做
marked 使用的方法是传 class
进去,不过这样就肯定需要操作 refs 了……
从官方文档来看,marked 本身对于 code style 也没有做什么优化:
如果自己做优化,那就……感觉更麻烦了。
在有替代品的情况下,有点不值得,而且这个样式不是很符合颜狗的审美。
与之对比的 react-markdown 就开放了组件的重写,目前实现的效果如下:
代码高亮功能和样式是使用另一个库完成的,下文另说,图片部分实现代码为:
const PostContent = ({ post }) => {
const customerComponents = {
p(paragraph) {
const { node } = paragraph;
if (node.children[0].tagName === "img") {
const img = node.children[0].properties;
return (
<div className={classes.image}>
<Image
src={img.src}
alg={img.alt}
width="100%"
height="100%"
layout="responsive"
objectFit="contain"
/>
</div>
);
}
return <p>{paragraph.children}</p>;
},
};
return (
<ReactMarkdown components={customerComponents}>
{post.content}
</ReactMarkdown>
);
};
component
是 react-markdown 开放对组件的重构,这段代码就对传进来的截点做了判断,如果是图片,就是用 Next.js 自带的组件进行渲染,同时完成多端优化,完胜小屏设备进一步压缩图片大小的优化(上面截图有展示)。
-
react-syntax-highlighter
这是代码高亮的插件,react-markdown 原生对代码的支持也挺……朴素的,所以找了这个插件,实现也是通过判断截点是否为 code
,如果是的话就使用 syntax highlighter 重写默认的样式,实现方法如下:
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { darcula } from "react-syntax-highlighter/dist/cjs/styles/prism";
const customerComponents = {
code(code) {
let language = "";
if (code.className) {
language = code.className.split("-")[1];
}
return (
<SyntaxHighlighter language={language} style={darcula}>
{code.children}
</SyntaxHighlighter>
);
},
};
-
gray-matter
这是用来读取 markdown 的 meta data 的插件。不知道 markdown 里面可以添加 meta data 这个功能有多少人了解,hexo 也是使用这种方法进行数据获取。
常用的 YAML 格式如下:
---
title: "Dummy Blog"
date: "2022-04-24"
lastUpdated: "2022-04-25"
---
gray-matter 就是一个可以读取这些 meta data 和 markdown 内容的第三方库,官方文档说明如下:
假设 md 内容为:
---
title: Hello
slug: home
---
<h1>Hello world!</h1>
解析后的内容为:
{
"content": "<h1>Hello world!</h1>",
"data": {
"title": "Hello",
"slug": "home"
}
}
通过这种方式,可以在 meta data 中添加封面的 url,发布日期等,实现起来更加方便也可以统一格式。