从零开始搭建 VitePress 博客系统
在这篇文章中,我将详细介绍如何使用 VitePress、TypeScript 和 Tailwind CSS 搭建一个功能完整的博客系统。
项目初始化
首先,让我们创建一个新的 VitePress 项目:
bash
npm create vitepress@latest my-blog
cd my-blog
npm install
项目结构设计
我们采用以下目录结构:
docs/
├── .vitepress/
│ ├── config.ts # VitePress 配置
│ ├── theme/ # 自定义主题
│ │ ├── index.ts # 主题入口
│ │ ├── Layout.vue # 布局组件
│ │ ├── style.css # 自定义样式
│ │ ├── tailwind.css # Tailwind 样式
│ │ └── components/ # 自定义组件
│ ├── data/ # 数据加载器
│ └── utils/ # 工具函数
├── posts/ # 博客文章
├── public/ # 静态资源
└── index.md # 首页
配置 Tailwind CSS
安装 Tailwind CSS 相关依赖:
bash
npm install -D tailwindcss autoprefixer @tailwindcss/typography
创建 tailwind.config.js
:
javascript
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./docs/**/*.{js,ts,vue,md}",
"./docs/.vitepress/**/*.{js,ts,vue}"
],
darkMode: 'class',
theme: {
extend: {}
},
plugins: [
require('@tailwindcss/typography')
]
}
自定义主题开发
主题入口文件
在 docs/.vitepress/theme/index.ts
中:
typescript
import { h } from 'vue'
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import './style.css'
import './tailwind.css'
export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
// 插槽配置
})
},
enhanceApp({ app, router, siteData }) {
// 注册全局组件
}
} satisfies Theme
博客列表组件
创建 docs/.vitepress/theme/components/BlogList.vue
:
vue
<template>
<div class="blog-list">
<article
v-for="post in posts"
:key="post.url"
class="blog-card mb-6"
>
<h2 class="blog-title">
<a :href="post.url">{{ post.title }}</a>
</h2>
<div class="blog-meta">
<span>{{ formatDate(post.date) }}</span>
<span>{{ post.readingTime }} 分钟阅读</span>
</div>
<p class="blog-excerpt">{{ post.description }}</p>
<div class="flex flex-wrap gap-2 mt-4">
<span v-for="tag in post.tags" :key="tag" class="tag">
{{ tag }}
</span>
</div>
</article>
</div>
</template>
<script setup>
import { defineProps } from 'vue'
defineProps({
posts: {
type: Array,
required: true
}
})
function formatDate(date) {
return new Date(date).toLocaleDateString('zh-CN')
}
</script>
数据加载器
创建 docs/.vitepress/data/posts.data.js
来自动加载文章:
javascript
import { createContentLoader } from 'vitepress'
import readingTime from 'reading-time'
export default createContentLoader('posts/**/*.md', {
includeSrc: true,
transform(rawData) {
return rawData
.map(({ url, frontmatter, src }) => {
const stats = readingTime(src)
return {
title: frontmatter.title,
url,
date: frontmatter.date,
description: frontmatter.description,
tags: frontmatter.tags || [],
author: frontmatter.author || 'William',
readingTime: Math.ceil(stats.minutes)
}
})
.filter(post => post.title && post.date)
.sort((a, b) => new Date(b.date) - new Date(a.date))
}
})
SEO 优化
在 VitePress 配置中添加 SEO 相关设置:
typescript
export default defineConfig({
title: 'My Tech Blog',
description: '分享技术、生活与思考',
head: [
['link', { rel: 'icon', href: '/favicon.ico' }],
['meta', { name: 'author', content: 'William' }],
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:site_name', content: 'My Tech Blog' }],
['meta', { name: 'twitter:card', content: 'summary_large_image' }]
]
})
部署配置
GitHub Pages 部署
创建 .github/workflows/deploy.yml
:
yaml
name: Deploy VitePress site to Pages
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run docs:build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/.vitepress/dist
VPS 部署
对于 VPS 部署,可以使用 Nginx:
nginx
server {
listen 80;
server_name yourdomain.com;
root /var/www/blog/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
性能优化
图片优化
typescript
// vitepress config
export default defineConfig({
vite: {
plugins: [
// 图片压缩插件
]
}
})
构建优化
typescript
export default defineConfig({
vite: {
build: {
rollupOptions: {
output: {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
}
}
}
}
})
总结
通过以上步骤,我们成功搭建了一个功能完整的 VitePress 博客系统,具备以下特性:
- ✅ 现代化的技术栈
- ✅ 响应式设计
- ✅ SEO 优化
- ✅ 自动化部署
- ✅ 性能优化
这个博客系统不仅性能优秀,而且易于维护和扩展。希望这篇文章能够帮助你快速上手 VitePress 博客开发!