铛铛铛~
大家好,我是 酱酱们的每日掘金 的主理人之一,也是 auto-sync-blog 的主要开发者之一。
该工具在去年 3 月发布了最初的 1.0 版本,当时基于 vuepress 进行的博客构建,由 阿南(南方者) 进行开发。
在今年三月,由 船长(Captaincc) 提出来可以进行一些优化和迭代。
船作为 酱酱团队 的 Leader,他的需求小弟们肯定要第一时间来满足的,所以在 1.0 的基础上直接进行了大量改动,除了核心的数据请求逻辑外其他内容基本都有修改。
那么为了保证大家能够继续使用或者进行二开,我们觉得有必要整一篇文章来对这个工具进行一些说明。
界面预览
大家也可以直接访问 teatools.github.io/auto-sync-b... 或者 tea.juejindev.com/
项目介绍
该工具借助 Github Actions 实现自动发布,默认配置两种触发方式:main
分支更新与 cron
定时任务,默认定时为 0 8 * * *
,也就是每天下午四点自动执行。
主要分为三个步骤:
- 执行 node 任务,抓取指定用户的已发布文章与专栏数据,并按不同维度进行整理
- 根据配置文件,生成对应的 markdown 文件与 vitepress 博客配置
- 根据生成文件,构建 vitepress 项目,并发布构建产物到 Github Page
其中数据分析维度分为:
overview
所有文章与各年度发布文章数量总览column
所有专栏总览与专栏文章集合category
不同文章类型集合tag
不同文章标签集合annual
不同年份文章集合ranking
所有文章阅读、点赞、评论、收藏 Top 10
除 overview 总览页 (也就是主内容页)外,其他几个维度均可以通过 configurations
文件进行控制。
另外,入口页(也就是 vitepress 项目默认首页)增加了 成员卡片,用于显示项目成员信息。
与 1.0 的区别
2.0 版本在数据抓取逻辑上与 1.0 保持一致,但博客工具更新为 vitepress,node 更新为 18+,并且全局替换为 esm 格式。
在数据存储上,使用模块化(也可以理解成就是闭包)的方式将数据存储在内存中,替换了 1.0 中的全局变量。并且在文章和专栏抓取结束之后会重新进行数据处理,将每个文章的发布时间、显示的 md 字符串、跳转链接等直接合并到文章数据中,并取消了 1.0 中的按专栏抓取专栏内文章的请求。
目前保存的数据有以下内容:
articles
:所有文章数据articlesMap
:由文章id
为键生成的Map
对象unColumnArticles
:未收录到专栏中的文章列表columns
:专栏列表columnMap
:由专栏id
与{ articles, columnInfo }
生成的Map
对象yearCollection
:按发布年度整合的 年份-文章列表 的Map
对象yearMonthCollection
:按发布年月整合的 年月-文章列表 的Map
对象tagCollection
:文章标签id
与文章列表的Map
对象categoryCollection
:文章分类id
与文章列表的Map
对象
各位也可以按照自己喜欢的维度进行其他格式的整合。
在数据整合之后,会按照配置文件进行不同的 md 文件生成。所以整体的目录结构也有了很大的变化。
目录结构与执行顺序
目前的目录结构大致如下:
txt
./
├─ LICENSE
├─ package.json
├─ package-lock.json
├─ Q&A.md // 问题统计与解决方法
├─ README.md
├─ README_EN.md
├─ configurations.js // 核心配置文件
├─ build // 构建相关
| └ config.base.js // 生成文件的目录配置
├─ docs // 自动生成的 vitepress 内容
| ├─ .vitepress
| | ├─ config // 由 vitepress.config.generator 生成的内容
| | └ theme // 复制的 theme 样式文件与插件配置
| └ src // 自动生成的所有页面 markdown 文件
├─ works // 核心部分
| ├─ index.js // 脚本执行入口
| ├─ apis // http api 请求地址
| | └ juejin.js
| ├─ generator // 文件生成
| | ├─ juejin
| | | ├─ category.generator.js // 文章分类相关 md 生成
| | | ├─ columns.generator.js // 专栏分类相关 md 生成
| | | ├─ overview.md.generator.js // 主概览页 md 生成
| | | ├─ ranking-list.md.generator.js // 排行榜页 md 生成
| | | ├─ tag.generator.js // 标签分类相关 md 生成
| | | └ year.generator.js // 年度整合相关 md 生成
| | ├─ vitepress
| | | ├─ theme // vitepress 主题配置文件夹
| | | ├─ index.md.generator.js // 主页 md 生成
| | | └ vitepress.generator.js // vitepress 项目 config 文件生成(生成的是 js)
| | └ index.js // 统一导出
| ├─ requests // 网络请求部分
| ├─ store // 全局数据处理与缓存
| ├─ template // 各类模板文件
| | ├─ vitepress
| | | ├─ vitepress.config.js // 生成 .vitepress/config/index.js 文件
| | | └ vitepress.index.md.js // 生成 .vitepress/src/index.md 文件
| | └ index.js // 统一导出
| ├─ utils // 工具函数
| ├─ website // 博客内生成的外链地址的配置信息
由于后续计划开发其他平台的数据统计,所以除 utils
工具函数目录之外,其他 works
内的目录模块中均会按照不同平台创建对应的文件目录(目前只有掘金)。
template
作为模板文件,内部变量由 双大括号 {{ }}
包裹,将会替换为 configurations
中的同名数据。
当执行 npm run sync:blog
时,会执行 work/index.js
。
js
import configurations from "../configurations.js"
import {
processCategoriesOverview,
processColumnsOverview,
processRankingList,
processTagsOverview,
processVitePressConfig,
processVitePressTheme,
} from "./generator/index.js"
import { processVitePressIndexMD, processOverviewMD, processYearsPage } from "./generator/index.js"
// 注意生成顺序
await processVitePressIndexMD()
await processOverviewMD()
const { press } = configurations
const navProcessMap = {
column: processColumnsOverview,
category: processCategoriesOverview,
tag: processTagsOverview,
annual: processYearsPage,
ranking: processRankingList,
}
for (const navKey of press.nav) {
navProcessMap[navKey] && (await navProcessMap[navKey]())
}
// 生成 vite press 配置
await processVitePressConfig()
await processVitePressTheme()
也就是从 generator
开始。
首先生成主要的 index.md
主页文件,主要读取 configurations
中的 blog
和 press
配置,替换模板中的变量,然后将生成内容写入到指定目录下。
然后是 processVitePressIndexMD
生成所有的文章概览。
这个过程中需要首先从 store
中读取文章与专栏等统计数据,触发数据请求。然后按照顺序将所有文章的 md 字符串进行整合,写入到指定目录中。
然后则是根据 configurations
中配置的 press.nav
执行对应的模块文件生成。
最后生成 vitepress
的配置文件和样式文件。
configurations 配置
整个配置文件分为三个部分:blog
、press
和 juejin
。
其中 blog
包含博客网站的名称、描述、ico 等内容,press
则是与 vitepress
相关的配置内容,例如首页的显示文本、背景图、导航栏、社交信息等。
两者有部分内容可能会有重合,但是主要职责不同。
press
中还有一个 members
的配置,用来控制首页成员卡片信息。
juejin
中则是用户在 掘金平台 的用户 id。
使用方式
与 1.0 相比,2.0 增加了很多可配置的内容,并简化了整体的执行逻辑。大家可以自行 fork 仓库,修改 configurations
文件后开启 actions 即可。
当然,必要的还是 PRESS_TOKEN_TEA_BLOG
。
最后
本文到这里就结束啦~如果本文对你有帮助,希望你能点赞收藏,如果文中有不当之处,也希望你能在评论里及时指出,大家的支持也是我前进的动力~~
如果想要关注更多的前端内容,可以关注我的公众号: MiyueFE 的前端圈,或者在 FrontendAskMeAnything 中提出疑问或者参与讨论~
最后,十分感谢大家的阅读!