许久未更,前些天准备更新内容时,发现ShokaX即将停止对Hexo的支持,正转向Astro。相较于Hexo,Astro的性能更好,功能更强大,且支持多种框架的组件。

虽然官方也给出了搭建与迁移的指南,但我在迁移过程中还是遇到了一些问题,下面是我迁移过程中的一些总结与记录,希望能帮助到有需要的朋友。

环境搭建篇

通常情况下,我们直接frok或者clone官方的ShokaX仓库即可,其官方也提供了Hyc脚手架进行交互式的安装与后期的维护,相关步骤参考项目的README.md即可。但在使用脚手架的过程我也遇到了一些问题:

  1. 运行hyc sync,hyc new "title"等命令时报错。
  2. 在使用其控制台时,不能正确的获取博客内容(实际上是上文sync没正确运行导致的连锁反应)。
    实际上,上述两条问题的主要内容在于缺乏prisma依赖,我的是此原因导致的,所有我们仅需要安装该依赖即可。安装完成后,上述两条问题均能得到解决。
bun install prisma --save-dev

环境的搭建基本没多大问题,搭建完成后其也提供了很多博客内容模板供我们参考。

另外其也支持相似文章推送,但可能由于在linux中,nodejs对显卡调用一直有问题,所以也是一直失败了,且没有相关日志提示,如果有类似问题hyc sync报错,同步失败,可尝试关闭embedding

迁移篇

多数内容官方文档也描述的相当详尽,除了文章内临时链接列表外,其余官网都做了很详细的迁移指南。
关于文章内临时链接列表,我通过简单修改其提供的友链组件实现,相关代码如下

//site: src/components/mdx/Links.astro
---
export interface LinkItem {
  url: string;
  site: string;
  desc: string;
  owner?: string;
  image?: string;
  color?: string;
}

interface Props {
  links: LinkItem[];
}

const { links } = Astro.props;
---

<div class="mdx-article-links">
  {links.map((link) => (
    <a
      href={link.url}
      target="_blank"
      rel="noopener noreferrer"
      class="mdx-link-card"
      style={`--card-color: ${link.color || "#3b82f6"};`}
      title={link.site}
    >
      <img
        class="mdx-link-avatar"
        src={link.image || `https://api.dicebear.com/6.x/initials/svg?seed=${encodeURIComponent(link.site)}`}
        alt={`${link.site} image`}
        loading="lazy"
      />
      <div class="mdx-link-content">
        <div class="mdx-link-title">{link.site}</div>
        <div class="mdx-link-desc">{link.desc}</div>
        {link.owner && <div class="mdx-link-author">{link.owner}</div>}
      </div>
    </a>
  ))}
</div>

src\styles\mdx-components.css中添加如下样式。

.md .mdx-article-links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
  margin: 1.5rem 0;
}

.md .mdx-link-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.1rem 1rem;
  background: var(--bg-secondary, #f8fafc);
  border-radius: 0.75rem;
  text-decoration: none;
  box-shadow: 0 2px 4px color-mix(in srgb, var(--grey-9) 10%, transparent);
  transition: all 0.25s ease;
  color: var(--text-primary, #1e293b);
}

.md .mdx-link-avatar {
  width: 64px;
  height: 64px;
  border-radius: 0.5rem;
  object-fit: cover;
  background: #e2e8f0;
  flex-shrink: 0;
}

.md .mdx-link-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.md .mdx-link-title {
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--card-color);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.md .mdx-link-desc {
  font-size: 0.75rem;
  color: var(--text-secondary, #475569);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.md .mdx-link-author {
  font-size: 0.65rem;
  color: var(--text-muted, #6c757d);
  margin-top: 0.05rem;
}

/* 悬浮效果 */
.md .mdx-link-card:hover {
  background: var(--card-color);
  border-color: var(--card-color);
  transform: translateY(-2px);
  box-shadow: 0 8px 16px -6px rgba(0, 0, 0, 0.1);
}

.md .mdx-link-card:hover .mdx-link-title {
  color: #ffffff;
}

.md .mdx-link-card:hover .mdx-link-desc,
.md .mdx-link-card:hover .mdx-link-author {
  color: rgba(255, 255, 255, 0.85);
}

.md .mdx-link-card:hover .mdx-link-avatar {
  transform: scale(1.02);
}

/* 移动端适配 */
@media (max-width: 640px) {
  .md .mdx-article-links {
    grid-template-columns: 1fr;
    gap: 0.8rem;
  }
  .md .mdx-link-card {
    padding: 0.6rem 0.8rem;
  }
  .md .mdx-link-avatar {
    width: 32px;
    height: 32px;
  }
}

并在astro.config.mjs文件中的AutoImport中声明以实现自动导入。

...
AutoImport({
  imports: [
    "@/components/mdx/Links.astro",
  ]
})
//对于1.6版本请将导入语句切换至对应位置

在文末或者文中,直接使用即可,以下是两种方案,其中第一种可以快速的实现从hexoastro的迁移。

---
title: Hello World
links: 
  - site: Connect a website to a USB, Serial, or HID device
    owner: Google Chrome Help
    url: https://support.google.com/chrome/answer/12576972?hl=en
    desc: 将网站连接到 USB、串行或 HID 设备
    image: https://avatars.githubusercontent.com/u/1342004?s=200&v=4
    color: "#ea4335"
  - site: Writing udev rules
    owner: Daniel Drake
    url: https://www.reactivated.net/writing_udev_rules.html
    desc: Writing udev rules
---
正文内容...
<Links links={frontmatter.links_data}/>

该方案存在弊端,其提供的图片链接仅能是一个外部链接。另一种方案可以使用本地图片,如下所示:

---
title: Hello World
---
import archlinux from "linux-use-mariadb-database/archlinux.jpg";
正文内容...
<Links links={[
  {
    site: "MariaDB - Arch Linux 中文维基",
    owner: "ArchWiki",
    url: "https://wiki.archlinuxcn.org/wiki/MariaDB",
    desc: "Arch Linux 中文维基",
    image: archlinux.src,
    color: "#1793d1"
  },
  {
    site: "MariaDB Documentation",
    owner: "mariadb",
    url: "https://mariadb.org/documentation/",
    desc: "Mariadb 官方文档",
    image: "https://mariadb.org//wp-content/themes/twentynineteen-child/icons/logo_seal.svg",
    color: "#c0765a"
  }
]}/>

如下图,上述两种方式均可复现原hexo中相似的效果。

图片路径篇

hexo不同的是,文中多处的相对链接路径是基于src/posts/文件夹的(自定义组件除外)。所以如果在hexo中迁移其cover字段需进行一定的修改,对于一些自定义组件,可以使用上述代码中的import xxx form 'path'去导入相关资源,并通过xxx.src去获取实际的路径信息。

一些其他的优化

rss订阅功能优化

已在1.6版本支持,现无须配置

友链页增加评论功能

已在1.6版本支持,通过配置src/theme.config.ts友链模块添加"comments": true即可,

评论模块相关内容配置完善

ShokaX的主题配置中,关于评论的配置内容并没有提供完全,我们可以通过修改 src\components\post\WalineComments.svelte 中的相应代码去丰富我们的评论区

...
const waline: WalineInstance | null = init({
  el: walineEl,
  serverURL,
  path: finalPath,
  lang,
  dark,
  //在此处添加更多配置信息
  meta: ["nick", "mail", "link"], // 评论者属性,可选 'nick'、'mail'、'link'
  requiredMeta: [], // 默认为空(昵称非必填)
  wordLimit: 0, // 评论字数限制,0 表示无限制,可设为数字或 [最小, 最大]
  pageSize: 10, // 评论列表分页每页条数
  lang: navigator.language, // 显示语言,如 'zh-CN'、'en'、'jp' 等
  commentSorting: "latest", // 评论排序方式,可选 'latest'、'oldest'、'hottest'
  login: "enable", // 登录模式,可选 'enable'、'disable'、'force'
  noCopyright: false, // 是否隐藏页脚版权信息(不建议隐藏)
  noRss: false, // 是否隐藏 RSS 订阅入口
  recaptchaV3Key: "", // Recaptcha v3 客户端 key
  turnstileKey: "", // Turnstile 客户端 key
  reaction: false, // 文章反应(点赞等),可设为 true、false 或表情数组
  emoji: ["//unpkg.com/@waline/emojis@1.1.0/weibo"], // 表情包设置
  search: false, // 搜索功能,可设为 true、false 或配置对象
  highlighter: null, // 代码块高亮器,自定义函数
  imageUploader: null, // 自定义图片上传方法
  texRenderer: null, // 自定义数学公式渲染方法
});
...

首页/索引页用ai总结替代文章的描述

已在1.6版本完成支持,仅需配置src/theme.config.ts即可

由于本人对前端相关内容并不是很了解,上述的解决方案也肯定不是最优解,仅供参考,如果各位大佬有更好的解决方法,欢迎留言指正,谢谢!

参考资料

本文参考如下内容

Astro Blog ShokaX 文档 imageAstro 官方文档 image