将 hexo 博客迁移至 valaxy

本文最后更新于1 个月前,文中所描述的信息可能已发生改变。

注意注意

本文章作于 valaxy 版本 0.12.2 , 部分内容可能已经过时 , 请结合官方文档一起阅读

前言

在 2022 年 8 月份,我向云游君的 hexo 主题 hexo-theme-yun 提 issue 的时候,他向我提到了 valaxy 这个由他开发的静态博客框架。当时 valaxy 十分先进的技术栈和一些优良特性一下就吸引了我,但是由于我已经使用 hexo 写了很多文章,且 valaxy 也没有迁移文档/工具,所以那时我并没有迁移。

时隔半年,我再去看 valaxy 的时候,它已经基本可用了,文档虽然还是不完整,但是够用。于是我决定将我的 hexo 博客迁移至 valaxy。hexo 这贼船越早下越好

关于 hexo

相信很多博主在搜索“白嫖”建自己的博客网站的时候,第一个了解到的方案就是 hexo + GitHub pages 。hexo 确实经典、成熟,但是却有很多历史问题。功能上不够组件化、体验上不能热更新、性能上构建速度不够快等等。尤其让我感到别扭的是它杂乱的目录结构…尽管已经使用 hexo 三年,我还是决定放弃它了。

关于 valaxy

这是一个各种意义上很新的东西,主要由云游君开发,它的目标是成为下一代静态博客框架。

关于 valaxy 的介绍可以在下面获取

但是 valaxy 并不旨在成为下一代的 hexo ,也就是说并不向着与 hexo 的兼容的方向开发。因此迁移起来并不是特别简单。


创建 valaxy 项目

环境

Valaxy 要求 Node.js 的 14.18 以上,如果你是从 hexo 的较新版本迁移的,一般不需要去升级。

valaxy 建议使用 pnpm 作为包管理器,使用 npm i -g pnpm 全局安装它

创建

在工作文件夹下,使用以下命令

shell
pnpm create valaxy

然后输入你的博客文件夹名,同时也是项目名称,默认为 valaxy-blog。我这里使用 valaxy-demo

输入项目名称

随后询问是否现在安装并启动,确定。

询问是否安装并启动

很快就完成了项目创建,此时可以在终端中按 o 打开浏览器预览

预览

进入创建好的项目文件夹,使用以下命令安装依赖

shell
# install
pnpm i

命令

valaxy 在默认局部配置脚本下的一些命令

开启本地开发环境(预览,支持热重载)

shell
pnpm run dev

构建静态文件

shell
pnpm run build

升级(pnpm 交互升级命令)

shell
# upgrade valaxy
pnpm up --latest -i

新建文章

shell
pnpm new post-title

修改配置

在此简要了解一下目录结构,见下图

valaxy目录结构

其中 valaxy.config.ts 是主要需要修改的配置。建议使用 VSCode 编辑它,并按照提示安装推荐的插件。

valaxy.config.ts 提供了完备的类型提示,这意味着你在 VSCode 中可以直接鼠标悬浮查看各参数注释。

默认有些配置项未在 valaxy.config.ts 中给出,使用的是默认值,可以自己添加上就可以覆盖默认值。

站点与作者信息

站点与作者信息配置
  • url: '站点链接'
  • lang: '默认语言(valaxy支持单页国际化)'
  • title: '站点标题'
  • subtitle: '副标题'
  • author:
    • name: '博主名字'
    • avatar: '头像地址'
    • status:
      • emoji: '一个emoji'
      • message: '状态说明'
  • mode: '默认颜色模式'
  • lastUpdated: '开启最近更新:true'
  • favicon: '站点图标地址'
  • description: '描述'

示例:

ts
  url: 'http://krau.top',
  lang: 'zh-CN',
  title: '柯罗krau的博客 | krau\'s blog',
  subtitle: '',
  author: {
    name: '柯罗krau',
    avatar: '/photo/avatar/avatar.jpg',
    status:
    {
      emoji: '😐',
      message: '真不想上学'
  }},
  mode: 'auto',
  lastUpdated: true,
  favicon: '',
  description: '年轻,就要折腾',
  //...

社交链接

  • social
    • name: '名称'
    • link: '链接'
    • icon: '图标'
    • color: '颜色'

示例:

ts
social: [
    {
      name: 'RSS',
      link: '/atom.xml',
      icon: 'i-ri-rss-line',
      color: 'orange',
    },
    {
      name: 'GitHub',
      link: 'https://github.com/krau',
      icon: 'i-ri-github-line',
      color: '#6e5494',
    },
    {
      name: '网易云音乐',
      link: 'https://music.163.com/#/user/home?id=1428613796',
      icon: 'i-ri-netease-cloud-music-line',
      color: '#C20C0C',
    },
    {
      name: '哔哩哔哩',
      link: 'https://space.bilibili.com/296036767',
      icon: 'i-ri-bilibili-line',
      color: '#FF8EB3',
    },
    {
      name: 'Telegram Channel',
      link: 'https://t.me/acherkrau',
      icon: 'i-ri-telegram-line',
      color: '#0088CC',
    },
    {
      name: 'Telegram Group',
      link: 'https://t.me/blogszh',
      icon: 'i-ri:telegram-fill',
      color: '"#0088CC'
    },
    {
      name: 'E-Mail',
      link: 'mailto:[email protected]',
      icon: 'i-ri-mail-line',
      color: '#8E71C1',
    },
    {
      name: 'Travelling',
      link: 'https://www.travellings.cn/go.html',
      icon: 'i-ri-train-line',
      color: 'var(--va-c-text)',
    },
  ],

搜索

  • search
    • enable: 开启搜索功能:true
    • type: '搜索方式:local|engine|algolia'

示例:

ts
  search: {
    enable: true,
    type: 'engine',
  },

赞助

  • sponsor
    • enable: true|false
    • title: '赞助标题'
    • methods
      • name: '赞助方式名称'
      • url: '链接'
      • color: '颜色'
      • icon: '图标'

示例:

ts
  sponsor: {
    enable: false,
    title: '我很可爱,请给我钱!',
    methods: [
      {
        name: '支付宝',
        url: '',
        color: '#00A3EE',
        icon: 'i-ri-alipay-line',
      },
      {
        name: 'QQ 支付',
        url: '',
        color: '#12B7F5',
        icon: 'i-ri-qq-line',
      },
      {
        name: '微信支付',
        url: '',
        color: '#2DC100',
        icon: 'i-ri-wechat-pay-line',
      },
    ],
  },

yun主题配置

valaxy 目前默认主题是 yun

  • theme: '主题名称'
  • themeConfig
    • banner
      • enable: 是否开启首页标题动画:true|false
      • title: '标题'
    • bg_image:
      • enable: 是否开启背景图:true|false
      • url: '背景图链接'
      • dark: '深色模式下的背景图'
      • opactity: 背景不透明度:float
    • colors:
      • primary: '主题色,支持16进制任意配色'
    • say:
      • enable: 是否开启一言:true|false
      • api: '一言api地址,可留空使用默认'
    • pages //页面配置
      • name: '名称'
      • url: '路径|链接'
      • icon: '图标'
      • color: '颜色'
    • footer
      • since: 网站开始年份
      • beian
        • enable: 是否开启备案信息显示:true|false
        • icp: '备案信息'

示例:

ts
  theme: 'yun',

  themeConfig: {
    banner: {
      enable: true,
      title: '柯罗の自留地',
    },
    bg_image: {
      enable: true,
      url: '/photo/bg/atri.webp',
      dark: '/photo/bg/bg.webp',
      opacity: 0.7
    },
    colors: {
      primary: '#39c5bb'
    },
    say:{
      enable: false
    },
    pages: [
      {
        name: '友人帐',
        url: '/links/',
        icon: 'i-ri-genderless-line',
        color: 'dodgerblue',
      },
      {
        name: 'My Love',
        url: '/girls/',
        icon: 'i-ri-women-line',
        color: 'hotpink',
      },
    ],

    footer: {
      since: 2020,
      beian: {
        enable: false,
        icp: '苏ICP备17038157号',
      },

    },
  },

评论

valaxy 通过插件的方式实现评论,目前实现了对 waline 的支持

ts
  comment: {
    enable: true,
  },

  addons: [
    addonWaline({
      serverURL: '后端链接',
      //以下功能未实现,但可以先写进配置里
      pageview: true,
      dark: 'auto',
      requiredMeta: ['nick','mail'],
      locale:{
        placeholder: '填写邮箱,可以收到回复通知~'
      }
        
    }),
  ],

完整配置文件示例

ts
import { defineConfig } from 'valaxy'
import type { ThemeConfig } from 'valaxy-theme-yun'
import { addonWaline } from 'valaxy-addon-waline'
//import { defineConfig } from 'vite'
// add icons what you will need

/**
 * User Config
 */

export default defineConfig<ThemeConfig>({
  url: 'https://krau.top',
  lang: 'zh-CN',
  title: '柯罗krau的博客 | krau\'s blog',
  subtitle: '',
  author: {
    name: '柯罗krau',
    avatar: '/photo/avatar/avatar.jpg',
    status:
    {
      emoji: '😐',
      message: '真不想上学'
  }},
  mode: 'auto',
  lastUpdated: true,
  favicon: '',
  description: '年轻,就要折腾',
  social: [
    {
      name: 'RSS',
      link: '/atom.xml',
      icon: 'i-ri-rss-line',
      color: 'orange',
    },
    {
      name: 'GitHub',
      link: 'https://github.com/krau',
      icon: 'i-ri-github-line',
      color: '#6e5494',
    },
    {
      name: '网易云音乐',
      link: 'https://music.163.com/#/user/home?id=1428613796',
      icon: 'i-ri-netease-cloud-music-line',
      color: '#C20C0C',
    },
    {
      name: '哔哩哔哩',
      link: 'https://space.bilibili.com/296036767',
      icon: 'i-ri-bilibili-line',
      color: '#FF8EB3',
    },
    {
      name: 'Telegram Channel',
      link: 'https://t.me/acherkrau',
      icon: 'i-ri-telegram-line',
      color: '#0088CC',
    },
    {
      name: 'Telegram Group',
      link: 'https://t.me/blogszh',
      icon: 'i-ri:telegram-fill',
      color: '"#0088CC'
    },
    {
      name: 'E-Mail',
      link: 'mailto:[email protected]',
      icon: 'i-ri-mail-line',
      color: '#8E71C1',
    },
    {
      name: 'Travelling',
      link: 'https://www.travellings.cn/go.html',
      icon: 'i-ri-train-line',
      color: 'var(--va-c-text)',
    },
  ],

  search: {
    enable: true,
    type: 'engine',
  },

  sponsor: {
    enable: false,
    title: '我很可爱,请给我钱!',
    methods: [
      {
        name: '支付宝',
        url: '',
        color: '#00A3EE',
        icon: 'i-ri-alipay-line',
      },
      {
        name: 'QQ 支付',
        url: '',
        color: '#12B7F5',
        icon: 'i-ri-qq-line',
      },
      {
        name: '微信支付',
        url: '',
        color: '#2DC100',
        icon: 'i-ri-wechat-pay-line',
      },
    ],
  },

  theme: 'yun',

  themeConfig: {
    banner: {
      enable: true,
      title: '柯罗の自留地',
    },
    bg_image: {
      enable: true,
      url: '/photo/bg/atri.webp',
      dark: '/photo/bg/bg.webp',
      opacity: 0.7
    },
    colors: {
      primary: '#39c5bb'
    },
    say:{
      enable: false
    },
    pages: [
      {
        name: '友人帐',
        url: '/links/',
        icon: 'i-ri-genderless-line',
        color: 'dodgerblue',
      },
      {
        name: 'My Love',
        url: '/girls/',
        icon: 'i-ri-women-line',
        color: 'hotpink',
      },
    ],

    footer: {
      since: 2020,
      beian: {
        enable: false,
        icp: '苏ICP备17038157号',
      },

    },
  },

  unocss: {
    safelist: [
      'i-ri-home-line',
    ],
  },

  comment: {
    enable: true,
  },

  addons: [
    addonWaline({
      serverURL: 'https://后端',
      pageview: true,
      dark: 'auto',
      requiredMeta: ['nick','mail'],
      locale:{
        placeholder: '填写邮箱,可以收到回复通知~'
      }
        
    }),
  ],
})

迁移文章

批量修改 frontmatter

由于原先在 hexo 的文章有太多 valaxy 不支持的 frontmatter 项,所以需要批量修改它们,以免引起奇怪的问题

由于文章数多,所以写个简单的脚本批量操作

需要先安装 python-frontmatter

shell
pip3 install python-frontmatter
python
import frontmatter
import glob

path = 'posts' #你的文章路径,相对于该脚本
mds = glob.glob(f'./{path}/*.md')

def del_metedata(md: str, key: str | list):
    post = frontmatter.load(md)
    metedata = post.metadata
    try:
        if isinstance(key, list):
            for k in key:
                try:
                    del metedata[k]
                except:
                    continue
        elif isinstance(key, str):
            del metedata[key]
        else:
            raise TypeError('key 是 str 或 list')
        frontmatter.dump(post, md)
    except Exception as e:
        print(f'{e}{md}')


def add_metedata(md: str, key: str, value: str):
    post = frontmatter.load(md)
    metedata = post.metadata
    try:
        metedata[key] = value
        frontmatter.dump(post, md)
    except Exception as e:
        print(f'{e}{md}')

def main():
    del_keys = [
        #要删除的项,你可以根据需要修改
        'toc',
        'abbrlink',
        'mathjax',
        'author',
        'hide',
        'sitemap',
        'indexing',
        'top',
        'password',
        'summary',
        'comments',
        'reward',
        'license',
        'edit',
        'copyright',
        'sticky',
        'description'
    ]
    for md in mds:
        del_metedata(md,del_keys)
        #添加你需要的项,如添加 layout: post
        add_metedata(md, 'layout', 'post')


if __name__ == '__main__':
    main()

修改文章内图片路径

如果你全站都使用的图床,可以忽略这一步。而我为了方便管理,把图片放在了本地,所以需要修改

原先是在 hexo 的 source 目录下,需要使用相对路径引用。而 valaxy 可以直接引用静态文件夹(public)内的文件,直接使用 /xxxx 即可

例如,我原先的图片路径是

../photos/post-pics/1.webp

那么只需要将原先在 hexo 博客目录的 photos 文件夹移动到 valaxy 的 public 文件夹下,然后将路径修改为

/photos/post-pics/1.webp

这里的修改可以使用 VSCode 的全局关键字替换功能

移动文章

把文章移动到 博客文件夹/pages/posts 下即可

但是我在操作的时候发现,一次性塞进去太多文章会导致预览页面加载不出来,这可能是一个 bug (版本 0.12.2 )。当然构建是没问题的,所以如果你不需要本地预览的话,可以直接都丢进去。

迁移友联页面

valaxy 的 yun 主题的友联页面在 pages/links/index.md,在 frontmatter 里配置就可以了,参考 valaxy-theme-yun 文档

注意 frontmatter 的下面要写一个

html
<YunLinks :links="frontmatter.links" :random="frontmatter.random" />

迁移 girls 页面

hexo-theme-yun 的配置相同,但是 frontmatter 下面要加上

html
<YunGirls :girls="frontmatter.girls" :random="frontmatter.random" />

哪来的二次元


这样就完成迁移了。如果有其他问题,或者需要更多信息,可以对比云游君的博客仓库中 hexo 和 valaxy 分支的差异。或者提出 issue 、提出讨论 ,以及在我博客下评论留言。

使用ShareX和Markdown Image自动压缩截图为WebP格式并一键插入Markdown文档
使用Python写一个Telegram bot吧|Telegram bot教程
Valaxy v0.18.4 驱动 | 主题 - Yun v0.18.4
本站已勉强运行0 天0 小时0 分0 秒(ノ`Д)ノ