antd+markdown构建网站

前段时间,一直在做数据分析方面的学习,所以采集不少公开的数据。
所以,打算做一个简单的网站来分享这些采集的数据,也方便其他学习数据分析的同学获取数据。

1. 选型原因

以前做项目用antdantd pro比较多,所以本来打算用antd pro来做一个管理数据的网站。
但是,采集来的数据文件差别很大,数据格式也差别很大,要想展示好数据,估计会在前端上浪费大量的时间。

而本来的目的只是分享数据而已,所以,也想过直接用markdown来做个静态的网站,
每种数据用一个markdown文件介绍即可,markdown格式灵活,编写简单,足以胜任。

但是,markdown的静态网站工具(比如 hugo 之类的),也有很多配置要学习,
而且以后如果有动态的功能要添加功能也不太方便。

于是,最后决定尝试用 antd pro 来搭建网站的整体结构,用markdown文件作为每个不同的页面。
前端是 antd pro 的工程,
后端是golang工程,后端很简单,通过APImarkdown文件内容返回到前端。

之所以这样做,一是因为对 antd pro 比较熟悉,方便以后增加菜单,甚至增加其他功能页面;
二是后端虽然简单,目前只有一个API,但是扩展也方便,比如加认证,权限功能,甚至提供一些分析结果展示的服务也不无可能。

2. markdown渲染

目前的关键就在于markdown的渲染,还好react有现成的markdown的渲染库。

本来以为只要几行代码就可以完成这个网站,然而实际做起来,果然处处有坑。。。

前端需要安装的主要库:

yarn add react-markdown
yarn add remark-gfm

2.1. 默认的渲染

因为是分享为主,对样式没什么特别要求,所以刚开始就直接用默认渲染的方式:

import { PageContainer } from '@ant-design/pro-components';


import { Card } from 'antd';


import React, { useEffect, useState } from 'react';


import ReactMarkdown from 'react-markdown';


import remarkGfm from 'remark-gfm';


const Home: React.FC = () => {
  const [md, handleMD] = useState('loading... ...');


  useEffect(() => {
    fetch('/api/v1/file/markdown/home/home.md')
      .then((resp) => resp.text())
      .then((txt) => handleMD(txt));
  }, [md]);

  return (
    <PageContainer>
    <Card
      style={{
      borderRadius: 8,
    }}
      >
      <ReactMarkdown
    		remarkPlugins={[[remarkGfm, { singleTilde: false }]]}
      >
      	{md}
      </ReactMarkdown>
  </Card>
  </PageContainer>
    );
};

export default Home;

运行之后网页中的效果如下:
image.png
虽说事先预计到默认样式会很朴素,实在没想到会朴素到这个程度。。。
不仅表格和代码部分不突出,连标题也和普通文本一样。
也许是受到antd pro整体的样式的影响,不管怎样,不优化是不行的了。

2.2. 表格的支持

首先要处理的表格的支持,因为打算做的是数据分享的网站,里面有很多介绍数据的表格。

为了覆盖antd样式带来的影响,在github上找了一个专门的markdown css
sindresorhus / github-markdown-css

它有几种css风格可以选择,这里我选择了默认的 github-markdown.css,下载之后放到自己的工程中再引用即可。

import { PageContainer } from '@ant-design/pro-components';


import { Card } from 'antd';


import React, { useEffect, useState } from 'react';


import ReactMarkdown from 'react-markdown';


import remarkGfm from 'remark-gfm';

import './github-markdown.css';

const Home: React.FC = () => {
  // 省略。。。

  return (
    <PageContainer>
      <Card
        style={{
          borderRadius: 8,
        }}
      >
        <ReactMarkdown
          className={'markdown-body'}
          remarkPlugins={[[remarkGfm, { singleTilde: false }]]}
        >
          {md}
        </ReactMarkdown>
      </Card>
    </PageContainer>
  );
};


export default Home;

主要变化就在 上面的第6行和第25行。

加入css之后,效果如下:
image.png

立刻好看了很多,表格可以正常显示了,但是代码没有高亮。

2.3. 代码的支持

接下来解决代码的高亮显示,需要安装:

yarn add remark-code-blocks
yarn add react-syntax-highlighter

然后改造上面代码中的 ReactMarkdown 部分:

import { PageContainer } from '@ant-design/pro-components';


import { Card } from 'antd';


import React, { useEffect, useState } from 'react';


import ReactMarkdown from 'react-markdown';


import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import remarkGfm from 'remark-gfm';
import './github-markdown.css';


const Home: React.FC = () => {
  // 省略。。。

  return (
    <PageContainer>
      <Card
        style={{
          borderRadius: 8,
        }}
      >
        <ReactMarkdown
          className={'markdown-body'}
          remarkPlugins={[[remarkGfm, { singleTilde: false }]]}
          components={{
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            code({ node, inline, className, children, ...props }) {
              const match = /language-(\w+)/.exec(className || '');
              return !inline && match ? (
                <SyntaxHighlighter
                  {...props}
                  // eslint-disable-next-line react/no-children-prop
                  children={String(children).replace(/\n$/, '')}
                  style={oneDark}
                  language={match[1]}
                  PreTag="div"
                />
              ) : (
                <code {...props} className={className}>
                  {children}
                </code>
              );
            },
          }}
        >
          {md}
        </ReactMarkdown>
      </Card>
    </PageContainer>
  );
};

export default Home;

显示效果如下:
image.png
最后的代码部分可以高亮显示了。

2.4. 图片的支持

最后,还有图片显示的支持。
图片的显示markdown本来是支持的,只是图片默认都是原样大小来显示,造成图大字小,显示很不协调。

默认是这样的:
image.png

所以,根据图片的情况,设置其最大宽度:

const Wzry: React.FC = () => {
  // 省略。。。
  return (
    <PageContainer header={{ breadcrumb: {} }}>
      <Card
        style={{
          borderRadius: 8,
        }}
      >
        <ReactMarkdown
          className={'markdown-body'}
          remarkPlugins={[[remarkGfm, { singleTilde: false }]]}
          components={{
            // 省略。。。
            img(props) {
              return <img {...props} style={{ maxWidth: 30 }} />;
            },
          }}
        >
          {md}
        </ReactMarkdown>
      </Card>
    </PageContainer>
  );
};

export default Wzry;


让图片的大小和文字能协调起来:
image.png

3. 后端主要代码

后端比较简单,主要就是用golanggin框架实现了一个返回markdown文件的API

// 路由部分
r.GET("/file/markdown/:filetype/:filename", controller.DownloadFileByName)

// API功能部分
func DownloadFileByName(c *gin.Context) {
	filetype := c.Param("filetype")
	filename := c.Param("filename")

	cnf := config.Get()
	p := path.Join(cnf.File.MarkdownDir, filetype, filename)

	c.File(p)
}

4. 最后

目前这个简单的网站已经发布在 databook.top/
数据都是公开的真实数据,已整理成csv文件(UTF8编码的,windows上直接用excel打开可能会乱码),后续会逐步添加其他类型的数据。

如果用excel打开的话,用导入文件的方式打开,导入文件时别忘了选择UTF8编码。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYlZHmZg' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片