From c1ea1865a413f4f808412d8824b6391a1e13c2e2 Mon Sep 17 00:00:00 2001 From: thehrz Date: Sun, 30 Jul 2023 17:22:21 +0800 Subject: [PATCH] feat: add usePosts --- package.json | 2 ++ pnpm-lock.yaml | 28 +++++++++++++++++++++------- src/auto-imports.d.ts | 3 +++ src/common/interfaces/Post.ts | 6 ++++++ src/composables/usePosts.ts | 22 ++++++++++++++++++++++ src/main.ts | 2 +- src/posts/contribute.md | 4 ++++ src/posts/index.vue | 12 +++++++++++- vite.config.ts | 24 +++++++++++++++++++++++- 9 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 src/common/interfaces/Post.ts create mode 100644 src/composables/usePosts.ts diff --git a/package.json b/package.json index c17f313..c1097ef 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@iconify-json/simple-icons": "^1.1.62", "@intlify/unplugin-vue-i18n": "^0.11.0", "@mdi/font": "^7.2.96", + "@types/fs-extra": "^11.0.1", "@types/markdown-it-link-attributes": "^3.0.1", "@types/nprogress": "^0.2.0", "@vitejs/plugin-vue": "^4.2.3", @@ -45,6 +46,7 @@ "cypress": "^12.17.2", "eslint": "^8.46.0", "eslint-plugin-cypress": "^2.13.3", + "fs-extra": "^11.1.1", "https-localhost": "^4.7.1", "markdown-it-link-attributes": "^4.0.1", "markdown-it-shiki": "^0.9.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 229de4b..29bbb21 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,6 +58,9 @@ devDependencies: '@mdi/font': specifier: ^7.2.96 version: 7.2.96 + '@types/fs-extra': + specifier: ^11.0.1 + version: 11.0.1 '@types/markdown-it-link-attributes': specifier: ^3.0.1 version: 3.0.1 @@ -88,6 +91,9 @@ devDependencies: eslint-plugin-cypress: specifier: ^2.13.3 version: 2.13.3(eslint@8.46.0) + fs-extra: + specifier: ^11.1.1 + version: 11.1.1 https-localhost: specifier: ^4.7.1 version: 4.7.1 @@ -1490,10 +1496,23 @@ packages: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: true + /@types/fs-extra@11.0.1: + resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} + dependencies: + '@types/jsonfile': 6.1.1 + '@types/node': 20.4.5 + dev: true + /@types/json-schema@7.0.12: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} dev: true + /@types/jsonfile@6.1.1: + resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} + dependencies: + '@types/node': 20.4.5 + dev: true + /@types/linkify-it@3.0.2: resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} dev: true @@ -4792,7 +4811,7 @@ packages: foreground-child: 3.1.1 jackspeak: 2.2.2 minimatch: 9.0.3 - minipass: 7.0.2 + minipass: 5.0.0 path-scurry: 1.10.1 dev: true @@ -6030,11 +6049,6 @@ packages: engines: {node: '>=8'} dev: true - /minipass@7.0.2: - resolution: {integrity: sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA==} - engines: {node: '>=16 || 14 >=14.17'} - dev: true - /minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -6535,7 +6549,7 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: lru-cache: 10.0.0 - minipass: 7.0.2 + minipass: 5.0.0 dev: true /path-to-regexp@0.1.7: diff --git a/src/auto-imports.d.ts b/src/auto-imports.d.ts index fe6988b..e41abf4 100644 --- a/src/auto-imports.d.ts +++ b/src/auto-imports.d.ts @@ -215,6 +215,7 @@ declare global { const usePointer: typeof import('@vueuse/core')['usePointer'] const usePointerLock: typeof import('@vueuse/core')['usePointerLock'] const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe'] + const usePosts: typeof import('./composables/usePosts')['default'] const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme'] const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast'] const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] @@ -511,6 +512,7 @@ declare module 'vue' { readonly usePointer: UnwrapRef readonly usePointerLock: UnwrapRef readonly usePointerSwipe: UnwrapRef + readonly usePosts: UnwrapRef readonly usePreferredColorScheme: UnwrapRef readonly usePreferredContrast: UnwrapRef readonly usePreferredDark: UnwrapRef @@ -801,6 +803,7 @@ declare module '@vue/runtime-core' { readonly usePointer: UnwrapRef readonly usePointerLock: UnwrapRef readonly usePointerSwipe: UnwrapRef + readonly usePosts: UnwrapRef readonly usePreferredColorScheme: UnwrapRef readonly usePreferredContrast: UnwrapRef readonly usePreferredDark: UnwrapRef diff --git a/src/common/interfaces/Post.ts b/src/common/interfaces/Post.ts new file mode 100644 index 0000000..c10f48d --- /dev/null +++ b/src/common/interfaces/Post.ts @@ -0,0 +1,6 @@ +interface Post { + path: string + title: string +} + +export { Post } diff --git a/src/composables/usePosts.ts b/src/composables/usePosts.ts new file mode 100644 index 0000000..43bbec3 --- /dev/null +++ b/src/composables/usePosts.ts @@ -0,0 +1,22 @@ +import { createGetRoutes } from 'virtual:meta-layouts' +import type { RouteMeta } from 'vue-router' +import type { Post } from '~/common/interfaces/Post' + +type Meta = { + frontmatter: { + title: string + } +} & RouteMeta + +export default (): Post[] => { + const router = useRouter() + + const routes = createGetRoutes(router)().filter((route) => { + return route.path.startsWith('/posts/') + }) + + return routes.map((route) => { + const meta = route.meta as Meta + return { path: route.path, title: meta.frontmatter.title } + }) +} diff --git a/src/main.ts b/src/main.ts index 6f068d1..c211eaa 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,10 @@ import { ViteSSG } from 'vite-ssg' import { setupLayouts } from 'virtual:meta-layouts' +import generatedRoutes from 'virtual:generated-pages' import App from './App.vue' import type { UserModule } from './types' import vuetify from './plugins/vuetify' -import generatedRoutes from '~pages' import '@unocss/reset/tailwind.css' import './styles/main.css' diff --git a/src/posts/contribute.md b/src/posts/contribute.md index 7b14bd2..79be173 100644 --- a/src/posts/contribute.md +++ b/src/posts/contribute.md @@ -1,3 +1,7 @@ +--- +title: "贡献指南" +--- + # 贡献指南 本文介绍了向 [19yuke2](https://git.thehrz.net/19yuke2-project/19yuke2) 创建 `合并请求` 的完整操作步骤。 diff --git a/src/posts/index.vue b/src/posts/index.vue index 986f48e..8554467 100644 --- a/src/posts/index.vue +++ b/src/posts/index.vue @@ -1,3 +1,13 @@ + + diff --git a/vite.config.ts b/vite.config.ts index 051beeb..b2e5ee5 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,11 @@ -import path from 'node:path' +import path, { resolve } from 'node:path' import { defineConfig } from 'vite' import Vue from '@vitejs/plugin-vue' +import fs from 'fs-extra' +import matter from 'gray-matter' import Pages from 'vite-plugin-pages' import generateSitemap from 'vite-ssg-sitemap' +import MarkdownIt from 'markdown-it' // import Layouts from 'vite-plugin-vue-layouts' import MetaLayouts from 'vite-plugin-vue-meta-layouts' @@ -43,6 +46,25 @@ export default defineConfig({ { dir: 'src/pages', baseRoute: '' }, { dir: 'src/posts', baseRoute: 'posts' }, ], + extendRoute(route) { + const path = resolve(__dirname, route.component.slice(1)) + const md = fs.readFileSync(path, 'utf-8') + const { data, excerpt } = matter(md, { + excerpt: (file) => { + const content = ((file as any).content as string).replace(/<[^>]*>/g, '').replace(/\[\[toc\]\]/g, '') + ;(file as any).excerpt = MarkdownIt() + .render(content) + .replace(/<[^>]*>/g, '') + .replace(/\n/g, ' ') + .replace(/\s+/, ' ') + .slice(0, 280) + .concat('...') + return file + }, + }) + route.meta = Object.assign(route.meta || {}, { frontmatter: data, excerpt }) + return route + }, }), // https://github.com/JohnCampionJr/vite-plugin-vue-layouts