UNPKG

create-base-teek-theme

Version:

### npm ``` npm create base-teek-theme@latest my-first-blog ```

341 lines (254 loc) 7.82 kB
--- date: 2025-03-17 16:03:50 title: 自动生成frontmatter permalink: /pages/3ab292 tags: - 插件 categories: - 工具类 author: name: 华总 link: https://xiaoying.org.cn --- # vitepress-plugin-setfrontmatter ## github地址 ::: navCard 2 ```yaml - name: vitepress-plugin-setfrontmatter desc: 这是一个适用于vitepress的 Vite 插件,vitepress启动时,插件会给指定的 markdown 自动生成frontmatter。 img: https://img.xiaoying.org.cn/img/202503231752583.png link: https://github.com/liyao52033/vitepress-plugin-setfrontmatter badge: vitepress插件 badgeType: tip ``` ::: ## ✨ 特性 - 🚀 自动生成 `frontmatter` - 🚀 支持自定义新的 `frontmatter` ## 安装 安装 `vitepress-plugin-setfrontmatter` 插件 ::: code-group ```shell [npm] npm install vitepress-plugin-setfrontmatter -D ``` ```shell [yarn] yarn add vitepress-plugin-setfrontmatter -D ``` ```shell [pnpm] pnpm i vitepress-plugin-setfrontmatter -D ``` ::: ## 基本使用 添加 `vitepress-plugin-setfrontmatter` 插件到 `.vitepress/config.ts` ```typescript import AutoFrontmatter from "vitepress-plugin-auto-frontmatter"; export default defineConfig({ vite: { plugins: [AutoFrontmatter({ pattern: "**/*.md", globOptions: { ignore: [""] } //忽略的文件夹 })], }, }); ``` > 说明:该插件仅限项目启动时生效。 ## 参数 ```typescript import type { GlobOptions } from "tinyglobby"; export interface AutoFrontmatterOption { /** * 扫描的文件路径表达式,为 global 表达式 */ pattern?: string | string[]; /** * tinyglobby 的配置项 * 插件默认已经忽略 node_modules dist 目录的所有文件 */ globOptions?: GlobOptions; /** * 转换处理好的 frontmatter,该函数需要返回一个新的 frontmatter 或只返回 undefined,如果返回 {},则清空 MD 文件本身存在的 frontmatter */ transform?: (frontmatter: Record<string, any>, fileInfo: FileInfo) => Record<string, any> | void; } export interface FileInfo { /** * 文件绝对路径 */ filePath: string; /** * 文件相对路径 */ relativePath: string; } ``` 插件默认忽略 ["node_modules", "dist"]` 目录下的文件,且只扫描 markdown 文档。 插件默认给 markdown 文件生成 `title` `date` 两个属性,其中 `title` 为文件名(支持带序号的文件名,如 `01.xx.md`),`date` 为文件的创建日期。 ```yaml --- title: 文件名 date: yyyy-MM-dd hh:mm:ss --- ``` ## 📖 自定义新的 `frontmatter` 如果想拓展 `frontmatter` 的内容,则使用 `transform` 函数。 想排除某个md文档不想自动生成 `frontmatter`,在`frontmatter` 中添加 `article: false` 或者 `layout: home`,则不会生成 `frontmatter`。 ```yaml //要排除的话二选一即可 --- article: false layout: home --- ``` 通过 `transform` 函数来添加一个唯一的永久链接和分类标签 ### 1、安装vitepress-plugin-catalogue ::: code-group ```shell [npm] npm install vitepress-plugin-catalogue -D ``` ```shell [yarn] yarn add vitepress-plugin-catalogue -D ``` ```shell [pnpm] pnpm i vitepress-plugin-catalogue -D ``` ::: ### 2、新建types.ts ```typescript import type { CatalogueOption } from "vitepress-plugin-catalogue"; import type { AutoFrontmatterOption } from "vitepress-plugin-auto-frontmatter"; export interface vpThemeConfig { /** * 内置 Vite 插件配置 */ vitePlugins?: Plugins; } export interface Plugins { /** * catalogues 插件配置项 */ catalogueOption?: CatalogueOption; /** * autoFrontmatter 插件配置项,并拓展出其他配置项 */ autoFrontmatterOption?: AutoFrontmatterOption & { permalinkPrefix?: string;}; } ``` ### 3、配置 ```typescript export default function vpThemeConfig(config: vpThemeConfig = {}): UserConfig { const { vitePlugins, ...tkThemeConfig } = config; const { autoFrontmatter = true, autoFrontmatterOption = {}, } = vitePlugins || {}; const plugins: PluginOption[] = []; // 定义插件扫描时忽略的目录 const ignoreDir = { autoFrontmatter: ["**/@pages/**"], }; // 自动生成 frontmatter 插件 const { pattern, globOptions = {}, transform, permalinkPrefix = "pages", } = autoFrontmatterOption; // 默认扫描全部 MD 文件 if (!pattern) autoFrontmatterOption.pattern = "**/*.md"; autoFrontmatterOption.globOptions = { ...autoFrontmatterOption.globOptions, ignore: [...ignoreDir.autoFrontmatter, ...(globOptions.ignore || [])], }; // 自定义 frontmatter 内容,添加永久链接和分类 autoFrontmatterOption.transform = (frontmatter, fileInfo) => { let transformResult = transform?.(frontmatter, fileInfo) || {}; if (permalink) { transformResult = { ...transformResult, ...createPermalink(permalinkPrefix) }; } if (!frontmatter.categories) { transformResult = { ...transformResult, ...createCategory(fileInfo, ["@fragment"]) }; } /** 继续添加你想要的字段,仿照创建 permalink 永久链接在下面实现即可, 返回值结构{ key: value } **/ return Object.keys(transformResult).length ? { ...frontmatter, ...transformResult } : undefined; }; plugins.push(AutoFrontmatter(autoFrontmatterOption)); return { // 使用永久链接插件需要忽略死链提醒 ignoreDeadLinks: true, vite: { plugins: plugins as any, // 解决项目启动后终端打印 Scss 的废弃警告:The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0. css: { preprocessorOptions: { scss: { api: "modern" } } }, optimizeDeps: { include: ["element-plus", "@giscus/vue", "@waline/client"], }, }, themeConfig: tkThemeConfig, }; } /** * 创建 permalink 永久链接 */ export const createPermalink = () => { return { permalink: `/pages/${(Math.random() + Math.random()).toString(16).slice(2, 8)}`, }; }; /** * 创建 categories 分类列表 * * @param fileInfo 文件信息 * @param ignore 需要忽略的文件名或目录名 */ export const createCategory = (fileInfo: FileInfo, ignore: string[] = []) => { const siteConfig: SiteConfig = (globalThis as any).VITEPRESS_CONFIG; const { locales = {} } = siteConfig.userConfig; const relativePathArr = fileInfo.relativePath.split("/"); const categories: string[] = []; relativePathArr.forEach((item, index) => { // 去除「序号.」的前缀,并获取文件名 const filename = item.replace(/^\d+\./, "").split(".")?.[0] || ""; // 兼容国际化功能,如果配置多语言,则不添加多语言根目录名 if (index !== relativePathArr.length - 1 && !locales[filename] && !ignore.includes(filename)) categories.push(filename); }); // [""] 表示添加一个为空的 categories return { categories: categories.length ? categories : [""] }; }; ``` 效果如下: ```yaml --- date: 2025-03-03 00:45:16 title: 插件测试 permalink: /pages/eb8f2f categories: - guide - vue --- ``` > 如果 `transform` 函数返回的 `frontmatter` 已经在文件存在(只比较 Key 是否相同,不比较 Value),则忽略生成。 ### 4、 使用 ::: code-group ```typescript[config.ts] import vpThemeConfig from "./theme/config/index"; const vpConfig = vpThemeConfig({ vitePlugins: { autoFrontmatterOption: { pattern: "**/*.md", globOptions: { ignore: ["utils", "index.md", "login.md"] } }, catalogueOption:{ path: "docs", ignoreList: ["login.md"] }, } }); export default defineConfig({ extends: vpConfig, ... )} ``` :::