【Website】网站生成框架切换到 VitePress
原由
NOTE
早前网站是基于 Github Pages + Hexo + hexo-theme-next 来构建的;如果是写写单篇的文章还够用,但对于写类似系列的文章还不够友好(后面要去构建自己的计算机知识体系);原因是,next主题的系列文章的导航栏是放在文章的顶部的,每次都要滑到网站顶部才能去转跳。正好赶上清明节放假几天
框架、库文档看多了,发现现在主流的文档排版格式都长成一个样:三段式,左侧导航、中间内容、右边当前文章大纲。长成一个样也有好处,大众使用成本变低了;文档排版格式草图如下:
可选工具列表
能用Markdown写系列文章的工具列表:
- VitePress: https://github.com/vuejs/vitepress
- GitBook:https://www.gitbook.com/
- MkDocs: https://www.mkdocs.org/
- Read the Docs:https://readthedocs.com/
- mdBooks:https://rust-lang.github.io/mdBook/
VitePress特点:
- 主要应用场景匹配:文档和博客 (Vue.js Vite官方文档都是基于)
- 文档:用来写系列文档
- 博客:用来写记录、总结、学习笔记
- 拓展性好:
- 内置 Markdown 扩展
- Markdown支持自定义 Vue 组件
- 学习成本:
- 有些配置是 JS/TS的;
- 自定义组件需要自己写 Vue 代码
VitePress 调整部分
添加Blog
VitePress 缺少Blog部分,参考 ti.bi 和 Vue.js blog 写了个 Vue 组件,放置在 Markdown 中。代码较多就不贴上来了
内容加宽
VitePress的内容宽度,个人觉得偏窄,把内容的 padding 给去掉了
css
/* 文章内容宽度 */
:root {
--vp-layout-max-width: 1440px;
}
.content-container {
max-width: 100% !important;
}
/* min-width: 1440px same as original min-width: 960px */
@media (min-width: 1440px) {
.VPSidebar {
padding-left: 32px !important;
width: var(--vp-sidebar-width) !important;
}
.VPContent.has-sidebar {
padding-left: var(--vp-sidebar-width) !important;
padding-right: 0 !important;
}
/* container --> content -> content-container */
.VPContent.has-sidebar .content {
max-width: 100% !important;
}
.VPContent.has-sidebar .content-container {
max-width: 100% !important;
}
.VPDoc:not(.has-sidebar) .content {
max-width: 100% !important;
}
.VPDoc:not(.has-sidebar) .content-container {
max-width: 100% !important;
}
}
/* Add additional min-width: 1680px */
@media (min-width: 1680px) {
.VPSidebar {
padding-left: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2) !important;
width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px) !important;
}
.VPContent.has-sidebar {
padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)) !important;
padding-right: calc((100vw - var(--vp-layout-max-width)) / 2) !important;
}
/* container --> content -> content-container */
.VPContent.has-sidebar .container {
max-width: 100% !important;
padding: 0px !important;
}
.VPContent.has-sidebar .content {
max-width: 100% !important;
/* padding-left: 0px !important; */
}
.VPContent.has-sidebar .content-container {
max-width: 100% !important;
padding: 0px !important;
}
.VPDoc:not(.has-sidebar) .container {
max-width: 60% !important;
padding: 0px !important;
}
.VPDoc:not(.has-sidebar) .content {
max-width: 100% !important;
/* padding-bottom: 32px !important; */
}
.VPDoc:not(.has-sidebar) .content-container {
max-width: 100% !important;
padding: 0px !important;
}
}
图片居中
图片设置默认显示居中
css
img {
display: block;
margin: auto;
}
工作流
npm
命令有个不好的地方,需要敲三个单词,比如 npm run dev
,而且还没有提示、补全。
Makefile
现在在 npm
命令的基础上,增加一层 makefile
,对npm
命令包装下,减少命令输入,还能提供提示、Tab
键补全;对于长用的本地运行 npm run dev
,设置成默认的伪目标,输入 make
就能运行
构建
- 本地运行
- 生成网站/网页
- 部署到 Github Pages
makefile
# 伪目标,默认 dev
.PHONY: dev
# 本地运行
dev:
npm run dev
# 生成网站
build:
npm run build
# 部署到 Github Pages
deploy: clean build
# echo setup
[ -d .vitepress/dist/.git ] || git init .vitepress/dist
# commit
cd .vitepress/dist && git add -A && git commit -m 'Update: $(DATE)'
# push
cd .vitepress/dist && git push -f -u https://github.com/WShiBin/wshibin.github.io master
创建文章
创建单篇 Blog 文章
makefile
# Post ----------------------------------------------
POST_TITLE := ''
# If the first argument is "post"...
ifeq (post,$(firstword $(MAKECMDGOALS)))
# use the rest as arguments for "post"
POST_TITLE := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# ...and turn them into do-nothing targets
$(eval $(POST_TITLE):;@:)
endif
DATE := $(shell date '+%Y-%m-%d %H:%M:%S')
DATE_YEAR := $(shell date '+%Y')
DATE_MONTH_DAY := $(shell date '+%m_%d_')
POST_TEMP_FRONTMATTER_START := "---"
POST_TEMP_FRONTMATTER_TITLE := "title: $(POST_TITLE)"
POST_TEMP_FRONTMATTER_CATEGORIES:= "categories: foo"
POST_TEMP_FRONTMATTER_TAGS := "tags: bar"
POST_TEMP_FRONTMATTER_SIDEBAR := "sidebar: false"
POST_TEMP_FRONTMATTER_PREV := "prev: false"
POST_TEMP_FRONTMATTER_NEXT := "next: false"
POST_TEMP_FRONTMATTER_COMMENTS := "comments: false"
POST_TEMP_FRONTMATTER_DATE := "date: $(DATE)"
POST_TEMP_FRONTMATTER_END := "---\n"
POST_TEMP_FRONTMATTER_TITLE_ := "\# {{ \$$frontmatter.title }}"
post:
@mkdir -p src/posts/$(DATE_YEAR)
@echo $(POST_TEMP_FRONTMATTER_START) > src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_TITLE) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_CATEGORIES) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_TAGS) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_SIDEBAR) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_PREV) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_NEXT) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_COMMENTS) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_DATE) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_END) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo $(POST_TEMP_FRONTMATTER_TITLE_) >> src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@echo src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
@code src/posts/$(DATE_YEAR)/$(DATE_MONTH_DAY)$(POST_TITLE).md
创建标题 Title 为 foo 的 Post 文章:
bash
$ make post foo
src/posts/2024/04_30_foo.md
图片处理
流程:
- 缩放:宽度大于1400px 的图片,等比缩放到1400 px
- 格式转换:png 和 jpg 转成 webp 格式
- 删除原来的图片
makefile
image:
@echo Resize image width to 1400
@./misc/image.sh 1400
@echo 'Convert image to webp'
@fd --threads=16 -e png -e jpg -x cwebp {} -o {.}.webp
@echo 'Delete origin image'
@fd --threads=16 -e png -e jpg -x rm
Other
关于图片
- 草图、画图用 Excalidraw 的 svg 图;直接引入,也能二次编辑
- 流程图其它图用 draw.io ;文章直接引入
- 截图用 Xnip 截图成png格式,最后转成 WebP 发布(优化文件大小)
fd
查找图片cwebp
转换图片
VSCode snippets 配置
用VSCode 的 snippets 来简化写一些内容模板:时间日期、文章和文档的 frontmatter
。配置文件.vscode/template.code-snippets
:
json
{
"Current date": {
"scope": "markdown",
"prefix": "date",
"body": ["${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}"],
"description": "Current date"
},
"Current date time": {
"scope": "markdown",
"prefix": "datetime",
"body": ["${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}"],
"description": "Current date time"
},
"Frontmatter doc": {
"scope": "markdown",
"prefix": "frontmatter_doc",
"body": [
"---",
"title: '$1'",
"outline: deep",
"layout: doc",
"prev: true",
"next: true",
"siderbar: true",
"date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}",
"---",
"",
"# {{ $$frontmatter.title }}",
""
],
"description": "Doc Frontmatter"
},
"Frontmatter post": {
"scope": "markdown",
"prefix": "frontmatter_post",
"body": [
"---",
"title: '$1'",
"categories: $2",
"tags: ",
" - $3",
"outline: deep",
"layout: doc",
"prev: false",
"next: false",
"siderbar: false",
"comments: true",
"date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}",
"---",
"",
"# $1",
""
],
"description": "Post Frontmatter"
}
}
Reference:
- Documentation for Vue 3: https://github.com/vuejs/docs
- Vue.js blog: https://github.com/vuejs/blog
- VitePress 文档: https://github.com/vuejs/vitepress/tree/main/docs
- 其他个人网站: