VuePress + GitHub 搭建个人博客踩坑记录

最近想给我教练搭个网站,本来选的是 VuePress 框架,也折腾完了,起码是搭建出来了,踩的坑也都总结好了
但是最近发现了一个更简洁的模板: VuePress-theme-hope ,所以最终网站使用的样式是这个
不过我觉得这里面踩坑的记录应该还是有些价值的,分享出来,看看能不能帮到一些小伙伴~


关于教程网上一大堆,我这里就不赘述了
用的 VuePress 版本是 1.9.9

config.js 配置

config.js 配置如下:

module.exports = {title: '',description: '',head: [ ['link', { rel: 'icon', href: 'logo.jpg' }],],base: '/', markdown: {lineNumbers: false },themeConfig: {logo:'logo.jpg',nav: require('./nav'),sidebar: require('./sidebar_config.json'),sidebarDepth: 1}
};

上面配置中, title 是网站名称, description 是网站描述, head 就是访问网站时左上角的那个小标标, base 是要上传的 github 仓库

主要是 themeConfig 里面的内容, logo 不用说了, nav 是导航栏,这里我是整体把导航栏放到了同级目录下, config.js 文件简洁一些
sidebar 这块配置,有些难度,主要在于,如果使用 sidebar: auto 的话,我试了下,效果不是很理想,如果是自己配置的话,就很麻烦,详细可见官网 多个侧边栏

sidebar 脚本:

作为一个程序员,要自己一个一个手动添加,着实是不能忍
所以就写了个脚本去跑,脚本代码如下:

const fs = require('fs');
const path = require('path');function generateSidebar(folderPath) {const sidebar = {};function traverseFolder(folderPath, basePath = '') {const files = fs.readdirSync(folderPath);// 排序文件列表const sortedFiles = files.sort((a, b) => {if (a === 'README.md') {return -1;} else if (b === 'README.md') {return 1;} else {return a.localeCompare(b);}});sortedFiles.forEach(file => {const filePath = path.join(folderPath, file);const stat = fs.statSync(filePath);// 如果是文件夹,递归调用 traverseFolder 方法,获取文件夹下的文件if (stat.isDirectory()) {const subFolderPath = path.join(folderPath, file);const subBasePath = path.join(basePath, `/${file}/`);traverseFolder(subFolderPath, subBasePath);} else if (file.endsWith('.md')) {let fileName = path.parse(file).name;if (fileName === 'README') {fileName = '';}// 替换路径中的反斜杠为正斜杠const normalizedBasePath = basePath.replace(/\\/g, '/');// 只有当 basePath 不为空时才加入到 sidebar 中if (normalizedBasePath !== '') {sidebar[normalizedBasePath] = sidebar[normalizedBasePath] || [];sidebar[normalizedBasePath].push(fileName);}}});}traverseFolder(folderPath);return sidebar;
}try {const sidebarConfig = generateSidebar('./docs');const jsonContent = JSON.stringify(sidebarConfig, null, 2);fs.writeFileSync('./docs/.vuepress/sidebar_config.json', jsonContent);console.log('JSON file generated successfully.');
} catch (error) {console.error(error.message);
}

脚本逻辑大概是:遍历循环 docs 文件夹下的所有文件,获取到之后,再按照 01 02 排序,在目录 ./docs/.vuepress/ 下生成 sidebar_config.json 文件, config.js 文件里面 sidebar 配置需要这个文件,多个侧边栏搞定
然后将上面脚本放在与 docs 文件夹同级目录下,运行命令 node auto_sidebar.js ,如无意外,应该会在目录 ./docs/.vuepress 下看到生成的 sidebar_config.json 文件
在这里插入图片描述

注意:因为我的 md 文件命名是以 01_xx 02_xx 开头的,所以排序是基于这个来排序的,如果你的文件命名规则和我的不同,请自行调整脚本逻辑

deploy 到 github 仓库

在本地开发好之后,到最后是要推送到 github 仓库的
首先要建立一个仓库,比如建了一个 test 仓库
VuePress 官方也给了脚本,详细可见: 部署- GitHub Pages
如果懒得访问链接,我把脚本内容也贴下:

#!/usr/bin/env sh# 确保脚本抛出遇到的错误
set -e# 生成静态文件
npm run docs:build# 进入生成的文件夹
cd docs/.vuepress/dist# 如果是发布到自定义域名
# echo 'www.example.com' > CNAMEgit init
git add -A
git commit -m 'deploy'# 如果发布到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master# 如果发布到 https://<USERNAME>.github.io/<REPO>
# git push -f git@github.com:<USERNAME>/<REPO>.git master:gh-pagescd -

其他优化点

对于 VuePress 来说,导航栏的增删改倒是还好,侧边栏增删改些微麻烦
主要在于,假设我的文件夹下,有 1_xx 2_xx 3_xx 4_xx 文件,现在新写了一篇文章,想把它放在 1 和 2 之间,按照我的脚本逻辑,需要把 2 以及以后的文件命名都修改才行
我这种懒人,肯定不想一个一个去修改,哈哈哈哈,所以也写了一个脚本出来
有需自取:

const fs = require('fs');
const path = require('path');function renameFiles(folderPath, startNumber) {const files = fs.readdirSync(folderPath);// 找出以数字加下划线开头的文件const targetFiles = files.filter(file => /^\d+_/g.test(file));// 判断起始数字是否在文件名中存在,如果存在则开始重命名if (targetFiles.some(file => file.startsWith(`${startNumber}_`))) {const startIndex = targetFiles.findIndex(file => file.startsWith(`${startNumber}_`));// 将文件名按照数字大小进行排序targetFiles.sort((a, b) => {const numberA = parseInt(a.match(/^\d+/)[0]);const numberB = parseInt(b.match(/^\d+/)[0]);return numberA - numberB;});for (let i = startIndex - 1; i < targetFiles.length; i++) {const file = targetFiles[i];const currentName = file.replace(/^\d+_/, '');const currentNumber = parseInt(file.match(/^\d+/)[0]);const newNumber = currentNumber + 1;const newFile = `${newNumber}_${currentName}`;const oldFilePath = path.join(folderPath, file);const newFilePath = path.join(folderPath, newFile);fs.renameSync(oldFilePath, newFilePath);}}
}// 传入目标文件夹路径和要更改的起始数字
renameFiles('./blog', 2);

以上
感谢您的阅读~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2000-2022年上市公司绿色专利申请占比/数据

2000-2022年上市公司绿色专利申请占比数据 1、时间&#xff1a;2000-2022年 2、来源&#xff1a;国家知识产权局、WIPO绿色专利清单 3、指标&#xff1a;年份、股票代码、股票简称、行业代码、省份、城市、区县、行政区划代码、城市代码、区县代码、首次上市年份、上市状态、…

黑马瑞吉外卖练习笔记

day2 员工管理 完善登录 问题&#xff1a;用户不登录&#xff0c;直接访问系统首页&#xff0c;照样可以正常访问。我们希望&#xff0c;只有登录成功后才可以访问系统中的页面&#xff0c;如果没有登录则跳转到登录页面 怎么实现&#xff1f; 用过滤器或拦截器&#xff0c;在…

[数据结构 C++] AVL树的模拟实现

文章目录 1、AVL树1.1 AVL树的概念 2、AVL树节点的定义3、AVL树的插入和旋转3.1 左单旋左旋代码实现 3.2 右单旋右旋代码实现 3.3 右左双旋右左双旋的代码实现 3.4 左右双旋左右双旋的代码实现 3.5 insert接口实现 4、判断是否为AVL树判断AVL树的代码实现 5、AVL树的性能 问题引…

刷题第3天(简单题):LeetCode203--移除链表元素--虚拟头结点

LeetCode203:给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示例 2&#xff1a;输入…

面试数据库篇(mysql)- 07索引创建原则与失效及优化

索引创建原则 1). 针对于数据量较大,且查询比较频繁的表建立索引。 2). 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。 3). 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。 4). 如果是字符…

flink下载安装部署说明

下载 下载地址 flink-1.16.2下载安装包&#xff0c;flink-1.16.2-bin-scala-2.12.zip资源-CSDN文库 安装 解压目录 启动集群 ./start-cluster.sh 提交作业 ./bin/flink run examples/streaming/WordCount.jar 查看日志 停止集群 ./bin/stop-cluster.sh 开启webui vim c…

数据结构与算法 - 数组与二分查找 + Leetcode典型题

1. 什么是数组 数组是存放在连续内存空间上的相同类型数据的集合。 数组可以方便的通过下标索引的方式获取到下标下对应的数据。 C中二维数组在地址空间上也是连续的。 需注意&#xff1a; 数组的下标从0开始。数组内存空间的地址是连续的。数组的元素是不能删的&#xff0c…

【HDFS】Decommision(退役) EC数据节点剩最后几个块卡住的问题

一、背景 近期操作退役EC集群的节点。在退役的过程中,遇到了一些问题。特此总结一下。 本文描述的问题现象是: 每一批次退役10个节点,完全退役成功后开始操作下一批。 但是,中间有一批次有2台节点的Under Replicated Blocks一直是1,不往下降。 处于Decommissioning状态卡…

鸿蒙OpenHarmony多线程能力场景化示例实践

简介 在OpenHarmony应用中&#xff0c;每个 进程 都会有一个主线程&#xff0c;主线程主要承担执行UI绘制操作、管理ArkTS引擎实例的创建和销毁、分发和处理事件、管理Ability生命周期等职责&#xff0c;具体可参见 线程模型概述 。因此&#xff0c;开发应用时应当尽量避免将耗…

Sora技术原理解析

1.Sora简介 Sora是一个基于大规模训练的文本控制视频生成扩散模型。 Sora能够生成高达1分钟的高清视频&#xff0c;涵盖广泛的视觉数据类型和分辨率。 Sora使用简单的文本描述&#xff0c;使得视频创作变得前所未有的简单和高效。 Sora的一些能力&#xff1a; Text-to-video…

windows server mysql 数据库停止 备份 恢复全流程操作方法

一,mysql备份 mysql最好是原工程文件备份.不需要sql查询的方式备份.安全高效. 比如,安装php与mysql组合后,我的mysql文件保存在: D:\phpstudy_pro\Extensions\MySQL5.7.26\data\dux 我只需要复制一份,保存起来就行. 二,mysql恢复 怎么恢复呢.我们一般是只恢复其中一个表,则找…

一个具有强大PDF处理能力的.Net开源项目

PDF具有跨平台、可读性强、不可修改性、无需特定阅读软件、内容安全等好处&#xff0c;在工作中经常都会用到。 所以&#xff0c;我们在项目开发中&#xff0c;经常需要生成PDF的文件&#xff0c;或者把Html、Xml等文件转化为PDF格式。 今天给大家推荐一个具有PDF处理能力的.…

优思学院|质量工程师需要学习什么软件?

初入职质量工程师的朋友常常会问&#xff1a;质量工程师需要学习什么软件&#xff1f;在质量控制和管理的世界里&#xff0c;拥有强大的数据分析工具是走向成功的关键&#xff0c;因此&#xff0c;对于质量工程师来说&#xff0c;掌握正确的软件不仅能提升工作效率&#xff0c;…

lv20 QT对话框3

1 内置对话框 标准对话框样式 内置对话框基类 QColorDialog, QErrorMessage QFileDialog QFontDialog QInputDialog QMessageBox QProgressDialogQDialog Class帮助文档 示例&#xff1a;各按钮激发对话框实现基类提供的各效果 第一步&#xff1a;实现组件布局&…

Pyhton的组合数据类型

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 生命对某些人来说是美丽的&#xff0c…

尝鲜18倍速大模型Groq和世界第二AI Mistral(Le Chat)

01 尝鲜 中午,一边吃饭,一边尝试一下最新的AI:Groq,它使用了重新设计的LPU,据说比英伟达的GPU快了18倍。 运行了开源的Mixtral-8x7b模型,屏幕上的文字回复几乎是瞬间的,那种速度感,让人心跳加速。 接着,我尝试了来自欧洲的新贵——Mistral AI的Le Chat。 这个三天前…

python学习笔记-内置异常

概述 Python 中的异常&#xff08;Exception&#xff09;是指在程序执行过程中遇到的错误或异常情况。当程序出现异常时&#xff0c;解释器会停止当前代码的执行&#xff0c;并试图找到匹配的异常处理器来处理异常。如果没有找到合适的异常处理器&#xff0c;程序就会终止并打…

go并发模式之----阻塞/屏障模式

常见模式之一&#xff1a;阻塞/屏障模式 定义 顾名思义&#xff0c;就是阻塞等待所有goroutine&#xff0c;直到所有goroutine完成&#xff0c;聚合所有结果 使用场景 多个网络请求&#xff0c;聚合结果 大任务拆分成多个子任务&#xff0c;聚合结果 示例 package main ​…

配电房轨道式巡检机器人方案

一、应用背景 在变电站、配电房、开关站等各种室内变配电场所内&#xff0c;由于变配电设备的数量众多、可能存在各类安全隐患&#xff0c;为了保证用电的安全可靠&#xff0c;都要进行日常巡检。 但目前配电房人工巡检方式有以下主要问题&#xff1a; 巡检工作量大、成本高 …

关于StartAI本地部署相关问题解答

很多小伙伴们都有接入自己本地SD的需求&#xff0c;对此小编整理了一些相关问题~ 一、本地部署相关条件 对于想要本地部署的小伙伴要了解&#xff0c;相对于使用StartAI试用引擎本地部署更加考验电脑硬件配置备噢~ 流畅使用要nvidia显卡&#xff0c;6g以上显存&#xff08;最…