选型
想搭一个个人博客,要求两点:好看、能折腾。
看了一圈,Hugo 太模板化,Hexo 年代太久。Valaxy 是基于 Vue 3 + Vite 的静态博客框架,主题开发就是写 Vue 组件,对我这种前端出身的人没有学习成本。
在 npm 上翻主题的时候发现了 valaxy-theme-shuimo,水墨风格:宣纸纹理、印章、动态山水画生成。一眼就定了。
初始化
mkdir blog && cd blog
pnpm init
pnpm add valaxy viteValaxy 要求主题名以 valaxy-theme- 开头,但水墨主题发布在 @jobinjia/valaxy-theme-shuimo。用 npm alias 解决:
{
"dependencies": {
"valaxy-theme-shuimo": "npm:@jobinjia/valaxy-theme-shuimo@^1.1.8"
}
}踩坑
坑一:Vite 版本不兼容
valaxy 0.28.x 的子依赖要求 vite 6-7,但 pnpm 默认拉了 vite 8,构建直接报错。在 pnpm-workspace.yaml 里强制锁定版本:
overrides:
vite: "^6.4.3"注意 pnpm 11.x 不读 package.json 的 pnpm 字段,必须写在 pnpm-workspace.yaml 里。
坑二:suncalc 模块加载失败
水墨主题用 suncalc 计算日出日落来驱动天空效果。但 suncalc 是 CJS 模块,Vite 6 的依赖预构建处理后导出为空对象。启动时能看到:
[shuimo-theme] Failed to unwrap suncalc module; shape:在 valaxy.config.ts 里加一行配置:
vite: {
optimizeDeps: {
include: ['suncalc'],
},
}修改后需要清缓存:
rm -rf node_modules/.valaxy node_modules/.vite坑三:Web Worker 构建报错
主题的山水画生成用了 Web Worker(useHeroSceneWorker.ts),Vite 6 默认的 worker format 是 iife,和 code-splitting 冲突,构建时报:
Invalid value "iife" for option "worker.format"加一行配置:
vite: {
worker: {
format: 'es',
},
}坑四:mlly 解析警告
启动时会看到:
WARN Failed to resolve package valaxy-theme-shuimo/package.json
ENOTDIR: not a directory, open '...valaxy.DbAZGdnY.mjs/package.json'这是 valaxy 0.28.x 的已知问题,mlly 库尝试把 .mjs 文件当目录读取。不影响运行,忽略即可。
坑五:pages 目录不存在
valaxy 启动时检查 pages/ 目录,不存在会直接退出。创建好目录结构:
pages/
├── posts/ # 博客文章
│ └── hello.md
└── about.md # 关于页面配置
valaxy.config.ts
关键配置:
decorations.seasonAware: false— 关闭四季飘散花卉,不喜欢花哨decorations.heroLandscape: true— 保留首页山水画stamp.author: '受命,于天,既寿,永昌'— 自定义印章文字
styles/index.css
水墨主题对比度偏低,自定义了一部分 CSS 变量提升文字可读性。
写文章脚本
为了方便,写了个 new.sh 脚本:
./new.sh "文章标题"
./new.sh "文章标题" -t "标签1,标签2" -c "分类"自动生成带 frontmatter 的 markdown 文件,默认标签和分类都是「随笔」,用 $EDITOR 打开直接写。
构建
pnpm build产物在 dist/ 目录,是 SPA 模式的静态站点。用 Nginx 托管,try_files 回退到 index.html 即可。
最终结构
blog/
├── valaxy.config.ts # 主配置
├── site.config.ts # 站点信息
├── package.json # 依赖
├── pnpm-workspace.yaml # pnpm overrides
├── new.sh # 新建文章脚本
├── pages/
│ ├── posts/ # 文章
│ └── about.md
├── styles/
│ └── index.css # 自定义样式
└── dist/ # 构建产物花了多久
断断续续折腾了大概一个下午。大部分时间花在解决 vite 版本和模块兼容性问题上,真正的配置工作其实很少。
现在写文章的流程就是 ./new.sh "标题" → 写正文 → pnpm build → 丢到服务器。简单粗暴,我喜欢。