【TeaTools/auto-sync-blog】掘金下午茶团队自动化掘金文章同步工具 2.0 发布啦~~

铛铛铛~

大家好,我是 酱酱们的每日掘金 的主理人之一,也是 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 * * *,也就是每天下午四点自动执行。

主要分为三个步骤:

  1. 执行 node 任务,抓取指定用户的已发布文章与专栏数据,并按不同维度进行整理
  2. 根据配置文件,生成对应的 markdown 文件与 vitepress 博客配置
  3. 根据生成文件,构建 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 中的按专栏抓取专栏内文章的请求。

目前保存的数据有以下内容:

  1. articles:所有文章数据
  2. articlesMap:由文章 id 为键生成的 Map 对象
  3. unColumnArticles:未收录到专栏中的文章列表
  4. columns:专栏列表
  5. columnMap:由专栏 id 与 { articles, columnInfo } 生成的 Map 对象
  6. yearCollection:按发布年度整合的 年份-文章列表 的 Map 对象
  7. yearMonthCollection:按发布年月整合的 年月-文章列表 的 Map 对象
  8. tagCollection:文章标签 id 与文章列表的 Map 对象
  9. 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 中提出疑问或者参与讨论~

最后,十分感谢大家的阅读!

相关推荐
树下水月24 分钟前
Typora破解
linux·服务器·前端
用户5508492902561 小时前
CSS布局实战:从Flex到Grid的完整避坑指南
前端
用户5508492902561 小时前
前端接口请求层怎么封装?一个可落地的请求方案
前端
MetWeave1 小时前
跟着一条 SPECI 走流水线:从电报到界面
前端
Helix2501 小时前
Chrome 开发者工具进阶:长截图、网络调试与性能分析
前端·chrome·chrome devtools·使用技巧·性能分析·开发者工具·长截图
liangshanbo12152 小时前
面试题:Webpack 的 publicPath 有什么作用?
前端·webpack·node.js
mjhcsp2 小时前
DeepSeek V4.1 Flash 批量处理效能实测
java·前端·数据库
CHEEVEN_QY3 小时前
新能源汽车电池托盘FSW量产的工艺稳定性控制
java·前端·汽车
Alice-YUE3 小时前
前端 × AI:从 Cursor 到 Transformer,一份完整认知路径
前端·人工智能·transformer·ai编程·前端开发·cursor
Code_Solitude3 小时前
C语言:关于二维数组的作业总结
java·c语言·前端