用 NextJS 重构

杂谈 | 共 2137 字 | 2024/8/13 发表 | 2024/8/13 更新

我一直都想把这个网站做好,大一实习学React和NextJS的就想用NextJS替换掉旧时代的Hugo了,也一直想多写点什么优质内容。然而不知不觉竟然毕业后又过了一年,我却还什么都没做。

主题

我比较喜欢bulma这个css库,很简洁也很好上手,之前的Hugo版本就是用的bulma,所以这次也继续用了。其实我大一的时候写的「临高启明公开图书馆」也是同样的设计,而且是NextJS的(虽然最早好像是Gatsby)。所以这次重构我基本就是把这两个网站融合一下,还用TypeScript重写了,虽然有些不必要的麻烦但还是想尽量避免屎山。

另外NextJS新出了一个App Router,乍一看不错,其实似乎主要是SSR相关的改进,对静态网站好像没什么用。而且还有些兼容性问题,比如APlayer的状态不会改变,所以我还是用传统的Pages Router。

APlayer

我一直喜欢个人网站上放个音乐播放器(虽然可能有些版权问题),所以我之前Hugo的版本就在首页和一些页面里放了APlayer。只需要几行script和一些config就能把一个简洁却精美的音乐播放器植入网页,缺点是每个网页的播放器是独立的,想浏览其他网页当前的播放器就没了。而现代的React SPA就可以很好的解决问题,但APlayer和相关的库已经很久没维护了,我遇到了前文提到的NextJS的兼容性问题。我试了很多React的APlayer库都没有合适的解决方案,最后还是用APlayer的官方库,然后利用useEffect在client的浏览器里动态导入库(不是NextJS的Dynamic Loadingnext/dynamic),最终效果还是不错的。

// 是的我还是用了any :(
export function AudioPlayer(props: { id: string; audio: any; fixed: boolean }) {
  const { id, audio, fixed } = props

  useEffect(() => {
    async function initAPlayer() {
      // @ts-ignore
      const APlayer = (await import('aplayer')).default
      const ap = new APlayer({
        container: document.getElementById(id),
        fixed: fixed,
        audio: audio,
      })
    }

    initAPlayer()
  }, [id, audio, fixed])

MDX?

我想用React/NextJS的另一个原因就是可以很方便的用MDX,感觉文章里面穿插一些自己写的动态的组件会很酷,所以一开始就按照NextJS的官方MDX教程写了半天。但后来发现还是有兼容性问题,首先我之前的markdown都是有frontmatter的,还是要先读完用gray-matter处理一遍。其次我之前会在markdown里插入一些html,而mdx并不支持。所以我最后还是用了之前临高启明公开图使馆的micromark,还是挺好用的。

Giscus

之前Hugo版本的评论系统用的是cusdis,但和micromark一样,作者最近好像没有怎么维护。而且我这些把之前文章的路径都改了一下,cusdis并不支持修改或者导出,所以之前的评论就只能留在他们的官方服务器上供我回忆了~

所以我这些想尽量用维护比较好,然后部署比较简单的评论系统。之前我见过基于GitHub Issues的utterances感觉不错,不过搜索的时候发现了这个基于GitHub Discussions的giscus,感觉更新看起来更好,索性就用这个了。目前看起来效果不错,主要的问题是需要GitHub账号,而且墙内可能不太好用,不过对大部分我的网站的受众应该不成问题。还有就是不支持匿名评论,不过另一方面也能减少垃圾评论。先用用这个试试看吧,希望大家能多多评论 :)

康威生命游戏

TODO