From 148c74c9570823d26a79927b065fe552c98d1a47 Mon Sep 17 00:00:00 2001 From: andatoshiki Date: Sat, 25 Mar 2023 20:02:47 +0800 Subject: [PATCH] feat(rss): hot introducing rss feature as seperate utility module after docs is built --- docs/.vitepress/utils/genFeed.js | 50 ++++++++++++++++++++++++ docs/.vitepress/utils/posts.data.d.ts | 10 +++++ docs/.vitepress/utils/posts.data.js | 56 +++++++++++++++++++++++++++ package.json | 5 ++- 4 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 docs/.vitepress/utils/genFeed.js create mode 100644 docs/.vitepress/utils/posts.data.d.ts create mode 100644 docs/.vitepress/utils/posts.data.js diff --git a/docs/.vitepress/utils/genFeed.js b/docs/.vitepress/utils/genFeed.js new file mode 100644 index 00000000..889a665c --- /dev/null +++ b/docs/.vitepress/utils/genFeed.js @@ -0,0 +1,50 @@ +const fs = require('fs') +const path = require('path') +const { Feed } = require('feed') +const { load } = require('./posts.data') +const { resolveSiteData } = require('vitepress') +const url = `https://note.toshiki.dev` + +genFeed() + +async function genFeed() { + const siteData = await resolveSiteData('.') + const posts = await load(true) + const cwd = process.cwd() + const feed = new Feed({ + title: siteData.title, + description: siteData.description, + id: url, + link: url, + language: siteData.lang, + image: `${url}/logos/logo-308px.png`, + favicon: `${url}/favicon.ico`, + copyright: siteData.themeConfig.name || '-', + }) + + posts.forEach((post) => { + const file = path.resolve(cwd, `dist/${post.href}`) + const rendered = fs.readFileSync(file, 'utf-8') + const content = rendered.match( + /([\s\S]*)<\/body>/ + ) + + feed.addItem({ + title: post.title, + id: `${url}${post.href}`, + link: `${url}${post.href}`, + description: post.excerpt, + content: content[1], + author: [ + { + name: post.data.author, + link: post.data.twitter + ? `https://twitter.com/${post.data.twitter}` + : undefined + } + ], + }) + }) + + fs.writeFileSync(path.resolve(cwd, 'dist/feed.rss'), feed.rss2()) +} \ No newline at end of file diff --git a/docs/.vitepress/utils/posts.data.d.ts b/docs/.vitepress/utils/posts.data.d.ts new file mode 100644 index 00000000..8684a37d --- /dev/null +++ b/docs/.vitepress/utils/posts.data.d.ts @@ -0,0 +1,10 @@ +export interface PostData { + title: string, + href: string, + create: number, + update: number, + tags?: string[], + cover?: string, + excerpt: string, +} +export declare const data: PostData[] diff --git a/docs/.vitepress/utils/posts.data.js b/docs/.vitepress/utils/posts.data.js new file mode 100644 index 00000000..319fdea8 --- /dev/null +++ b/docs/.vitepress/utils/posts.data.js @@ -0,0 +1,56 @@ +// from https://github.com/vuejs/blog +const fs = require('fs') +const path = require('path') +const matter = require('gray-matter') +const { createMarkdownRenderer } = require('vitepress') + +const cwd = process.cwd() + +module.exports = { + watch: path.relative(__dirname, cwd + '/docs/*.md').replace(/\\/g, '/'), + async load(asFeed = false) { + const md = await createMarkdownRenderer(cwd) + const postDir = path.join(cwd, 'docs') + return fs + .readdirSync(postDir) + .filter((file) => file.endsWith('.md')) + .map((file) => getPost(md, file, postDir, asFeed)) + .sort((a, b) => b.create - a.create) + } +} + +const cache = new Map() + +function getPost(md, file, postDir, asFeed = false) { + const fullePath = path.join(postDir, file) + const timestamp = Math.floor(fs.statSync(fullePath).mtimeMs) + + const cached = cache.get(fullePath) + if (cached && timestamp === cached.timestamp) { + return cached.post + } + + const src = fs.readFileSync(fullePath, 'utf-8') + const { data, excerpt } = matter(src, { excerpt: true }) + + const post = { + title: data.title, + href: `${file.replace(/\.md$/, '.html')}`, + create: +new Date(data.date) || timestamp, + update: timestamp, + tags: data.tags, + cover: data.cover, + excerpt: md.render(excerpt) + } + if (asFeed) { + // only attach these when building the RSS feed to avoid bloating the + // client bundle size + post.data = data + } + + cache.set(fullePath, { + timestamp, + post + }) + return post +} \ No newline at end of file diff --git a/package.json b/package.json index 20840a6d..3405730d 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,15 @@ "private": true, "scripts": { "docs:dev": "vitepress dev docs", - "docs:build": "vitepress build docs", + "docs:build": "vitepress build docs && node docs/.vitepress/utils/genFeed.js", "docs:preview": "vitepress preview docs", "docs:host": "vitepress dev docs --host", "rm:dist": "rm -rf /docs/.vitepress/dist", "rm:cache": "rm -rf /docs/.vitepress/cache", "prepare": "husky install", "lint": "prettier --write .", - "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0" + "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0", + "feed": "node docs/.vitepress/utils/genFeed.js" }, "lint-staged": { "*.{js,jsx,vue,ts,tsx}": [