VitePress站点生成RSS并自动部署刷新阿里云CDN
简述
利用buildEnd构建钩子在站点构建完成后自动上传部署,并刷新静态页面CDN缓存。
在构建钩子中生成RSS并部署
在docs.vitepress\config.mts文件中添加如下设置:
ts
import { defineConfig } from 'vitepress'
import createRssFile from './theme/rss'
import ssh from './theme/ssh'
export default defineConfig({
sitemap: {
hostname: '****'
},
buildEnd(siteConfig) {
//生成rss后ssh上传
createRssFile(siteConfig).then(() => ssh(siteConfig))
},
})
RSS生成脚本
新建ts文件(如docs.vitepress\theme\rss.ts)
ts
import path from "path";
import { writeFileSync } from "fs";
import { Feed } from "feed";
import { createContentLoader, type SiteConfig } from "vitepress";
export default async function createRssFile(config: SiteConfig): Promise<void> {
const hostname = config.sitemap?.hostname || 'https://fuxes.cn'
const feed = new Feed({
title: "****",
description: "****",
id: hostname,
link: hostname,
language: "zh-CH",
image: hostname + "/favicon.ico",
favicon: hostname + "/favicon.ico",
copyright: "****",
});
const posts = await createContentLoader(['**/*.md'], {
includeSrc: true,
excerpt: true,
render: true,
transform(rawData) {
return rawData
.map(e => {
return {
url: e.url,
html: e.html,
excerpt: e.excerpt,
//我的md博文最后都有成文时间,也可用fs.statSync读取文件mtime;
date: new Date(e.src!.slice(-10))
}
})
//检查日期是否有效
.filter(e => !Number.isNaN(e.date.getTime()))
.sort((a, b) => b.date.getTime() - a.date.getTime())
.slice(0, 3)
},
}).load();
for (const { url, excerpt, html, date } of posts) {
const title = url.slice(url.lastIndexOf('/') + 1)
feed.addItem({
title,
id: `${hostname}${url}`,
link: `${hostname}${url}`,
content: html,
author: [
{
name: "****",
email: "****",
link: hostname,
},
],
date: date,
});
}
writeFileSync(path.join(config.outDir, "feed.xml"), feed.rss2(), "utf-8")
console.log('rss build complete')
}
部署后自动刷新CDN
部署脚本具体见Node SSH,在上传文件的回调函数中调用CDN刷新脚本
js
import Cdn from './cdn'
ssh.connect({
//...
}).then(function () {
//...
ssh.putDirectory('D:\\****\\docs\\.vitepress\\dist', '/usr/local/nginx/html', {
//...
}).then(function (status) {
console.log(`deploy ${status ? 'successful' : 'unsuccessful'}:${successful.length},fail:${failed.join(',')}`)
//只需刷新静态网页即可,url列表从构建钩子参数siteConfig的page中获取,也可以用fs递归读取docs文件夹的md文件
let htmls = config.pages.map(e => e.replace(/index\.md$/, '').replace(/\.md$/, ''))
htmls.push('feed.xml')
htmls.push('hashmap.json')
htmls.push('sitemap.xml')
Cdn.refresh(htmls.map(e => config.sitemap?.hostname + '/' + e))
.finally(() => process.exit(1))
})
})
CDN刷新脚本
- 在阿里云访问控制RAM控制台新建用户
- 生成AccessKey,并在环境变量中设置,名称为'ALIBABA_CLOUD_ACCESS_KEY_ID'、'ALIBABA_CLOUD_ACCESS_KEY_SECRET'
- 在阿里云访问控制RAM控制台用户权限管理添加管理CDN的权限AliyunCDNFullAccess
- 安装阿里云SDK
sh
$ npm install --save @alicloud/cdn20180510@5.0.0
$ npm install @alicloud/credentials
$ npm install @alicloud/openapi-client
- 新建js文件(如docs.vitepress\theme\cdn.js)
js
// This file is auto-generated, don't edit it
// 依赖的模块可通过下载工程中的模块依赖文件或右上角的获取 SDK 依赖信息查看
import Cdn20180510 from '@alicloud/cdn20180510'
import OpenApi from '@alicloud/openapi-client'
import Util from '@alicloud/tea-util'
import Credential from '@alicloud/credentials'
class Cdn {
/**
* 使用凭据初始化账号Client
* @return Client
* @throws Exception
*/
//该方法会默认优先读取系统环境变量中的key和secret(设置完环境变量后需重启终端/编辑器刷新)
static createClient() {
let credential = new Credential.default();
let config = new OpenApi.Config({
credential: credential,
});
config.endpoint = `cdn.aliyuncs.com`;
return new Cdn20180510.default(config);
}
static async refresh(urls) {
let client = Cdn.createClient();
let refreshObjectCachesRequest = new Cdn20180510.RefreshObjectCachesRequest({
objectPath: urls.map(e => encodeURI(e)).join('\n'),
objectType: "File",
});
let runtime = new Util.RuntimeOptions({});
try {
// 复制代码运行请自行打印 API 的返回值
await client.refreshObjectCachesWithOptions(refreshObjectCachesRequest, runtime);
console.log(`refresh successful ${urls.length}`)
} catch (error) {
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
console.log(error.message);
// 诊断地址
console.log(error.data["Recommend"]);
Util.default.assertAsString(error.message);
}
}
}
export default Cdn
结语
设置完成,运行命令即可一键生成rss并自动部署刷新。
sh
$ npm run docs:build
正常运行显示如下:
sh
> docs:build
> vitepress build docs
vitepress v1.5.0
✓ building client + server bundles...
✓ rendering pages...
✓ generating sitemap...
build complete in 5.06s.
rss build complete
deploy successful:**,fail:
refresh successful **
2025-04-25