V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
RiddMa
V2EX  ›  分享创造

使用 Next.js + Velite 搭建基于 Git 和 GitHub Actions CI/CD 的自部署博客,自定义 Markdown 渲染管线等。持续更新教程,欢迎围观

  •  1
     
  •   RiddMa · 21 天前 · 1501 次点击

    最近上线了新版博客 riddma.com,更新了技术栈,并打算以此写一系列教程,也是记录一下自己折腾博客技术栈这么多年(却还没有写几篇正经文章)的经验。

    我对博客的要求:

    • 数据与系统分离,Markdown 记录文章保存在本地,与各类笔记/知识库软件无痛迁移。
    • 无外部数据库等依赖,最好一个 Git 仓库带着走。
    • 表现力强,支持各种富文本和动态组件,超越原生 Markdown 能力。
    • 能方便地扩展各种动态页面,从静态博客变为动态个人主页。
    • 技术栈现代化,界面美观,动效丰富。

    基于以上考虑,我选择的技术栈:

    • 前后端:Next.js 14 (App Router) + remark-rehype 自定义 Markdown 渲染管线
    • 数据库:Prisma + SQLite
    • 美化:Tailwind CSS + DaisyUI + NextUI + Framer Motion + GSAP
    • CMS:基于 Git 和 Velite 的 Serverless 架构
    • LLM:Deepseek-V2
    • 部署:GitHub Actions CI/CD + VPS Self-Host (也支持 Vercel 一键部署)

    这套技术栈适合需要完全自定义博客外观和功能,不怕折腾并且对前端有一定熟悉程度的人。博客代码开源,还在开发,有很多 bug ,李姐万岁。

    后续会在 从零开始的现代化个人博客搭建指南 专栏中持续更新文章,预计会包含一篇总览性的概述,和若干踩坑点的问题解决等。此外,我也会更新一些发烧级 HomeServer/NAS 装机经验( ProxmoxVE ,TrueNAS Scale 系统)、软硬路由器和 OpenWRT 的折腾经验等,欢迎持续关注或者催更)))

    第一次发帖,不知道有人看吗……

    21 条回复    2024-06-05 15:55:34 +08:00
    terranboy
        1
    terranboy  
       21 天前
    一个博客有必要用这么多东西吗 Tailwind CSS + DaisyUI + NextUI + Framer Motion + GSAP
    Track13
        2
    Track13  
       21 天前
    ...为什么不用 mdx ,自定义 md 指令,麻烦还不好看。
    RiddMa
        3
    RiddMa  
    OP
       21 天前
    @Track13 MDX 语法不完全兼容 Markdown ,并且编译不过就完全不能输出内容,更像是和 TS 的“硬链接”。自定义指令像是软链接。我试过使用 MDX.js ,然后弃坑了。现在这个方案最适合我
    RiddMa
        4
    RiddMa  
    OP
       21 天前
    @terranboy 生命在于折腾,趁着还能折腾动的时候,hh
    YAZAKI
        5
    YAZAKI  
       21 天前
    强!
    Track13
        6
    Track13  
       21 天前
    @RiddMa 哪些语法不支持?我加上 gfm 插件后没感觉有不支持的。
    RiddMa
        7
    RiddMa  
    OP
       21 天前
    @Track13 不是不支持,是不完全兼容,主要原因是有特殊字符需要转义,所以从 Markdown 迁移的文档会报错。转义比较麻烦,而且转义之后的文本看起来不是很美观。

    下面是 GPT 给的例子:

    在将 Markdown 文档转换为 MDX 时,某些内容可能需要额外的转义以确保正确解析。主要需要注意以下几点:

    1. **JSX 标签:** 如果在你的 Markdown 文档中包含类似 JSX 标签的内容,这些内容需要被正确转义或处理,以避免与实际 JSX 语法冲突。例如,如果有 `<tag>` 这样的内容,可能需要将其转义为 `{'<tag>'}`。

    2. **Curly Braces (大括号):** 在 MDX 中,大括号 `{}` 通常用于插入 JavaScript 表达式或 JSX 语法。因此,在普通文本中使用大括号需要小心。例如,`{` 和 `}` 在 MDX 中需要转义成 `{'{'}` 和 `{'}'}`。

    3. **嵌套内容:** Markdown 的嵌套列表、嵌套代码块等复杂结构在 MDX 中使用时,可能需要特别注意其语法是否与 JSX 冲突。例如,嵌套代码块中的 JSX 标签可能需要通过转义来处理。

    4. **HTML 标签:** 如果你的 Markdown 文档中包含原始 HTML 标签,确保这些标签不会与 JSX 标签冲突。例如,如果你有 `<div>` 标签,可以考虑使用 JSX 的方式 `<div></div>` 或者转义为 `{'<div>'}`。

    5. **Inline Code 和代码块:** 在 Markdown 中使用反引号(`` ` ``)来标记内联代码和代码块时,如果代码块中包含 JSX 语法,需要确保它们被正确解析。例如,内联代码中的 JSX 语法可能需要转义:
    ```mdx
    Here is some inline code: `const element = <MyComponent />`
    ```
    可能需要写成:
    ```mdx
    Here is some inline code: `const element = {'<MyComponent />'}`
    ```

    以下是一些具体的例子,展示了如何在 MDX 中处理这些情况:

    ### 原始 Markdown 示例
    ```markdown
    # 标题

    这是一个段落,其中包含一些特殊字符 < 和 >。

    <div>这是一个 HTML 标签</div>

    这是一个内联代码 `const element = <Component />`。

    这是一个代码块:

    ```
    const element = <Component />;
    ```
    ```

    ### 转换为 MDX 示例
    ```mdx
    # 标题

    这是一个段落,其中包含一些特殊字符 {'<'} 和 {'>'}。

    <div>这是一个 HTML 标签</div>

    这是一个内联代码 `const element = {'<Component />'}`。

    这是一个代码块:

    ```javascript
    const element = {'<Component />'};
    ```
    ```

    通过以上示例可以看出,主要需要注意的就是在 JSX 语法和 Markdown 特性之间保持正确的转义和解析,以确保 MDX 文件能够正常工作。
    Track13
        8
    Track13  
       21 天前
    @RiddMa 明白了,不过我没有遇到例子中的情况。
    ShuWei
        9
    ShuWei  
       20 天前
    astro 好像是更好的选择
    RiddMa
        10
    RiddMa  
    OP
       20 天前
    @ShuWei 有看到过,但没有深入了解。我理解 Astro 主要面向静态网页 SSG ,有一些担心它的动态能力,毕竟我这边用到了 Next.js 的后端和 Prisma ORM 。此外 .astro 魔改 HTML 语法相较 React 通用的 .tsx 也有一定学习和迁移成本,综合考虑一下,还是选了 Next.js 感觉最稳妥。如果您有 Astro 相关实践对比,请不吝赐教。
    ShuWei
        11
    ShuWei  
       20 天前
    @RiddMa 当你的目的不是做一个博客的时候,可以继续越复杂越好
    Amose2024
        12
    Amose2024  
       19 天前
    有点不相信你折腾了几年-.-,登录鉴权没有,错误页没有,Admin 没有,Api 和数据存储逻辑约等于没有,而为了所谓动效竟然使用那么 UI 框架。。。如果真是有几年功夫,js+tailwindcss 什么效果会写不出来呢?一堆框架不怕降低性能么?有可能你只是自学了一些前端知识,而不是真的程序员啊。
    RiddMa
        13
    RiddMa  
    OP
       19 天前 via iPhone
    @Amose2024 😂我确实不是程序员,不过是 CS 本硕,还没毕业呢。折腾几年一共用过六七个博客方案,现在这个项目写了大概一个多月,确实有很多不完善的地方。我之前也用过无头 WordPress 、Strapi 和 TinaCMS 当后端,现在不用 CMS 的目的就是抛弃 Admin 页面和后端 API ,管理数据完全依靠文件系统和 Git ,我觉得这样更方便。存储逻辑这块是依靠 Velite 生成 TS 类型,博客数据直接是静态生成的 Object 数组。UI 框架确实有点多,正在逐步剔除,不过有 treeshaking 性能感觉也还可以接受……
    x2420390517
        14
    x2420390517  
       19 天前
    @RiddMa #10 https://astro.build/themes/ 很多好的主题,哪来改改,自己定义一些需要的功能就很好
    x2420390517
        15
    x2420390517  
       19 天前
    我现在用 git 存博客,是因为我希望后面哪天我服务器不续约了,我的博客也还能跑,这是我用 astro 主题改的 https://blog.ll1025.cn/
    davin
        16
    davin  
       19 天前
    重构 N 次,决不再改!
    相信我,你接下来还会改的😄
    gaocc
        17
    gaocc  
       18 天前
    配色有点怪,有 UI 同事嘛,可以问问。或者国外火点的博客抄个配色。

    另外能告知维护成本嘛?😩自己搞的服务器成本每年 1k 极限了,域名续费太贵都放弃了
    lozzow
        18
    lozzow  
       18 天前
    挺好看的哈哈,效果也很简洁高效
    RiddMa
        19
    RiddMa  
    OP
       18 天前
    @x2420390517 博客很简洁,响应也很快,感谢推荐,学习了
    RiddMa
        20
    RiddMa  
    OP
       18 天前
    @gaocc 不专业哇…配色配着玩的,楼里有推荐主题的我去抄个试试 hh 。
    维护成本:riddma.com 域名一年 10 刀,在 namesilo 买的。服务器是搬瓦工 JP ,一年 50 刀的丐中丐,只是图它网好。
    txzh007
        21
    txzh007  
       17 天前
    @gaocc .link 域名很便宜 博客服务器 1c1g 都能搞,国内轻量套 cf 壳成本不过一两百
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2324 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 10:51 · PVG 18:51 · LAX 03:51 · JFK 06:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.