闲来无事,研究了一下vuepress2和它的插件机制,写了一个可以一键通过已有博客生成vuepress2的文档站的vuepress2插件vuepress-plugin-blog-sync
效果
在vuepress2中简单引入即可达到将政采云掘金博客一键生成vuepress2页面,效果✨ 详见Demo
使用
安装插件
代码语言:javascript复制npm i vuepress-plugin-blog-sync
按照vuepress文档初始化后,vuepress.config.ts
中修改成如下配置引入插件即可达到效果
// vuepress.config.ts
import { defaultTheme, defineUserConfig } from 'vuepress'
import { blogSyncPlugin } from 'vuepress-plugin-blog-sync'
export default defineUserConfig({
lang: 'zh-CN',
title: 'vuepress-plugin-blog-sync Demo',
description: 'Input juejin/csdn/github/etc, output vuepress2 web site',
base: '/vuepress-plugin-blog-sync/',
plugins: [
blogSyncPlugin({
syncConfig: {
type: 'juejin',
userId: '3456520257288974',
},
}),
],
theme: defaultTheme({
navbar: [{
text: 'Github',
link: 'https://github.com/flytam/vuepress-plugin-blog-sync',
}],
}),
})
实现
主要利用了之前自己开发的csdnsynchexo提供的爬取网站文章的能力结合vuepress2提供的插件能力,150行代码即可实现,源码详见,下面简单介绍下相关实现点
文章拉取
在vuepress2的onInitialized中进行拉取(使用csdnsynchexo提供的run函数),并进行相关的数据处理,然后通过插件传递的app实例往app.pages
中添加我们拉取回来的文章信息,这里按照category作为路由分类
自动生成目录页
为了便于统一导航,设计了一个目录页的自动生成的逻辑,同时用户也可以自己传递generateContent
进行目录页的内容生成
自动生成navbar
vuepress2的插件不再提供配置导航栏的相关api。对于默认主题,提供了在config文件中类似以下的配置能力
代码语言:javascript复制export default defineUserConfig({
// ...
theme: defaultTheme({
navbar: [{
text: 'Github',
link: 'https://github.com/flytam/vuepress-plugin-blog-sync',
}],
}),
})
// ...
通过查阅vuepress2源码我们可以得知。vuepress2在node侧编译时,会将主题的themeData
相关信息输出到一个本地文件,在客户端打包时去引用该文件获取到navbar相关信息进行渲染导航栏
输出themeData
信息到一个本地文件
显而易见,如果我们需要根据文章目录自动生成导航,就需要在生命周期中去将我们需要生成的导航信息写入到该文件的指定字段
经过查阅文档和调试,可以在onPreparedhook中进行实现。并设计了默认会自动按照文章分类进行生成导航,也可以用户自己传递自定义函数来生成该导航的逻辑,自定义函数的两个入参分别是原来的导航对象和我们处理好的文章信息,返回一个新的导航对象用于替换掉原先的导航对象
代码语言:javascript复制{
/**
* 是否根据文章category自动生成navbar
* 默认主题
* @default true
*/
navbar?: {
custom?: (originNavbarConfig: DefaultThemeData['navbar'], blogMetaContext: BlogMetaContext) => DefaultThemeData['navbar']
} | false
}
为了保证对代码文件修改操作的稳定性,这里引入babel进行ast转换进行修改该字段并修改,修改完成后写入原来的internal/themeData
文件
最后
然后就搞定了。整个功能还是比较简单的。通过这样一个简单的插件编写,就能实现一个非常好玩的功能,并且也了解到vuepress2的源码和架构。还是挺不错的